//===- ClasspathVMThread.cpp - GNU classpath java/lang/VMThread -----------===//
//
//                            The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "types.h"

#include "Classpath.h"
#include "JavaArray.h"
#include "JavaClass.h"
#include "JavaObject.h"
#include "JavaThread.h"
#include "JavaUpcalls.h"
#include "Jnjvm.h"

using namespace j3;

extern "C" {

// Never throws.
// Never calls Java code.
JNIEXPORT JavaObject* JNICALL Java_java_lang_VMThread_currentThread(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz
#endif
) {
  return JavaThread::get()->currentThread();
}

void start(JavaThread* thread) {

  JavaObjectVMThread* vmThread = NULL;
  JavaObject* javaThread = NULL;
  llvm_gcroot(vmThread, 0);
  llvm_gcroot(javaThread, 0);

  Jnjvm* vm = thread->getJVM();
  // Wait some time to let the creator initialise these fields.
  while ((thread->javaThread == NULL) || (thread->vmThread == NULL)) {
    vmkit::Thread::yield();
  }

  // Ok, now that the thread is created we can set the the value of vmdata,
  // which is the JavaThread object.
  vmThread = (JavaObjectVMThread*)thread->vmThread;
  assert(vmThread && "Didn't fix the vmThread of a j3 thread");
  assert(vmThread->getVirtualTable());
  JavaObjectVMThread::setVmdata(vmThread, thread);
  
  UserClass* vmthClass = (UserClass*)JavaObject::getClass(vmThread); 
  
  javaThread = thread->javaThread;
  assert(javaThread && "Didn't fix the javaThread of a j3 thread");
 
  assert(vmThread->getVirtualTable());
  assert(javaThread->getVirtualTable());
  // Run the VMThread::run function
  vm->upcalls->runVMThread->invokeIntSpecial(vm, vmthClass, vmThread);
 
  // Remove the thread from the list.
  bool isDaemon = vm->upcalls->daemon->getInstanceInt8Field(javaThread);
  if (!isDaemon) {
    vm->threadSystem.leave();
  }
}

JNIEXPORT void JNICALL Java_java_lang_VMThread_start(
#ifdef NATIVE_JNI
JNIEnv *env,
#endif
JavaObject* vmThread, sint64 stackSize) {

  JavaObject* javaThread = 0;
  llvm_gcroot(vmThread, 0);
  llvm_gcroot(javaThread, 0);

  BEGIN_NATIVE_EXCEPTION(0)

  Jnjvm* vm = JavaThread::get()->getJVM();
  
  // Classpath has set this field.
  javaThread = vm->upcalls->assocThread->getInstanceObjectField(vmThread);
  assert(javaThread && "VMThread with no Java equivalent");
 
  JavaThread* th = new JavaThread(vm);
  if (!th) vm->outOfMemoryError();

  // If the thread is not a daemon, it is added to the list of threads to
  // wait until exit.
  bool isDaemon = vm->upcalls->daemon->getInstanceInt8Field(javaThread);

  if (!isDaemon) {
    vm->threadSystem.enter();
  }

  th->start((void (*)(vmkit::Thread*))start);
  // Now that the thread has been created, initialise its object fields.
  th->initialise(javaThread, vmThread);

  END_NATIVE_EXCEPTION
}

JNIEXPORT void JNICALL Java_java_lang_VMThread_interrupt(
#ifdef NATIVE_JNI
JNIEnv *env,
#endif
JavaObject* vmthread) {
  gc* obj = NULL;
  llvm_gcroot(obj, 0);
  llvm_gcroot(vmthread, 0);  

  BEGIN_NATIVE_EXCEPTION(0)

  Jnjvm* vm = JavaThread::get()->getJVM();
  JavaField* field = vm->upcalls->vmdataVMThread; 
  
  // It's possible that the thread to be interrupted has not finished
  // its initialization. Wait until the initialization is done.
  while (field->getInstanceObjectField(vmthread) == 0)
    vmkit::Thread::yield();
  
  JavaThread* th = (JavaThread*)field->getInstanceObjectField(vmthread);
  th->lockingThread.interruptFlag = 1;
  th->parkLock.interrupt();
  //th->parkLock.unpark();
  vmkit::FatLock* lock = th->lockingThread.waitsOn;

  // If the thread is blocked on a wait. We also verify nextWaiting in case
  // the thread has been notified.
  if (lock && th->lockingThread.nextWaiting) {
    th->lockingThread.state = vmkit::LockingThread::StateInterrupted;
  
    // Make sure the thread is waiting.
    uint32 locked = 0;
    while (true) {
      locked = (lock->tryAcquire() == 0);
      if (locked || (lock->getOwner() != th && lock->getOwner() != 0))
        break;
      else vmkit::Thread::yield();
    }
    
    // Interrupt the thread.
    th->lockingThread.varcond.signal();

    // Release the lock if we acquired it.
    if (locked) lock->release(obj = lock->getAssociatedObject(), vm->lockSystem);
  }

  // Here we could also raise a signal for interrupting I/O
  
  END_NATIVE_EXCEPTION
}

// Never throws.
// Never calls Java code.
JNIEXPORT jboolean JNICALL Java_java_lang_VMThread_interrupted(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
) {
  JavaThread* th = JavaThread::get();
  uint32 interrupt = th->lockingThread.interruptFlag;
  th->lockingThread.interruptFlag = 0;
  return (jboolean)interrupt;
}

// Never throws.
// Never calls Java code.
JNIEXPORT jboolean JNICALL Java_java_lang_VMThread_isInterrupted(
#ifdef NATIVE_JNI
JNIEnv *env,
#endif
JavaObject* vmthread) {
  
  llvm_gcroot(vmthread, 0);

  Jnjvm* vm = JavaThread::get()->getJVM();
  JavaField* field = vm->upcalls->vmdataVMThread;
  JavaThread* th = (JavaThread*)field->getInstanceObjectField(vmthread);
  return (jboolean)th->lockingThread.interruptFlag;
}

// Never throws.
// Never calls Java code.
JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeSetPriority(
#ifdef NATIVE_JNI
JNIEnv *env,
#endif
JavaObject* vmthread, jint prio) {
  // Currently not implemented
  llvm_gcroot(vmthread, 0);
}

// Never throws.
// Never calls Java code.
JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeStop(
#ifdef NATIVE_JNI
JNIEnv *env,
#endif
JavaObject* vmthread, JavaObject* exc) {
  // Currently not implemented
  llvm_gcroot(vmthread, 0);
  llvm_gcroot(exc, 0);
}

// Never throws.
// Never calls Java code.
JNIEXPORT void JNICALL Java_java_lang_VMThread_yield(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
) {
  vmkit::Thread::yield();
}

JNIEXPORT JavaObject* JNICALL Java_java_lang_VMThread_getState(
#ifdef NATIVE_JNI
JNIEnv *env,
#endif
JavaObject* vmthread) {
  JavaString* obj = NULL;
  llvm_gcroot(obj, 0);
  llvm_gcroot(vmthread, 0);  

  BEGIN_NATIVE_EXCEPTION(0)

  Jnjvm* vm = JavaThread::get()->getJVM();
  JavaField* field = vm->upcalls->vmdataVMThread; 
  
  // It's possible that the thread to be interrupted has not finished
  // its initialization. Wait until the initialization is done.
  JavaThread* th = (JavaThread*)field->getInstanceObjectField(vmthread);
  if (th == 0) {
    obj = vm->asciizToStr("NEW");
    return obj;
  }
  else {
  	switch (th->state) {
  		case vmkit::LockingThread::StateWaiting:
  			obj = vm->asciizToStr("WAITING");
  			return obj;
  		case vmkit::LockingThread::StateTimeWaiting:
  			obj = vm->asciizToStr("TIMED_WAITING");
  			return obj;
  		case vmkit::LockingThread::StateBlocked:
  			obj = vm->asciizToStr("BLOCKED");
  			return obj;
  		default: // both RUNNABLE and INTERRUPTED
  			obj = vm->asciizToStr("RUNNABLE");
  			return obj;
  	}
  }
  
  END_NATIVE_EXCEPTION
}


}
