[vmkit-commits] [vmkit] r180504 - improving prk/unpark implementation
Peter Senna Tschudin
peter.senna at gmail.com
Thu Apr 25 10:18:52 PDT 2013
Author: peter.senna
Date: Thu Apr 25 12:17:21 2013
New Revision: 180504
URL: http://llvm.org/viewvc/llvm-project?rev=180504&view=rev
Log:
improving prk/unpark implementation
(cherry picked from commit db2918b65307f8acbf0fc92804182b599287edfa)
Modified:
vmkit/trunk/lib/j3/ClassLib/GNUClasspath/ClasspathVMThread.inc
vmkit/trunk/lib/j3/ClassLib/Unsafe.inc
vmkit/trunk/lib/j3/VMCore/JavaThread.cpp
vmkit/trunk/lib/j3/VMCore/JavaThread.h
vmkit/trunk/lib/j3/VMCore/Jnjvm.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=180504&r1=180503&r2=180504&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/ClassLib/GNUClasspath/ClasspathVMThread.inc (original)
+++ vmkit/trunk/lib/j3/ClassLib/GNUClasspath/ClasspathVMThread.inc Thu Apr 25 12:17:21 2013
@@ -126,7 +126,10 @@ JavaObject* vmthread) {
JavaThread* th = (JavaThread*)field->getInstanceObjectField(vmthread);
th->lockingThread.interruptFlag = 1;
- th->parkLock.interrupt();
+ //th->parkLock.interrupt();
+ //fprintf(stderr, "Interrupting started%lld\n", th->getThreadID());
+ th->parkLock.unpark();
+ //fprintf(stderr, "Interrupting done%lld\n", th->getThreadID());
vmkit::FatLock* lock = th->lockingThread.waitsOn;
// If the thread is blocked on a wait. We also verify nextWaiting in case
Modified: vmkit/trunk/lib/j3/ClassLib/Unsafe.inc
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/ClassLib/Unsafe.inc?rev=180504&r1=180503&r2=180504&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/ClassLib/Unsafe.inc (original)
+++ vmkit/trunk/lib/j3/ClassLib/Unsafe.inc Thu Apr 25 12:17:21 2013
@@ -486,7 +486,7 @@ JNIEXPORT void JNICALL Java_sun_misc_Uns
JavaObject* unsafe, jboolean isAbsolute, jlong time) {
llvm_gcroot(unsafe, 0);
JavaThread* thread = (JavaThread*)JavaThread::get();
- thread->parkLock.park(isAbsolute, time);
+ thread->parkLock.park(isAbsolute, time, thread);
}
JNIEXPORT void JNICALL Java_sun_misc_Unsafe_unpark(
@@ -511,7 +511,9 @@ JavaObject* unsafe, JavaObject* thread)
JavaThread::yield();
th = (JavaThread*)field->getInstanceObjectField(vmthread);
}
+ //fprintf(stderr, "unparking started %lld\n", th->getThreadID());
th->parkLock.unpark();
+ //fprintf(stderr, "unparking done %lld\n", th->getThreadID());
}
//===--- Monitor support --------------------------------------------------===//
Modified: vmkit/trunk/lib/j3/VMCore/JavaThread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/JavaThread.cpp?rev=180504&r1=180503&r2=180504&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/JavaThread.cpp (original)
+++ vmkit/trunk/lib/j3/VMCore/JavaThread.cpp Thu Apr 25 12:17:21 2013
@@ -206,58 +206,166 @@ void JavaThread::throwNullPointerExcepti
}
ParkLock::ParkLock() {
- permit = 1;
+ permit = 0;
}
ParkLock::~ParkLock() {
}
+inline void _OrderAccess_fence() {
+ // Always use locked addl since mfence is sometimes expensive
+ __sync_synchronize();
+ //__asm__ volatile ("lock; addl $0,0(%%esp)" : : : "cc", "memory");
+}
+
// Implementation of method park, see LockSupport.java
// time is in nanoseconds if !isAboslute, otherwise it is in milliseconds
-void ParkLock::park(bool isAbsolute, int64_t time) {
- JavaThread* thread = (JavaThread*)vmkit::Thread::get();
- lock.lock();
- if (permit == 0){
- permit = 1;
- __sync_synchronize();
- lock.unlock(thread);
- return;
- }
- if (isAbsolute && time == 0) {
- lock.unlock(thread);
- return;
- }
- if (time == 0) {
- thread->setState(vmkit::LockingThread::StateWaiting);
- permit = 2;
- __sync_synchronize();
- cond.wait(&lock);
- permit = 1;
- }
- else {
- thread->setState(vmkit::LockingThread::StateTimeWaiting);
- permit = 2;
- __sync_synchronize();
- cond.myTimeWait(&lock, isAbsolute, time);
- permit = 1;
- }
- thread->setState(vmkit::LockingThread::StateRunning);
- __sync_synchronize();
- lock.unlock(thread);
+void ParkLock::park(bool isAbsolute, int64_t time, JavaThread* thread) {
+// lock.lock();
+// if (permit == 0){
+// permit = 1;
+// __sync_synchronize();
+// lock.unlock(thread);
+// return;
+// }
+// if (isAbsolute && time == 0) {
+// lock.unlock(thread);
+// return;
+// }
+// if (thread->lockingThread.interruptFlag) {
+// lock.unlock(thread);
+// return;
+// }
+// if (time == 0) {
+// thread->setState(vmkit::LockingThread::StateWaiting);
+// //permit = 2;
+// __sync_synchronize();
+// cond.wait(&lock);
+// //if (permit == 2) permit = 1;
+// //permit = 1;
+// }
+// else {
+// thread->setState(vmkit::LockingThread::StateTimeWaiting);
+// //permit = 2;
+// __sync_synchronize();
+// cond.myTimeWait(&lock, isAbsolute, time);
+// //if (permit == 2) permit = 1;
+// //permit = 1;
+// }
+// thread->setState(vmkit::LockingThread::StateRunning);
+// __sync_synchronize();
+// lock.unlock(thread);
+ // Optional fast-path check:
+ // Return immediately if a permit is available.
+ if (permit > 0) {
+ permit = 0 ;
+ _OrderAccess_fence();//__sync_synchronize();//OrderAccess::fence();
+ return ;
+ }
+
+ // Optional optimization -- avoid state transitions if there's an interrupt pending.
+ // Check interrupt before trying to wait
+ if (thread->lockingThread.interruptFlag) {
+ return;
+ }
+
+ if (time < 0 || (isAbsolute && time == 0) ) { // don't wait at all
+ return;
+ }
+
+
+ // Enter safepoint region
+ // Beware of deadlocks such as 6317397.
+ // The per-thread Parker:: mutex is a classic leaf-lock.
+ // In particular a thread must never block on the Threads_lock while
+ // holding the Parker:: mutex. If safepoints are pending both the
+ // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock.
+ //ThreadBlockInVM tbivm(jt);
+
+ // Don't wait if cannot get lock since interference arises from
+ // unblocking. Also. check interrupt before trying wait
+ if (thread->lockingThread.interruptFlag || lock.tryLock() != 0) {
+ return;
+ }
+
+ //fprintf(stderr, "Starting method %lld\n", thread->getThreadID());
+
+ int status ;
+ if (permit > 0) { // no wait needed
+ permit = 0;
+ lock.unlock(thread);
+ _OrderAccess_fence();//__sync_synchronize();//OrderAccess::fence();
+ //fprintf(stderr, "Finishing method 0 %lld\n", thread->getThreadID());
+ return;
+ }
+
+ //OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
+ //jt->set_suspend_equivalent();
+ // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
+
+ if (time == 0) {
+ //thread->setState(vmkit::LockingThread::StateWaiting);
+ cond.wait(&lock);
+ } else {
+ //thread->setState(vmkit::LockingThread::StateTimeWaiting);
+ cond.myTimeWait(&lock, isAbsolute, time);
+ }
+ //thread->setState(vmkit::LockingThread::StateRunning);
+ permit = 0 ;
+ lock.unlock(thread);
+ // If externally suspended while waiting, re-suspend
+ //if (jt->handle_special_suspend_equivalent_condition()) {
+ // jt->java_suspend_self();
+ //}
+
+ __sync_synchronize();//OrderAccess::fence();
+ //fprintf(stderr, "Finishing method 1 %lld\n", thread->getThreadID());
}
void ParkLock::unpark() {
+
JavaThread* thread = (JavaThread*)vmkit::Thread::get();
- bool flag = false;
+ //bool flag = false;
+// lock.lock();
+// if (permit == 0) {
+// lock.unlock(thread);
+// return;
+// }
+// //if (permit != 0)
+// // flag = !__sync_bool_compare_and_swap(&permit, 1, 0);
+// permit = 0;
+// __sync_synchronize();
+// //flag = true;
+// cond.signal();
+// lock.unlock(thread);
+ //if (flag)
+ // cond.signal();
+ int s ;
lock.lock();
- if (permit != 0)
- flag = !__sync_bool_compare_and_swap(&permit, 1, 0);
- lock.unlock(thread);
- if (flag)
- cond.signal();
+ s = permit;
+ permit = 1;
+ _OrderAccess_fence();
+ if (s < 1) {
+ if (false) {
+ cond.signal();
+ lock.unlock(thread);
+ } else {
+ lock.unlock(thread);
+ cond.signal();
+ }
+ } else {
+ lock.unlock(thread);
+ }
}
-void ParkLock::interrupt() {
- cond.signal();
-}
+//void ParkLock::interrupt() {
+// //
+// if (lock.tryLock() == 0) {
+// JavaThread* thread = (JavaThread*)vmkit::Thread::get();
+// cond.signal();
+//
+// lock.unlock(thread);
+// }
+// _OrderAccess_fence();
+//}
Modified: vmkit/trunk/lib/j3/VMCore/JavaThread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/JavaThread.h?rev=180504&r1=180503&r2=180504&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/JavaThread.h (original)
+++ vmkit/trunk/lib/j3/VMCore/JavaThread.h Thu Apr 25 12:17:21 2013
@@ -68,9 +68,9 @@ public:
ParkLock();
~ParkLock();
- void park(bool isAbsolute, int64_t time);
+ void park(bool isAbsolute, int64_t time, JavaThread* thread);
void unpark();
- void interrupt();
+// void interrupt();
};
/// JavaThread - This class is the internal representation of a Java thread.
Modified: vmkit/trunk/lib/j3/VMCore/Jnjvm.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/Jnjvm.cpp?rev=180504&r1=180503&r2=180504&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/Jnjvm.cpp (original)
+++ vmkit/trunk/lib/j3/VMCore/Jnjvm.cpp Thu Apr 25 12:17:21 2013
@@ -44,6 +44,27 @@ const char* Jnjvm::dirSeparator = "/";
const char* Jnjvm::envSeparator = ":";
const unsigned int Jnjvm::Magic = 0xcafebabe;
+/**
+ * In JVM specification, the virtual machine should execute some code.
+ * See Runtime.addShutdownHook
+ * In GNUClasspath the default behavior when the program call System.exit
+ * is to execute such a code.
+ * Hence, the only mission of this thread is to call System.exit when
+ * the user press Ctrl_C
+ */
+void threadToDetectCtrl_C(vmkit::Thread* th) {
+ while (!vmkit::finishForCtrl_C) {
+ vmkit::lockForCtrl_C.lock();
+ vmkit::condForCtrl_C.wait(&vmkit::lockForCtrl_C);
+ vmkit::lockForCtrl_C.unlock(th);
+ }
+ fprintf(stderr, "Crazy stuff\n");
+ JavaThread* kk = (JavaThread*)th;
+ UserClass* cl = kk->getJVM()->upcalls->SystemClass;
+ kk->getJVM() -> upcalls->SystemExit->invokeIntStatic(kk->getJVM(), cl, 0);
+}
+
+
/// initialiseClass - Java class initialization. Java specification §2.17.5.
void UserClass::initialiseClass(Jnjvm* vm) {
@@ -1320,6 +1341,9 @@ void Jnjvm::runApplication(int argc, cha
argumentsInfo.argv = argv;
mainThread = new JavaThread(this);
mainThread->start((void (*)(vmkit::Thread*))mainJavaStart);
+
+ JavaThread* th = new JavaThread(this);
+ th->start((void (*)(vmkit::Thread*))threadToDetectCtrl_C);
}
Jnjvm::Jnjvm(vmkit::BumpPtrAllocator& Alloc,
More information about the vmkit-commits
mailing list