[vmkit-commits] [vmkit] r180485 - Implementing methods unpark/park in class sun.misc.Unsafe. Very important for performance in multithread-applications.
Peter Senna Tschudin
peter.senna at gmail.com
Thu Apr 25 10:17:04 PDT 2013
Author: peter.senna
Date: Thu Apr 25 12:15:33 2013
New Revision: 180485
URL: http://llvm.org/viewvc/llvm-project?rev=180485&view=rev
Log:
Implementing methods unpark/park in class sun.misc.Unsafe. Very important for performance in multithread-applications.
(cherry picked from commit 8a9e28bfb4101c4b7bbe9df45f820238decf764a)
Modified:
vmkit/trunk/lib/j3/ClassLib/GNUClasspath/ClasspathVMThread.inc
vmkit/trunk/lib/j3/ClassLib/Unsafe.inc
vmkit/trunk/lib/j3/VMCore/JavaObject.cpp
vmkit/trunk/lib/j3/VMCore/JavaThread.cpp
vmkit/trunk/lib/j3/VMCore/JavaThread.h
vmkit/trunk/lib/vmkit/CommonThread/ctlock.cpp
Modified: vmkit/trunk/lib/j3/ClassLib/GNUClasspath/ClasspathVMThread.inc
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/ClassLib/GNUClasspath/ClasspathVMThread.inc?rev=180485&r1=180484&r2=180485&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/ClassLib/GNUClasspath/ClasspathVMThread.inc (original)
+++ vmkit/trunk/lib/j3/ClassLib/GNUClasspath/ClasspathVMThread.inc Thu Apr 25 12:15:33 2013
@@ -126,6 +126,7 @@ JavaObject* vmthread) {
JavaThread* th = (JavaThread*)field->getInstanceObjectField(vmthread);
th->lockingThread.interruptFlag = 1;
+ th->parkLock.interrupt();
vmkit::FatLock* lock = th->lockingThread.waitsOn;
// If the thread is blocked on a wait. We also verify nextWaiting in case
@@ -240,7 +241,7 @@ JavaObject* vmthread) {
return obj;
}
else {
- switch (th->status) {
+ switch (th->state) {
case vmkit::LockingThread::StateWaiting:
obj = vm->asciizToStr("WAITING");
return obj;
Modified: vmkit/trunk/lib/j3/ClassLib/Unsafe.inc
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/ClassLib/Unsafe.inc?rev=180485&r1=180484&r2=180485&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/ClassLib/Unsafe.inc (original)
+++ vmkit/trunk/lib/j3/ClassLib/Unsafe.inc Thu Apr 25 12:15:33 2013
@@ -484,12 +484,34 @@ JavaObject* unsafe, jlong ptr, jlong val
//===--- Park/Unpark thread support ---------------------------------------===//
JNIEXPORT void JNICALL Java_sun_misc_Unsafe_park(
JavaObject* unsafe, jboolean isAbsolute, jlong time) {
- // Nothing, for now.
+ llvm_gcroot(unsafe, 0);
+ JavaThread* thread = (JavaThread*)JavaThread::get();
+ thread->parkLock.park(isAbsolute, time);
}
JNIEXPORT void JNICALL Java_sun_misc_Unsafe_unpark(
JavaObject* unsafe, JavaObject* thread) {
- // Nothing, for now.
+ llvm_gcroot(unsafe, 0);
+ llvm_gcroot(thread, 0);
+ JavaObject* vmthread;
+ llvm_gcroot(vmthread, 0);
+ Jnjvm* vm = JavaThread::get()->getJVM();
+ JavaField* field = vm->upcalls->vmdataVMThread;
+ JavaField* field2 = vm->upcalls->vmThread;
+
+ // It's possible that the thread to be interrupted has not finished
+ // its initialization. Wait until the initialization is done.
+ vmthread = field2->getInstanceObjectField(thread);
+ while (vmthread == 0) {
+ JavaThread::yield();
+ vmthread = field2->getInstanceObjectField(thread);
+ }
+ JavaThread* th = (JavaThread*)field->getInstanceObjectField(vmthread);
+ while (th == 0) {
+ JavaThread::yield();
+ th = (JavaThread*)field->getInstanceObjectField(vmthread);
+ }
+ th->parkLock.unpark();
}
//===--- Monitor support --------------------------------------------------===//
Modified: vmkit/trunk/lib/j3/VMCore/JavaObject.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/JavaObject.cpp?rev=180485&r1=180484&r2=180485&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/JavaObject.cpp (original)
+++ vmkit/trunk/lib/j3/VMCore/JavaObject.cpp Thu Apr 25 12:15:33 2013
@@ -84,9 +84,9 @@ void JavaObject::waitIntern(
UNREACHABLE();
}
- thread->status = (timed)? vmkit::LockingThread::StateTimeWaiting: vmkit::LockingThread::StateWaiting;
+ thread->state = (timed)? vmkit::LockingThread::StateTimeWaiting: vmkit::LockingThread::StateWaiting;
bool interrupted = thread->lockingThread.wait(self, table, info, timed);
- thread->status = vmkit::LockingThread::StateRunning;
+ thread->state = vmkit::LockingThread::StateRunning;
if (interrupted) {
thread->getJVM()->interruptedException(self);
@@ -238,9 +238,9 @@ void JavaObject::overflowThinLock(JavaOb
void JavaObject::acquire(JavaObject* self) {
llvm_gcroot(self, 0);
- JavaThread::get()->status = vmkit::LockingThread::StateBlocked;
+ JavaThread::get()->state = vmkit::LockingThread::StateBlocked;
vmkit::ThinLock::acquire(self, JavaThread::get()->getJVM()->lockSystem);
- JavaThread::get()->status = vmkit::LockingThread::StateRunning;
+ JavaThread::get()->state = vmkit::LockingThread::StateRunning;
}
void JavaObject::release(JavaObject* self) {
Modified: vmkit/trunk/lib/j3/VMCore/JavaThread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/JavaThread.cpp?rev=180485&r1=180484&r2=180485&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/JavaThread.cpp (original)
+++ vmkit/trunk/lib/j3/VMCore/JavaThread.cpp Thu Apr 25 12:15:33 2013
@@ -31,6 +31,7 @@ JavaThread::JavaThread(vmkit::VirtualMac
currentAddedReferences = NULL;
javaThread = NULL;
vmThread = NULL;
+ state = vmkit::LockingThread::StateRunning;
}
void JavaThread::initialise(JavaObject* thread, JavaObject* vmth) {
@@ -203,3 +204,96 @@ void JavaThread::throwNullPointerExcepti
MyVM->nullPointerException();
UNREACHABLE();
}
+
+ParkLock::ParkLock() {
+ permit = 1;
+}
+
+ParkLock::~ParkLock() {
+
+}
+
+// Fill the structure t with the values from time
+// time is in nanoseconds
+void ParkLock::calculateTime(timeval* t, uint64_t time) {
+ uint64_t milli = time / 10;
+ //uint64_t microseconds = time; // /1000
+ //uint64_t seconds = microseconds / 1000000;
+ //microseconds %= 1000000;
+ t->tv_sec = milli / 1000;
+ t->tv_usec = (milli % 1000) * 1000 + time / 1000;
+}
+
+#include <sys/time.h>
+
+// Implementation of method park, see LockSupport.java
+// time is in nanoseconds if !isAboslute, otherwise it is in milliseconds
+void ParkLock::park(bool isAbsolute, uint64_t time) {
+ JavaThread* thread = (JavaThread*)vmkit::Thread::get();
+ lock.lock();
+ if (permit == 0){
+ permit = 1;
+ __sync_synchronize();
+ lock.unlock(thread);
+ return;
+ }
+ if (isAbsolute) {
+ fprintf(stderr, "PUTA MADRE QUE LO PARIO\n");
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ uint64_t l = tv.tv_sec*1000L + tv.tv_usec / 1000; // to milliseconds
+ if (time <= l) {
+ lock.unlock(thread);
+ return;
+ }
+ time = time - l;
+ time *= 1000000; // to nanoseconds
+ }
+
+ if (time == 0) {
+ thread->setState(vmkit::LockingThread::StateWaiting);
+ permit = 2;
+ __sync_synchronize();
+ cond.wait(&lock);
+ permit = 1;
+ }
+ else {
+ timeval t;
+ calculateTime(&t, time);
+ thread->setState(vmkit::LockingThread::StateTimeWaiting);
+ permit = 2;
+ __sync_synchronize();
+ cond.timedWait(&lock, &t);
+ permit = 1;
+ }
+ thread->setState(vmkit::LockingThread::StateRunning);
+ __sync_synchronize();
+ //} catch (InterruptedException e) {
+ // permit = 1;
+ // th.interrupt();
+ //}
+ lock.unlock(thread);
+}
+
+void ParkLock::unpark() {
+ JavaThread* thread = (JavaThread*)vmkit::Thread::get();
+ lock.lock();
+ int p = permit;
+ if (p != 0) {
+ if (p == 2)
+ cond.signal();
+ else {
+ permit = 0;
+ __sync_synchronize();
+ }
+ }
+ lock.unlock(thread);
+}
+
+void ParkLock::interrupt() {
+ JavaThread* thread = (JavaThread*)vmkit::Thread::get();
+ lock.lock();
+ if (permit == 2)
+ cond.signal();
+ lock.unlock(thread);
+}
Modified: vmkit/trunk/lib/j3/VMCore/JavaThread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/JavaThread.h?rev=180485&r1=180484&r2=180485&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/JavaThread.h (original)
+++ vmkit/trunk/lib/j3/VMCore/JavaThread.h Thu Apr 25 12:15:33 2013
@@ -56,6 +56,25 @@ class Jnjvm;
th->enterUncooperativeCode(SP); \
return; } \
+/// This is used to implement park/unpark behavior.
+/// The functionalities is the foundation for java.util.concurrency package
+class ParkLock {
+private:
+ vmkit::LockNormal lock;
+ vmkit::Cond cond;
+ int permit;
+
+
+ void calculateTime(timeval* t, uint64_t time);
+
+public:
+ ParkLock();
+ ~ParkLock();
+
+ void park(bool isAbsolute, uint64_t time);
+ void unpark();
+ void interrupt();
+};
/// JavaThread - This class is the internal representation of a Java thread.
/// It maintains thread-specific information such as its state, the current
@@ -94,7 +113,11 @@ public:
///
JNILocalReferences* localJNIRefs;
- int status;
+ // State of this Thread
+ int state;
+
+ // Lock to implement park/unpark
+ ParkLock parkLock;
JavaObject** pushJNIRef(JavaObject* obj) {
@@ -113,7 +136,7 @@ public:
/// JavaThread - Empty constructor, used to get the VT.
///
JavaThread() {
- status = vmkit::LockingThread::StateRunning;
+ state = vmkit::LockingThread::StateRunning;
}
/// ~JavaThread - Delete any potential malloc'ed objects used by this thread.
@@ -211,7 +234,9 @@ public:
/// the stack.
///
uint32 getJavaFrameContext(void** buffer);
-
+
+ inline void setState(int a) { state= a; }
+
private:
/// internalClearException - Clear the C++ and Java exceptions
/// currently pending.
Modified: vmkit/trunk/lib/vmkit/CommonThread/ctlock.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/vmkit/CommonThread/ctlock.cpp?rev=180485&r1=180484&r2=180485&view=diff
==============================================================================
--- vmkit/trunk/lib/vmkit/CommonThread/ctlock.cpp (original)
+++ vmkit/trunk/lib/vmkit/CommonThread/ctlock.cpp Thu Apr 25 12:15:33 2013
@@ -184,7 +184,7 @@ int Cond::timedWait(Lock* l, struct time
&timeout);
th->leaveUncooperativeCode();
- assert((!res || res == ETIMEDOUT) && "Error on timed wait");
+ //assert((!res || res == ETIMEDOUT) && "Error on timed wait");
l->unsafeLock(n);
return res;
More information about the vmkit-commits
mailing list