[vmkit-commits] [vmkit] r73170 - in /vmkit/trunk: include/mvm/Threads/Locks.h lib/JnJVM/Classpath/ClasspathVMThread.cpp lib/JnJVM/VMCore/JavaObject.cpp lib/JnJVM/VMCore/JavaObject.h lib/JnJVM/VMCore/JavaThread.h lib/Mvm/CommonThread/ctlock.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Wed Jun 10 10:33:55 PDT 2009


Author: geoffray
Date: Wed Jun 10 12:33:54 2009
New Revision: 73170

URL: http://llvm.org/viewvc/llvm-project?rev=73170&view=rev
Log:
Change the wait()/interrupt() implementation to not use a thread-local lock.


Modified:
    vmkit/trunk/include/mvm/Threads/Locks.h
    vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h
    vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h
    vmkit/trunk/lib/Mvm/CommonThread/ctlock.cpp

Modified: vmkit/trunk/include/mvm/Threads/Locks.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/Threads/Locks.h?rev=73170&r1=73169&r2=73170&view=diff

==============================================================================
--- vmkit/trunk/include/mvm/Threads/Locks.h (original)
+++ vmkit/trunk/include/mvm/Threads/Locks.h Wed Jun 10 12:33:54 2009
@@ -157,7 +157,8 @@
   
   virtual void lock();
   virtual void unlock();
-  
+  virtual int tryLock();
+
   /// recursionCount - Get the number of times the lock has been locked.
   ///
   int recursionCount() { return n; }

Modified: vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.cpp?rev=73170&r1=73169&r2=73170&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThread.cpp Wed Jun 10 12:33:54 2009
@@ -105,23 +105,39 @@
   Jnjvm* vm = JavaThread::get()->getJVM();
   JavaObject* vmthread = (JavaObject*)_vmthread;
   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->getObjectField(vmthread) == 0)
     mvm::Thread::yield();
   
   JavaThread* th = (JavaThread*)field->getObjectField(vmthread);
-  th->lock.lock();
   th->interruptFlag = 1;
+  LockObj* lock = th->waitsOn;
 
-  // here we could also raise a signal for interrupting I/O
-  if (th->state == JavaThread::StateWaiting) {
+  // If the thread is blocked on a wait. We also verify nextWaiting in case
+  // the thread has been notified.
+  if (lock && th->nextWaiting) {
     th->state = JavaThread::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 mvm::Thread::yield();
+    }
+    
+    // Interrupt the thread.
     th->varcond.signal();
+
+    // Release the lock if we acquired it.
+    if (locked) lock->release();
   }
-  
-  th->lock.unlock();
 
+  // Here we could also raise a signal for interrupting I/O
+  
   END_NATIVE_EXCEPTION
 }
 

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp?rev=73170&r1=73169&r2=73170&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp Wed Jun 10 12:33:54 2009
@@ -37,15 +37,14 @@
   if (owner()) {
     LockObj * l = lock.changeToFatlock(this);
     JavaThread* thread = JavaThread::get();
-    mvm::Lock& mutexThread = thread->lock;
+    thread->waitsOn = l;
     mvm::Cond& varcondThread = thread->varcond;
 
-    mutexThread.lock();
     if (thread->interruptFlag != 0) {
-      mutexThread.unlock();
       thread->interruptFlag = 0;
+      thread->waitsOn = 0;
       thread->getJVM()->interruptedException(this);
-    } else {
+    } else { 
       thread->state = JavaThread::StateWaiting;
       if (l->firstThread) {
         l->firstThread->prevWaiting->nextWaiting = thread;
@@ -64,19 +63,20 @@
              "Inconsistent list");
       
       bool timeout = false;
-      uint32 recur = l->lock.unlockAll();
 
-      if (timed) {
-        timeout = varcondThread.timedWait(&mutexThread, info);
-      } else {
-        varcondThread.wait(&mutexThread);
+      if (!thread->interruptFlag) {
+        if (timed) {
+          timeout = varcondThread.timedWait(&l->lock, info);
+        } else {
+          varcondThread.wait(&l->lock);
+        }
       }
 
+
       bool interrupted = (thread->interruptFlag != 0);
-      mutexThread.unlock();
-      l->lock.lockAll(recur);
 
       if (interrupted || timeout) {
+        
         if (thread->nextWaiting) {
           if (l->firstThread != thread) {
             thread->nextWaiting->prevWaiting = thread->prevWaiting;
@@ -94,10 +94,15 @@
           }
           thread->nextWaiting = 0;
           thread->prevWaiting = 0;
+        } else {
+          assert(!thread->prevWaiting && "Inconstitent state");
+          // Notify lost, notify someone else.
+          notify();
         }
       }
-
+      
       thread->state = JavaThread::StateRunning;
+      thread->waitsOn = 0;
 
       if (interrupted) {
         thread->interruptFlag = 0;
@@ -125,11 +130,10 @@
       JavaThread* cur = l->firstThread;
       if (cur) {
         do {
-          cur->lock.lock();
           if (cur->interruptFlag != 0) {
-            cur->lock.unlock();
             cur = cur->nextWaiting;
-          } else if (cur->javaThread != 0) {
+          } else {
+            assert(cur->javaThread && "No java thread");
             assert(cur->prevWaiting && cur->nextWaiting &&
                    "Inconsistent list");
             if (cur != l->firstThread) {
@@ -149,10 +153,7 @@
             cur->prevWaiting = 0;
             cur->nextWaiting = 0;
             cur->varcond.signal();
-            cur->lock.unlock();
             break;
-          } else {
-            cur->lock.unlock();
           }
         } while (cur != l->firstThread);
       }
@@ -170,12 +171,10 @@
       JavaThread* cur = l->firstThread;
       if (cur) {
         do {
-          cur->lock.lock();
           JavaThread* temp = cur->nextWaiting;
           cur->prevWaiting = 0;
           cur->nextWaiting = 0;
           cur->varcond.signal();
-          cur->lock.unlock();
           cur = temp;
         } while (cur != l->firstThread);
         l->firstThread = 0;

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h?rev=73170&r1=73169&r2=73170&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h Wed Jun 10 12:33:54 2009
@@ -52,6 +52,12 @@
     lock.lock();
   }
   
+  /// tryAcquire - Tries to acquire the lock.
+  ///
+  int tryAcquire() {
+    return lock.tryLock();
+  }
+  
   /// acquireAll - Acquires the lock nb times.
   void acquireAll(uint32 nb) {
     lock.lockAll(nb);

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h?rev=73170&r1=73169&r2=73170&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaThread.h Wed Jun 10 12:33:54 2009
@@ -24,6 +24,7 @@
 class Class;
 class JavaObject;
 class Jnjvm;
+class LockObj;
 
 
 #define BEGIN_NATIVE_EXCEPTION(level) \
@@ -76,10 +77,6 @@
   ///
   JavaObject* vmThread;
 
-  /// lock - This lock is used when waiting or being notified or interrupted.
-  ///
-  mvm::LockNormal lock;
-
   /// varcond - Condition variable when the thread needs to be awaken from
   /// a wait.
   ///
@@ -97,6 +94,10 @@
   ///
   JavaThread* prevWaiting;
 
+  /// waitsOn - The monitor on which the thread is waiting on.
+  ///
+  LockObj* waitsOn;
+
   static const unsigned int StateRunning;
   static const unsigned int StateWaiting;
   static const unsigned int StateInterrupted;

Modified: vmkit/trunk/lib/Mvm/CommonThread/ctlock.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/CommonThread/ctlock.cpp?rev=73170&r1=73169&r2=73170&view=diff

==============================================================================
--- vmkit/trunk/lib/Mvm/CommonThread/ctlock.cpp (original)
+++ vmkit/trunk/lib/Mvm/CommonThread/ctlock.cpp Wed Jun 10 12:33:54 2009
@@ -81,6 +81,16 @@
   ++n;
 }
 
+int LockRecursive::tryLock() {
+  int res = 0;
+  if (!selfOwner()) {
+    res = pthread_mutex_trylock((pthread_mutex_t*)&internalLock);
+    owner = mvm::Thread::get();
+  }
+  ++n;
+  return res;
+}
+
 void LockRecursive::unlock() {
   assert(selfOwner() && "Not owner when unlocking");
   --n;





More information about the vmkit-commits mailing list