[vmkit-commits] [vmkit] r145295 - in /vmkit/trunk/lib/j3: ClassLib/OpenJDK/JavaUpcalls.cpp ClassLib/OpenJDK/OpenJDK.inc VMCore/JavaThread.h

Will Dietz wdietz2 at illinois.edu
Mon Nov 28 14:27:03 PST 2011


Author: wdietz2
Date: Mon Nov 28 16:27:03 2011
New Revision: 145295

URL: http://llvm.org/viewvc/llvm-project?rev=145295&view=rev
Log:
Impl JVM_Sleep; create dummy per-thread 'sleepObject' to wait on.

Modified:
    vmkit/trunk/lib/j3/ClassLib/OpenJDK/JavaUpcalls.cpp
    vmkit/trunk/lib/j3/ClassLib/OpenJDK/OpenJDK.inc
    vmkit/trunk/lib/j3/VMCore/JavaThread.h

Modified: vmkit/trunk/lib/j3/ClassLib/OpenJDK/JavaUpcalls.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/ClassLib/OpenJDK/JavaUpcalls.cpp?rev=145295&r1=145294&r2=145295&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/ClassLib/OpenJDK/JavaUpcalls.cpp (original)
+++ vmkit/trunk/lib/j3/ClassLib/OpenJDK/JavaUpcalls.cpp Mon Nov 28 16:27:03 2011
@@ -224,14 +224,19 @@
                                  const char* thName, JavaObject* Group) {
   JavaObject* th = NULL;
   JavaObject* name = NULL;
+  JavaObject* sleep = NULL;
   llvm_gcroot(Group, 0);
   llvm_gcroot(th, 0);
   llvm_gcroot(name, 0);
+  llvm_gcroot(sleep, 0);
 
   assert(thName && thName[0] && "Invalid thread name!");
 
   th = newThread->doNew(vm);
+  sleep = OfObject->doNew(vm);
+
   myth->javaThread = th;
+  myth->sleepObject = sleep;
 
   name = vm->asciizToStr(thName);
 

Modified: vmkit/trunk/lib/j3/ClassLib/OpenJDK/OpenJDK.inc
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/ClassLib/OpenJDK/OpenJDK.inc?rev=145295&r1=145294&r2=145295&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/ClassLib/OpenJDK/OpenJDK.inc (original)
+++ vmkit/trunk/lib/j3/ClassLib/OpenJDK/OpenJDK.inc Mon Nov 28 16:27:03 2011
@@ -18,6 +18,7 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <limits.h>
 #include <signal.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
@@ -194,12 +195,16 @@
 /*
  * java.lang.System
  */
-JNIEXPORT jlong JNICALL
-JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored) {
+
+uint64 CurrentTimeMillis() {
   struct timeval tv;
   gettimeofday(&tv, NULL);
-  jlong time = (tv.tv_sec * 1000LL) + (tv.tv_usec / 1000LL);
-  return time;
+  return (tv.tv_sec * 1000LL) + (tv.tv_usec / 1000LL);
+}
+
+JNIEXPORT jlong JNICALL
+JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored) {
+  return CurrentTimeMillis();
 }
 
 JNIEXPORT jlong JNICALL
@@ -209,7 +214,7 @@
 
   gettimeofday(&tv, NULL);
 
-  jlong time = (tv.tv_sec * 1000000LL) + (tv.tv_usec / 1000000LL);
+  jlong time = tv.tv_sec * 1000000000LL + tv.tv_usec * 1000LL;
 
   return time;
 }
@@ -496,8 +501,8 @@
 
   Jnjvm* vm = thread->getJVM();
 
-  // Wait some time to let the creator initialise this field
-  while (thread->javaThread == NULL) {
+  // Wait some time to let the creator initialise the fields
+  while (thread->javaThread == NULL || thread->sleepObject == NULL) {
     vmkit::Thread::yield();
   }
 
@@ -517,10 +522,9 @@
   }
 
   assert(javaThread->getVirtualTable());
-  // Run the VMThread::run function
 
+  // Run the Thread::run() function
   UserClass* thClass = (UserClass*)JavaObject::getClass(javaThread);
-
   vm->upcalls->runThread->invokeIntSpecial(vm, thClass, javaThread);
 
   // Remove the thread from the list.
@@ -533,10 +537,12 @@
  */
 JNIEXPORT void JNICALL
 JVM_StartThread(JNIEnv *env, jobject _thread) {
+  JavaObject * sleepObject = 0;
   JavaObject * thread = 0;
   JavaThread * javaThread = 0;
   llvm_gcroot(thread, 0);
   llvm_gcroot(javaThread, 0);
+  llvm_gcroot(sleepObject, 0);
   BEGIN_JNI_EXCEPTION
 
   thread = *(JavaObject**)_thread;
@@ -544,11 +550,16 @@
   assert(thread->getVirtualTable());
   Jnjvm* vm = JavaThread::get()->getJVM();
 
+  // Create a placeholder 'sleepObject' that
+  // we track in same field as Classpath's VMThread,
+  // used solely for sleeping.
+  sleepObject = vm->upcalls->OfObject->doNew(vm);
+
   JavaThread * newTh = new JavaThread(vm);
   if (!newTh) vm->outOfMemoryError();
   newTh->start((void (*)(vmkit::Thread*))start);
 
-  newTh->initialise(thread, 0);
+  newTh->initialise(thread, sleepObject);
 
   RETURN_VOID_FROM_JNI
 
@@ -609,9 +620,63 @@
   vmkit::Thread::yield();
 }
 
+static struct timeval getTimeVal(long long ms) {
+  struct timeval ret;
+  long long seconds = ms / 1000LL;
+  ret.tv_usec = 1000LL * (ms % 1000LL);
+  ret.tv_sec = seconds > LONG_MAX ? LONG_MAX : seconds;
+  return ret;
+}
+
+
 JNIEXPORT void JNICALL
 JVM_Sleep(JNIEnv *env, jclass threadClass, jlong millis) {
-  NYI();
+
+  BEGIN_JNI_EXCEPTION
+
+  Jnjvm * vm = th->getJVM();
+
+  // Check for invalid sleep time
+  if (millis < 0)
+    th->getJVM()->illegalArgumentException("Negative sleep value");
+
+  // If Thread is interrupted, throw exception
+  if (th->lockingThread.interruptFlag != 0) {
+    th->lockingThread.interruptFlag = 0;
+    vm->interruptedException(NULL);
+    UNREACHABLE();
+  }
+
+  // Treat sleep(0) as yield.
+  if (millis == 0) {
+    vmkit::Thread::yield();
+    RETURN_VOID_FROM_JNI
+  }
+
+  // See the Classpath sleep() implementation for inspiration here.
+  // We use a dummy per-thread 'sleepObject' to wait on instead of using
+  // a VMThread, but otherwise same implementation.
+  assert(th->sleepObject && "Missing sleep object!");
+
+  uint64 now = CurrentTimeMillis();
+
+  JavaObject::acquire(th->sleepObject);
+  while(true) {
+    struct timeval tv = getTimeVal(millis);
+    JavaObject::timedWait(th->sleepObject, tv);
+
+    uint64 then = now;
+    now = CurrentTimeMillis();
+    uint64 timePassed = now - then;
+
+    if (timePassed >= millis) break;
+
+    millis -= timePassed;
+  }
+  JavaObject::release(th->sleepObject);
+
+  RETURN_VOID_FROM_JNI
+  END_JNI_EXCEPTION
 }
 
 JNIEXPORT jobject JNICALL

Modified: vmkit/trunk/lib/j3/VMCore/JavaThread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/JavaThread.h?rev=145295&r1=145294&r2=145295&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/JavaThread.h (original)
+++ vmkit/trunk/lib/j3/VMCore/JavaThread.h Mon Nov 28 16:27:03 2011
@@ -74,9 +74,13 @@
   ///
   JavaObject* javaThread;
 
-  /// vmThread - The VMThread object of this thread.
+  /// vmThread - The VMThread object of this thread. (GNU Classpath)
+  /// sleepObject - Empty Object used to wait on for sleeping (OpenJDK)
   ///
-  JavaObject* vmThread;
+  union {
+    JavaObject* vmThread;
+    JavaObject* sleepObject;
+  };
 
   vmkit::LockingThread lockingThread;
   





More information about the vmkit-commits mailing list