//===---------- ctthread.cc - Thread implementation for VMKit -------------===//
//
//                            The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "debug.h"

#include "mvm/GC.h"
#include "mvm/MethodInfo.h"
#include "mvm/VirtualMachine.h"
#include "mvm/Threads/Cond.h"
#include "mvm/Threads/Locks.h"
#include "mvm/Threads/Thread.h"
#include "mvm/VMKit.h"

#include <cassert>
#include <csetjmp>
#include <cstdio>
#include <ctime>
#include <dlfcn.h>
#include <errno.h>
#include <pthread.h>
#include <sys/mman.h>
#include <sched.h>
#include <signal.h>
#include <unistd.h>

using namespace mvm;

Thread::Thread(VMKit* vmk) {
#ifdef RUNTIME_DWARF_EXCEPTIONS
	internalPendingException = 0;
#else
	lastExceptionBuffer = 0;
#endif
	vmkit = vmk;
	lastKnownFrame = 0;
	pendingException = 0;
	allVmsData = 0;
	state = 0;             // not daemon, not running
	vmk->registerPreparedThread(this);
}

void Thread::setDaemon() {
	if((state & THREAD_RUNNING) && !(state & THREAD_DAEMON))
		vmkit->nonDaemonThreadsManager.leaveNonDaemonMode();
	state |= THREAD_DAEMON;
}

void Thread::setNonDaemon() {
	if((state & THREAD_RUNNING) && (state & THREAD_DAEMON))
		vmkit->nonDaemonThreadsManager.enterNonDaemonMode();
	state &= ~THREAD_DAEMON;
}

void Thread::attach(VirtualMachine* vm) {
	vmData = allVmsData[vm->vmID];

	if(!vmData) {
		vmkit->vmkitLock();
		vmData = allVmsData[vm->vmID] = vm->buildVMThreadData(this);
		vmkit->vmkitUnlock();
	}
}

// must be protected by rendezvous.threadLock
void Thread::reallocAllVmsData(int old, int n) {
	VMThreadData **newData = new VMThreadData*[n];
	if(old) {
		memcpy(newData, allVmsData, old*sizeof(VMThreadData*));
		VMThreadData **oldData = allVmsData;
		allVmsData = newData;
		delete oldData;
	} else
		allVmsData = newData;
	memset(allVmsData + old*sizeof(VMThreadData*), 0, (n-old)*sizeof(VMThreadData*));
}

void Thread::tracer(uintptr_t closure) {
	mvm::Collector::markAndTraceRoot(&pendingException, closure);

	// should we take the vmkit lock? I suppose that all the threads are suspended during the collection...
	for(size_t i=0; i<vmkit->vmsArraySize; i++)
		if(allVmsData[i]) {
			allVmsData[i]->tracer(closure);
		}
}

int Thread::kill(void* tid, int signo) {
  return pthread_kill((pthread_t)tid, signo);
}

int Thread::kill(int signo) {
  return pthread_kill((pthread_t)internalThreadID, signo);
}

void Thread::exit(int value) {
  pthread_exit((void*)value);
}

void Thread::yield(void) {
  Thread* th = mvm::Thread::get();
  if (th->isMvmThread()) {
    if (th->doYield && !th->inRV) {
      th->vmkit->rendezvous.join();
    }
  }
  sched_yield();
}

void Thread::joinRVBeforeEnter() {
  vmkit->rendezvous.joinBeforeUncooperative(); 
}

void Thread::joinRVAfterLeave(void* savedSP) {
  vmkit->rendezvous.joinAfterUncooperative(savedSP); 
}

void Thread::startKnownFrame(KnownFrame& F) {
  // Get the caller of this function
  void** cur = (void**)FRAME_PTR();
  // Get the caller of the caller.
  cur = (void**)cur[0];
  F.previousFrame = lastKnownFrame;
  F.currentFP = cur;
  // This is used as a marker.
  F.currentIP = NULL;
  lastKnownFrame = &F;
}

void Thread::endKnownFrame() {
  assert(lastKnownFrame->currentIP == NULL);
  lastKnownFrame = lastKnownFrame->previousFrame;
}

void Thread::startUnknownFrame(KnownFrame& F) {
  // Get the caller of this function
  void** cur = (void**)FRAME_PTR();
  // Get the caller of the caller.
  cur = (void**)cur[0];
  F.previousFrame = lastKnownFrame;
  F.currentFP = cur;
  F.currentIP = FRAME_IP(cur);
  lastKnownFrame = &F;
}

void Thread::endUnknownFrame() {
  assert(lastKnownFrame->currentIP != NULL);
  lastKnownFrame = lastKnownFrame->previousFrame;
}

#if defined(__MACH__)
#define SELF_HANDLE RTLD_DEFAULT
#else
#define SELF_HANDLE 0
#endif

Thread* Thread::setPendingException(gc *obj) {
	llvm_gcroot(obj, 0);
  assert(pendingException == 0 && "pending exception already there?");
	pendingException = obj;
	return this;
}

void Thread::throwIt() {
  assert(pendingException);

#ifdef RUNTIME_DWARF_EXCEPTIONS
  // Use dlsym instead of getting the functions statically with extern "C"
  // because gcc compiles exceptions differently.
  typedef void* (*cxa_allocate_exception_type)(unsigned);
  typedef void  (*cxa_throw_type)(void*, void*, void*);
  
  static cxa_allocate_exception_type cxa_allocate_exception =
    (cxa_allocate_exception_type)(uintptr_t)
    dlsym(SELF_HANDLE, "__cxa_allocate_exception");
  
  static cxa_throw_type cxa_throw =
    (cxa_throw_type)(uintptr_t)
    dlsym(SELF_HANDLE, "__cxa_throw");
  
  void* exc = cxa_allocate_exception(0);
  // 32 = sizeof(_Unwind_Exception) in libgcc...  
  internalPendingException = (void*)((uintptr_t)exc - 32);
  cxa_throw(exc, 0, 0);
#else
#if defined(__MACH__)
  _longjmp(lastExceptionBuffer->buffer, 1);
#else
  longjmp(lastExceptionBuffer->buffer, 1);
#endif
#endif
}

void Thread::printBacktrace() {
  StackWalker Walker(this);

  while (MethodInfo* MI = Walker.get()) {
    MI->print(Walker.ip, Walker.addr);
    ++Walker;
  }
}

void Thread::getFrameContext(void** buffer) {
  mvm::StackWalker Walker(this);
  uint32_t i = 0;

  while (void* ip = *Walker) {
    buffer[i++] = ip;
    ++Walker;
  }
}

uint32_t Thread::getFrameContextLength() {
  mvm::StackWalker Walker(this);
  uint32_t i = 0;

  while (*Walker) {
    ++i;
    ++Walker;
  }
  return i;
}

MethodInfo* StackWalker::get() {
  if (addr == thread->baseSP) return 0;
  ip = FRAME_IP(addr);
  bool isStub = ((unsigned char*)ip)[0] == 0xCE;
  if (isStub) ip = addr[2];
  return thread->vmkit->IPToMethodInfo(ip);
}

void* StackWalker::operator*() {
  if (addr == thread->baseSP) return 0;
  ip = FRAME_IP(addr);
  bool isStub = ((unsigned char*)ip)[0] == 0xCE;
  if (isStub) ip = addr[2];
  return ip;
}

void StackWalker::operator++() {
  if (addr != thread->baseSP) {
    assert((addr < thread->baseSP) && "Corrupted stack");
    assert((addr < addr[0]) && "Corrupted stack");
    if ((frame != NULL) && (addr == frame->currentFP)) {
      assert(frame->currentIP == NULL);
      frame = frame->previousFrame;
      assert(frame != NULL);
      assert(frame->currentIP != NULL);
      addr = (void**)frame->currentFP;
      frame = frame->previousFrame;
    } else {
      addr = (void**)addr[0];
    }
  }
}

StackWalker::StackWalker(mvm::Thread* th) {
  thread = th;
  frame = th->lastKnownFrame;
  if (mvm::Thread::get() == th) {
    addr = (void**)FRAME_PTR();
    addr = (void**)addr[0];
  } else {
    addr = (void**)th->waitOnSP();
    if (frame) {
      assert(frame->currentFP >= addr);
    }
    if (frame && (addr == frame->currentFP)) {
      frame = frame->previousFrame;
      assert((frame == NULL) || (frame->currentIP == NULL));
    }
  }
  assert(addr && "No address to start with");
}


#ifdef WITH_LLVM_GCC
void Thread::scanStack(uintptr_t closure) {
  StackWalker Walker(this);
  while (MethodInfo* MI = Walker.get()) {
    MI->scan(closure, Walker.ip, Walker.addr);
    ++Walker;
  }
}

#else

void Thread::scanStack(uintptr_t closure) {
  register unsigned int  **max = (unsigned int**)(void*)this->baseSP;
  if (mvm::Thread::get() != this) {
    register unsigned int  **cur = (unsigned int**)this->waitOnSP();
    for(; cur<max; cur++) Collector::scanObject((void**)cur, closure);
  } else {
    jmp_buf buf;
    setjmp(buf);
    register unsigned int  **cur = (unsigned int**)&buf;
    for(; cur<max; cur++) Collector::scanObject((void**)cur, closure);
  }
}
#endif

void Thread::enterUncooperativeCode(unsigned level) {
  if (isMvmThread()) {
    if (!inRV) {
      assert(!lastSP && "SP already set when entering uncooperative code");
      // Get the caller.
      void* temp = FRAME_PTR();
      // Make sure to at least get the caller of the caller.
      ++level;
      while (level--) temp = ((void**)temp)[0];
      // The cas is not necessary, but it does a memory barrier.
      __sync_bool_compare_and_swap(&lastSP, 0, temp);
      if (doYield) joinRVBeforeEnter();
      assert(lastSP && "No last SP when entering uncooperative code");
    }
  }
}

void Thread::enterUncooperativeCode(void* SP) {
  if (isMvmThread()) {
    if (!inRV) {
      assert(!lastSP && "SP already set when entering uncooperative code");
      // The cas is not necessary, but it does a memory barrier.
      __sync_bool_compare_and_swap(&lastSP, 0, SP);
      if (doYield) joinRVBeforeEnter();
      assert(lastSP && "No last SP when entering uncooperative code");
    }
  }
}

void Thread::leaveUncooperativeCode() {
  if (isMvmThread()) {
    if (!inRV) {
      assert(lastSP && "No last SP when leaving uncooperative code");
      void* savedSP = lastSP;
      // The cas is not necessary, but it does a memory barrier.
      __sync_bool_compare_and_swap(&lastSP, lastSP, 0);
      // A rendezvous has just been initiated, join it.
      if (doYield) joinRVAfterLeave(savedSP);
      assert(!lastSP && "SP has a value after leaving uncooperative code");
    }
  }
}

void* Thread::waitOnSP() {
  // First see if we can get lastSP directly.
  void* sp = lastSP;
  if (sp) return sp;
  
  // Then loop a fixed number of iterations to get lastSP.
  for (uint32 count = 0; count < 1000; ++count) {
    sp = lastSP;
    if (sp) return sp;
  }
  
  // Finally, yield until lastSP is not set.
  while ((sp = lastSP) == NULL) mvm::Thread::yield();

  assert(sp != NULL && "Still no sp");
  return sp;
}


uintptr_t Thread::baseAddr = 0;

// These could be set at runtime.
#define STACK_SIZE 0x100000
#define NR_THREADS 255

#if (__WORDSIZE == 64)
#define START_ADDR 0x110000000
#define END_ADDR 0x170000000
#else
#define START_ADDR 0x10000000
#define END_ADDR 0x70000000
#endif

/// StackThreadManager - This class allocates all stacks for threads. Because
/// we want fast access to thread local data, and can not rely on platform
/// dependent thread local storage (eg pthread keys are inefficient, tls is
/// specific to Linux), we put thread local data at the bottom of the 
/// stack. A simple mask computes the thread local data , based on the current
/// stack pointer.
//
/// The stacks are allocated at boot time. They must all be in the memory range
/// 0x?0000000 and Ox(?+1)0000000, so that the thread local data can be computed
/// and threads have a unique ID.
///
class StackThreadManager {
public:
  uintptr_t baseAddr;
  uint32 allocPtr;
  uint32 used[NR_THREADS];
  LockNormal stackLock;

  StackThreadManager() {
    baseAddr = 0;
    uintptr_t ptr = START_ADDR;

    // Do an mmap at a fixed address. If the mmap fails for a given address
    // use the next one.
    while (!baseAddr && ptr != END_ADDR) {
      ptr = ptr + 0x10000000;
#if defined (__MACH__)
      uint32 flags = MAP_PRIVATE | MAP_ANON | MAP_FIXED;
#else
      uint32 flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED;
#endif
      baseAddr = (uintptr_t)mmap((void*)ptr, STACK_SIZE * NR_THREADS, 
                                 PROT_READ | PROT_WRITE, flags, -1, 0);
      if (baseAddr == (uintptr_t)MAP_FAILED) baseAddr = 0;
    }
    if (!baseAddr) {
      fprintf(stderr, "Can not allocate thread memory\n");
      abort();
    }
 
    // Protect the page after the first page. The first page contains thread
    // specific data. The second page has no access rights to catch stack
    // overflows.
    uint32 pagesize = getpagesize();
    for (uint32 i = 0; i < NR_THREADS; ++i) {
      uintptr_t addr = baseAddr + (i * STACK_SIZE) + pagesize;
      mprotect((void*)addr, pagesize, PROT_NONE);
    }

    memset((void*)used, 0, NR_THREADS * sizeof(uint32));
    allocPtr = 0;
    mvm::Thread::baseAddr = baseAddr;
  }

  uintptr_t allocate() {
    stackLock.lock();
    uint32 myIndex = 0;
    do {
      if (!used[myIndex]) {
        used[myIndex] = 1;
        break;
      }
      ++myIndex;
    } while (myIndex != NR_THREADS);
  
    stackLock.unlock();
    
    if (myIndex != NR_THREADS)
      return baseAddr + myIndex * STACK_SIZE;

    return 0;
  }

};


/// Static allocate a stack manager. In the future, this should be virtual
/// machine specific.
StackThreadManager TheStackManager;

extern void sigsegvHandler(int, siginfo_t*, void*);

/// internalThreadStart - The initial function called by a thread. Sets some
/// thread specific data, registers the thread to the GC and calls the
/// given routine of th.
///
void Thread::internalThreadStart(mvm::Thread* th) {
  th->baseSP  = FRAME_PTR();

  // Set the SIGSEGV handler to diagnose errors.
  struct sigaction sa;
  sigset_t mask;
  sigfillset(&mask);
  sa.sa_flags = SA_SIGINFO;
  sa.sa_mask = mask;
  sa.sa_sigaction = sigsegvHandler;
  sigaction(SIGSEGV, &sa, NULL);


  assert(th->vmkit && "VM not set in a thread");

  th->vmkit->rendezvous.prepareForJoin();
  th->routine(th);
	th->state &= ~THREAD_RUNNING;
	if(!(th->state & THREAD_DAEMON))
		th->vmkit->nonDaemonThreadsManager.leaveNonDaemonMode();
  th->vmkit->unregisterRunningThread(th);
}

/// start - Called by the creator of the thread to run the new thread.
/// The thread is in a detached state, because each virtual machine has
/// its own way of waiting for created threads.
int Thread::start(void (*fct)(mvm::Thread*)) {
  pthread_attr_t attributs;
  pthread_attr_init(&attributs);
  pthread_attr_setstack(&attributs, this, STACK_SIZE);
  routine = fct;
  // Make sure to add it in the list of threads before leaving this function:
  // the garbage collector wants to trace this thread.
	state |= THREAD_RUNNING;
	if(!(state & THREAD_DAEMON))
		vmkit->nonDaemonThreadsManager.enterNonDaemonMode();
  vmkit->registerRunningThread(this);
  int res = pthread_create((pthread_t*)(void*)(&internalThreadID), &attributs,
                           (void* (*)(void *))internalThreadStart, this);
  pthread_detach((pthread_t)internalThreadID);
  pthread_attr_destroy(&attributs);
  return res;
}

/// operator new - Get a stack from the stack manager. The Thread object
/// will be placed in the first page at the bottom of the stack. Hence
/// Thread objects can not exceed a page.
void* Thread::operator new(size_t sz) {
  assert(sz < (size_t)getpagesize() && "Thread local data too big");
  void* res = (void*)TheStackManager.allocate();
  // Give it a second chance.
  if (res == NULL) {
    Collector::collect();
    // Wait for the finalizer to have cleaned up the threads.
    while (res == NULL) {
      mvm::Thread::yield();
      res = (void*)TheStackManager.allocate();
    }
  }
  // Make sure the thread information is cleared.
  memset(res, 0, sz);
  return res;
}

void Thread::operator delete(void* th) {
  uintptr_t index = ((uintptr_t)th & Thread::IDMask);
  index = (index & ~TheStackManager.baseAddr) >> 20;
  TheStackManager.used[index] = 0;
}

Thread::~Thread() {
  // It seems like the pthread implementation in Linux is clearing with NULL
  // the stack of the thread. So we have to get the thread id before
  // calling pthread_join.
  void* thread_id = internalThreadID;
  if (thread_id != NULL) {
    // Wait for the thread to die.
    pthread_join((pthread_t)thread_id, NULL);
  }
	vmkit->unregisterPreparedThread(this);
}

