[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