[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