//===--- ctlock.cc - Common threads implementation of locks ---------------===//
//
//                     The Micro Virtual Machine
//
// This file is distributed under the University of Illinois Open Source 
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <cassert>

#include "vmkit/Cond.h"
#include "vmkit/Locks.h"
#include "vmkit/Thread.h"
#include "vmkit/VirtualMachine.h"
#include "VmkitGC.h"
#include <cerrno>
#include <sys/time.h>
#include <pthread.h>


namespace vmkit {

/**
 * These variables are used to implement some behavior
 * when the user presses Ctrl_C.
 */
LockNormal lockForCtrl_C;
Cond condForCtrl_C;
bool finishForCtrl_C = false;


Lock::Lock() {
  pthread_mutexattr_t attr;

  // Initialize the mutex attributes
  int errorcode = pthread_mutexattr_init(&attr);
  assert(errorcode == 0); 

  // Initialize the mutex as a recursive mutex, if requested, or normal
  // otherwise.
  int kind = PTHREAD_MUTEX_NORMAL;
  errorcode = pthread_mutexattr_settype(&attr, kind);
  assert(errorcode == 0); 

#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && \
    !defined(__DragonFly__)
  // Make it a process local mutex
  errorcode = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE);
#endif

  // Initialize the mutex
  errorcode = pthread_mutex_init(&internalLock, &attr);
  assert(errorcode == 0); 

  // Destroy the attributes
  errorcode = pthread_mutexattr_destroy(&attr);
  assert(errorcode == 0);

  owner = 0;
}

Lock::~Lock() {
  pthread_mutex_destroy((pthread_mutex_t*)&internalLock);
}

bool Lock::selfOwner(vmkit::Thread* ownerThread) {
  if (!ownerThread) ownerThread = vmkit::Thread::get();
  return owner == ownerThread;
}

vmkit::Thread* Lock::getOwner() {
  return owner;
}

void LockNormal::lock() {
  Thread* th = Thread::get();
  th->enterUncooperativeCode();
  pthread_mutex_lock((pthread_mutex_t*)&internalLock);
  th->leaveUncooperativeCode();
  owner = th;
}

int LockNormal::tryLock() {
  Thread* th = Thread::get();
  th->enterUncooperativeCode();
  //pthread_mutex_lock((pthread_mutex_t*)&internalLock);
  int r = pthread_mutex_trylock((pthread_mutex_t*)&internalLock);
  th->leaveUncooperativeCode();
  if (r == 0)
	  owner = th;
  return r;
}

void LockNormal::unlock(vmkit::Thread* ownerThread) {
  assert(selfOwner(ownerThread) && "Not owner when unlocking");
  owner = 0;
  pthread_mutex_unlock((pthread_mutex_t*)&internalLock);
}

void LockRecursive::lock() {
  if (!selfOwner()) {


    Thread* th = Thread::get();
    th->enterUncooperativeCode();
    pthread_mutex_lock((pthread_mutex_t*)&internalLock);
    assert((n == 0) && "Inconsistent state of recursive lock");
    th->leaveUncooperativeCode();
    owner = th;
  }
  else {
	  assert((n != 0) && "Inconsistent state of recursive lock");
  }
  ++n;
}

int LockRecursive::tryLock() {
  int res = -1;
  if (!selfOwner()) {
	  Thread* th = Thread::get();
	  th->enterUncooperativeCode();
    res = pthread_mutex_trylock((pthread_mutex_t*)&internalLock);
    if (!res) {
    	  ++n;
    	  owner = vmkit::Thread::get();
    }
    th->leaveUncooperativeCode();
  }
  else
	  n++;

  return res;
}

void LockRecursive::unlock(vmkit::Thread* ownerThread) {
  assert(selfOwner(ownerThread) && "Not owner when unlocking");
  --n;
  if (n == 0) {
    owner = 0;
    pthread_mutex_unlock((pthread_mutex_t*)&internalLock);
  }
}

int LockRecursive::unlockAll(vmkit::Thread* ownerThread) {
  assert(selfOwner(ownerThread) && "Not owner when unlocking all");
  int res = n;
  n = 0;
  owner = 0;
  pthread_mutex_unlock((pthread_mutex_t*)&internalLock);
  return res;
}

void LockRecursive::lockAll(int count) {
  if (selfOwner()) {
    n += count;
  } else {
    Thread* th = Thread::get();
    th->enterUncooperativeCode();
    pthread_mutex_lock((pthread_mutex_t*)&internalLock);
    th->leaveUncooperativeCode();
    owner = th;
    n = count;
  }
}

Cond::Cond() {
  int errorcode;
  errorcode = pthread_cond_init((pthread_cond_t*)&internalCond, NULL);
  assert(errorcode == 0); 
}

Cond::~Cond() {
  pthread_cond_destroy((pthread_cond_t*)&internalCond);
}

void Cond::broadcast() {
  pthread_cond_broadcast((pthread_cond_t*)&internalCond);
}

void Cond::wait(Lock* l) {
  assert(l->selfOwner());
  int n = l->unsafeUnlock();
  int res;
  Thread* th = Thread::get();
  th->enterUncooperativeCode();
  res = pthread_cond_wait((pthread_cond_t*)&internalCond,
													(pthread_mutex_t*)&(l->internalLock));
  th->leaveUncooperativeCode();

  assert(!res && "Error on wait");
  l->unsafeLock(n);
}

void Cond::signal() {
  pthread_cond_signal((pthread_cond_t*)&internalCond);
}

#define BILLION 1000000000
#define NANOSECS_PER_SEC 1000000000
#define NANOSECS_PER_MILLISEC 1000000
#define MAX_SECS 100000000
int Cond::timedWait(Lock* l, struct timeval *ref) { 
  struct timespec timeout; 
  struct timeval now;
  gettimeofday(&now, NULL); 
  timeout.tv_sec = now.tv_sec + ref->tv_sec; 
  timeout.tv_nsec = (now.tv_usec + ref->tv_usec) * 1000;
  if (timeout.tv_nsec > BILLION) {
    timeout.tv_sec++;
    timeout.tv_nsec -= BILLION;
  }
  if (timeout.tv_sec <= now.tv_sec) {
	  timeout.tv_sec = now.tv_sec;
	  timeout.tv_nsec = NANOSECS_PER_SEC >> 1;
  }
  
  assert(l->selfOwner());
  int n = l->unsafeUnlock();
  
  Thread* th = Thread::get();
  th->enterUncooperativeCode();
  int res = pthread_cond_timedwait((pthread_cond_t*)&internalCond, 
                                   (pthread_mutex_t*)&(l->internalLock),
                                   &timeout);
  

  if (res != 0) {
  		pthread_cond_destroy (&internalCond) ;
  		pthread_cond_init    (&internalCond, NULL);
  }
  th->leaveUncooperativeCode();

  assert((!res || res == ETIMEDOUT) && "Error on timed wait");
  l->unsafeLock(n);

  return res;
}



int Cond::myTimeWait(Lock* l, bool isAbsolute, int64_t nsec) {
	struct timeval now;
	struct timespec absTime;
	int status = gettimeofday(&now, NULL);
	assert(status == 0 && "gettimeofday");

	time_t max_secs = now.tv_sec + MAX_SECS;

	 if (isAbsolute) {
	    sint64 secs = nsec / 1000;
	    if (secs > max_secs) {
	      absTime.tv_sec = max_secs;
	    }
	    else {
	      absTime.tv_sec = secs;
	    }
	    absTime.tv_nsec = (nsec % 1000) * NANOSECS_PER_MILLISEC;
	}
	 else {
		sint64 secs = nsec / NANOSECS_PER_SEC;
		if (secs >= MAX_SECS) {
		  absTime.tv_sec = max_secs;
		  absTime.tv_nsec = 0;
		}
		else {
		  absTime.tv_sec = now.tv_sec + secs + 0; // 150 / 850 / 1000
		  absTime.tv_nsec = (nsec % NANOSECS_PER_SEC) + now.tv_usec*1000;
		  if (absTime.tv_nsec >= NANOSECS_PER_SEC) {
			absTime.tv_nsec -= NANOSECS_PER_SEC;
			++absTime.tv_sec; // note: this must be <= max_secs
		  }
		}
	 }

	assert(l->selfOwner());
	int n = l->unsafeUnlock();

	Thread* th = Thread::get();
	th->enterUncooperativeCode();
	int res = pthread_cond_timedwait((pthread_cond_t*)&internalCond,
								   (pthread_mutex_t*)&(l->internalLock),
								   &absTime);


	if (res != 0) {
		pthread_cond_destroy (&internalCond) ;
		pthread_cond_init    (&internalCond, NULL);
	}
	th->leaveUncooperativeCode();

	assert((!res || res == ETIMEDOUT) && "Error on timed wait");
	l->unsafeLock(n);

	return res;
}

}
