[vmkit-commits] [vmkit] r72722 - in /vmkit/trunk: include/mvm/Threads/Locks.h lib/JnJVM/VMCore/JavaClass.h lib/JnJVM/VMCore/JavaObject.cpp lib/JnJVM/VMCore/JavaObject.h lib/Mvm/CommonThread/ctlock.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Tue Jun 2 00:24:46 PDT 2009


Author: geoffray
Date: Tue Jun  2 02:24:46 2009
New Revision: 72722

URL: http://llvm.org/viewvc/llvm-project?rev=72722&view=rev
Log:
Bugfix in  wait() and add a couple of asserts.


Modified:
    vmkit/trunk/include/mvm/Threads/Locks.h
    vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h
    vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp
    vmkit/trunk/lib/JnJVM/VMCore/JavaObject.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=72722&r1=72721&r2=72722&view=diff

==============================================================================
--- vmkit/trunk/include/mvm/Threads/Locks.h (original)
+++ vmkit/trunk/include/mvm/Threads/Locks.h Tue Jun  2 02:24:46 2009
@@ -11,6 +11,7 @@
 #define MVM_LOCKS_H
 
 #include <pthread.h>
+#include <cassert>
 
 #include "mvm/Threads/Thread.h"
 
@@ -66,6 +67,11 @@
 ///
 class Lock {
   friend class Cond;
+  
+private:
+  virtual void unsafeLock(int n) = 0;
+  virtual int unsafeUnlock() = 0;
+
 protected:
   /// owner - Which thread is currently holding the lock?
   ///
@@ -74,12 +80,13 @@
   /// internalLock - The lock implementation of the platform.
   ///
   pthread_mutex_t internalLock;
+  
 
 public:
 
   /// Lock - Creates a lock, recursive if rec is true.
   ///
-  Lock(bool rec);
+  Lock();
   
   /// ~Lock - Give it a home.
   ///
@@ -105,8 +112,18 @@
 
 /// LockNormal - A non-recursive lock.
 class LockNormal : public Lock {
+  friend class Cond;
+private:
+  virtual void unsafeLock(int n) {
+    owner = mvm::Thread::get();
+  }
+  
+  virtual int unsafeUnlock() {
+    owner = 0;
+    return 0;
+  }
 public:
-  LockNormal() : Lock(false) {}
+  LockNormal() : Lock() {}
 
   virtual void lock();
   virtual void unlock();
@@ -115,14 +132,27 @@
 
 /// LockRecursive - A recursive lock.
 class LockRecursive : public Lock {
+  friend class Cond;
 private:
   
   /// n - Number of times the lock has been locked.
   ///
   int n;
 
+  virtual void unsafeLock(int a) {
+    n = a;
+    owner = mvm::Thread::get();
+  }
+  
+  virtual int unsafeUnlock() {
+    int ret = n;
+    n = 0;
+    owner = 0;
+    return ret;
+  }
+
 public:
-  LockRecursive() : Lock(true) { n = 0; }
+  LockRecursive() : Lock() { n = 0; }
   
   virtual void lock();
   virtual void unlock();
@@ -186,7 +216,7 @@
     if (!(lock & FatMask)) {
       TFatLock* obj = TFatLock::allocate(O);
       size_t val = (((size_t) obj) >> 1) | FatMask;
-      uint32 count = lock & 0xFF;
+      uint32 count = lock & ThinCountMask;
       obj->acquireAll(count + 1);
       lock = val;
       return obj;
@@ -235,10 +265,13 @@
         obj->acquire();
       }
     }
+
+    assert(owner() && "Not owner after quitting acquire!");
   }
 
   /// release - Release the lock.
   void release() {
+    assert(owner() && "Not owner when entering release!");
     uint64 id = mvm::Thread::get()->getThreadID();
     if (lock == id) {
       lock = 0;
@@ -272,7 +305,7 @@
   bool owner() {
     uint64 id = mvm::Thread::get()->getThreadID();
     if (id == lock) return true;
-    if ((lock & 0x7FFFFF00) == id) return true;
+    if ((lock & ThinMask) == id) return true;
     if (lock & FatMask) {
       TFatLock* obj = (TFatLock*)(lock << 1);
       return obj->owner();
@@ -280,6 +313,15 @@
     return false;
   }
 
+  mvm::Thread* getOwner() {
+    if (lock & FatMask) {
+      TFatLock* obj = (TFatLock*)(lock << 1);
+      return obj->getOwner();
+    } else {
+      return (mvm::Thread*)(lock & ThinMask);
+    }
+  }
+
   /// getFatLock - Get the fat lock is the lock is a fat lock, 0 otherwise.
   TFatLock* getFatLock() {
     if (lock & FatMask) {

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h Tue Jun  2 02:24:46 2009
@@ -388,7 +388,14 @@
     /// condVar - Used to wake threads waiting on the load/resolve/initialize
     /// process of this class, done by another thread.
     mvm::Cond condVar;
-    
+  
+    bool owner() {
+      return lockVar.selfOwner();
+    }
+
+    mvm::Thread* getOwner() {
+      return lockVar.getOwner();
+    }
 
     static FatLock* allocate(UserCommonClass* cl) {
       return new(cl->classLoader->allocator) FatLock();

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaObject.cpp Tue Jun  2 02:24:46 2009
@@ -94,13 +94,12 @@
       thread->interruptFlag = 0;
       thread->getJVM()->interruptedException(this);
     } else {
-      uint32_t recur = l->lock.recursionCount();
       JavaCond* cond = l->getCond();
       cond->wait(thread);
       thread->state = JavaThread::StateWaiting;
       
       bool timeout = false;
-      l->lock.unlockAll();
+      uint32 recur = l->lock.unlockAll();
 
       if (timed) {
         timeout = varcondThread.timedWait(&mutexThread, info);
@@ -126,6 +125,7 @@
   } else {
     JavaThread::get()->getJVM()->illegalMonitorStateException(this);
   }
+  assert(owner() && "Not owner after wait");
 }
 
 void JavaObject::wait() {
@@ -143,6 +143,7 @@
   } else {
     JavaThread::get()->getJVM()->illegalMonitorStateException(this);
   }
+  assert(owner() && "Not owner after notify");
 }
 
 void JavaObject::notifyAll() {
@@ -151,7 +152,9 @@
     if (l) l->getCond()->notifyAll();
   } else {
     JavaThread::get()->getJVM()->illegalMonitorStateException(this);
-  } 
+  }
+
+  assert(owner() && "Not owner after notifyAll");
 }
 
 void JavaObject::decapsulePrimitive(Jnjvm *vm, uintptr_t &buf,

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

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaObject.h Tue Jun  2 02:24:46 2009
@@ -100,6 +100,12 @@
   bool owner() {
     return lock.selfOwner();
   }
+ 
+  /// getOwner - Get the owner of this lock.
+  ///
+  mvm::Thread* getOwner() {
+    return lock.getOwner();
+  }
   
   /// getCond - Returns the conditation variable of this lock, allocating it
   /// if non-existant.

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

==============================================================================
--- vmkit/trunk/lib/Mvm/CommonThread/ctlock.cpp (original)
+++ vmkit/trunk/lib/Mvm/CommonThread/ctlock.cpp Tue Jun  2 02:24:46 2009
@@ -13,12 +13,14 @@
 #include "mvm/Threads/Locks.h"
 #include "mvm/Threads/Thread.h"
 #include "cterror.h"
+#include <cerrno>
 #include <sys/time.h>
+#include <pthread.h>
 
 
 using namespace mvm;
 
-Lock::Lock(bool recursive) {
+Lock::Lock() {
   pthread_mutexattr_t attr;
 
   // Initialize the mutex attributes
@@ -27,7 +29,7 @@
 
   // Initialize the mutex as a recursive mutex, if requested, or normal
   // otherwise.
-  int kind = ( recursive  ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL );
+  int kind = PTHREAD_MUTEX_NORMAL;
   errorcode = pthread_mutexattr_settype(&attr, kind);
   assert(errorcode == 0); 
 
@@ -66,30 +68,45 @@
 }
 
 void LockNormal::unlock() {
+  assert(selfOwner() && "Not owner when unlocking");
   owner = 0;
   pthread_mutex_unlock((pthread_mutex_t*)&internalLock);
 }
 
 void LockRecursive::lock() {
-  pthread_mutex_lock((pthread_mutex_t*)&internalLock);
-  if (!owner) owner = mvm::Thread::get();
+  if (!selfOwner()) {
+    pthread_mutex_lock((pthread_mutex_t*)&internalLock);
+    owner = mvm::Thread::get();
+  }
   ++n;
 }
 
 void LockRecursive::unlock() {
+  assert(selfOwner() && "Not owner when unlocking");
   --n;
-  if (n == 0) owner = 0;
-  pthread_mutex_unlock((pthread_mutex_t*)&internalLock);
+  if (n == 0) {
+    owner = 0;
+    pthread_mutex_unlock((pthread_mutex_t*)&internalLock);
+  }
 }
 
 int LockRecursive::unlockAll() {
+  assert(selfOwner() && "Not owner when unlocking all");
   int res = n;
-  while (n) unlock();
+  n = 0;
+  owner = 0;
+  pthread_mutex_unlock((pthread_mutex_t*)&internalLock);
   return res;
 }
 
 void LockRecursive::lockAll(int count) {
-  for (int i = 0; i < count; ++i) lock();
+  if (selfOwner()) {
+    n += count;
+  } else {
+    pthread_mutex_lock((pthread_mutex_t*)&internalLock);
+    owner = mvm::Thread::get();
+    n = count;
+  }
 }
 
 Cond::Cond() {
@@ -106,8 +123,14 @@
 }
 
 void Cond::wait(Lock* l) {
-  pthread_cond_wait((pthread_cond_t*)&internalCond,
-                    (pthread_mutex_t*)&(l->internalLock));
+
+  int n = l->unsafeUnlock();
+
+  int res = pthread_cond_wait((pthread_cond_t*)&internalCond,
+                              (pthread_mutex_t*)&(l->internalLock));
+
+  assert(!res && "Error on wait");
+  l->unsafeLock(n);
 }
 
 void Cond::signal() {
@@ -122,6 +145,15 @@
   gettimeofday(&now, &tz); 
   timeout.tv_sec = now.tv_sec + ref->tv_sec; 
   timeout.tv_nsec = now.tv_usec + ref->tv_usec;
-  return pthread_cond_timedwait((pthread_cond_t*)&internalCond, 
-                                (pthread_mutex_t*)&(l->internalLock), &timeout);
+  
+  int n = l->unsafeUnlock();
+  
+  int res = pthread_cond_timedwait((pthread_cond_t*)&internalCond, 
+                                   (pthread_mutex_t*)&(l->internalLock),
+                                   &timeout);
+  
+  assert((!res || res == ETIMEDOUT) && "Error on timed wait");
+  l->unsafeLock(n);
+
+  return res;
 }





More information about the vmkit-commits mailing list