[vmkit-commits] FatLock assertion failure?
Will Dietz
wdietz2 at illinois.edu
Thu Dec 1 14:50:33 PST 2011
On Thu, Dec 1, 2011 at 3:19 PM, Nicolas Geoffray
<nicolas.geoffray at gmail.com> wrote:
> Thanks Will for debugging the problem! Indeed, I commented the releasing of
> the fat lock and it worked without any crashes. That's great news because it
> looks like we nailed it. The bad news though is that if we don't release a
> fat lock, it will never be able to get used again. Even worst is if we need
> to keep a pointer to the associated object. The lock will just keep that
> object alive forever.
> If it helps, I'm ok with submitting a change that basically comments out the
> release of a FatLock. When I'll have time, I'll investigate more at which
> point do we have a race.
> Cheers,
> Nicolas
>
Welcome, I was very glad at how well that fixes it myself :).
There are two issues you mention--one is worrying about consuming Lock
resources, and I think that's not really a concern. Looking at this:
http://www.research.ibm.com/people/d/dfb/thinlocks-publications.html#Bacon03Retrospective
They claim it never happens in practice, and only theoretically
happens in pathological cases. They also describe the difficulty of
deflation a tad (but not as well as others) including brief mentions
of solutions that might be of interest to VMKit. Anyway I don't think
we should worry about running out of space for locks.
The other issue you mention is miscalculating the liveness of an
object through its lock. I agree this is something we should fix but
I'm okay postponing it for now.
FWIW inlined below is a sample patch that's been working for me. If
you prefer we can comment out the code instead of removing it, I'm
fine either way. Removing the spinlocks/thread counts is a nice
bonus.
~Will
>From f4bf1be53feaa8b419fea8654c34fb04f735f61d Mon Sep 17 00:00:00 2001
From: Will Dietz <w at wdtz.org>
Date: Tue, 29 Nov 2011 14:24:44 -0600
Subject: [PATCH] Remove code that deflates fat locks, due to races it doesn't
work on SMP.
Fixes bug where multithreaded code would occasionally assert out with:
j3: /home/will/vmkit-svn/lib/vmkit/CommonThread/ObjectLocks.cpp:305:
bool vmkit::FatLock::acquire(gc *): Assertion `obj->header &
ThinLock::FatMask' failed.
---
include/vmkit/ObjectLocks.h | 9 +------
lib/vmkit/CommonThread/ObjectLocks.cpp | 43 +------------------------------
2 files changed, 3 insertions(+), 49 deletions(-)
diff --git a/include/vmkit/ObjectLocks.h b/include/vmkit/ObjectLocks.h
index 1b0b4d3..7409e80 100644
--- a/include/vmkit/ObjectLocks.h
+++ b/include/vmkit/ObjectLocks.h
@@ -68,9 +68,6 @@ public:
class FatLock : public vmkit::PermanentObject {
private:
vmkit::LockRecursive internalLock;
- vmkit::SpinLock spinLock;
- uint32_t waitingThreads;
- uint32_t lockingThreads;
LockingThread* firstThread;
gc* associatedObject;
uint32_t index;
@@ -171,14 +168,10 @@ public:
static const uint64_t ThinCountShift = NonLockBits;
static const uint64_t ThinCountAdd = 1LL << NonLockBits;
- /// initialise - Initialise the value of the lock.
- ///
- static void removeFatLock(FatLock* fatLock, LockSystem& table);
-
/// overflowThinlock - Change the lock of this object to a fat lock because
/// we have reached the maximum number of locks.
static void overflowThinLock(gc* object, LockSystem& table);
-
+
/// changeToFatlock - Change the lock of this object to a fat lock. The lock
/// may be in a thin lock or fat lock state.
static FatLock* changeToFatlock(gc* object, LockSystem& table);
diff --git a/lib/vmkit/CommonThread/ObjectLocks.cpp
b/lib/vmkit/CommonThread/ObjectLocks.cpp
index 9456045..cd99492 100644
--- a/lib/vmkit/CommonThread/ObjectLocks.cpp
+++ b/lib/vmkit/CommonThread/ObjectLocks.cpp
@@ -39,27 +39,7 @@ void ThinLock::overflowThinLock(gc* object,
LockSystem& table) {
} while (((object->header) & ~NonLockBitsMask) != ID);
assert(obj->associatedObject == object);
}
-
-/// initialise - Initialise the value of the lock.
-///
-void ThinLock::removeFatLock(FatLock* fatLock, LockSystem& table) {
- gc* object = fatLock->associatedObject;
- llvm_gcroot(object, 0);
- word_t ID;
- word_t oldValue = 0;
- word_t newValue = 0;
- word_t yieldedValue = 0;
- ID = fatLock->getID();
- do {
- oldValue = object->header;
- newValue = oldValue & NonLockBitsMask;
- yieldedValue = __sync_val_compare_and_swap(&object->header,
oldValue, newValue);
- } while (oldValue != yieldedValue);
- assert((oldValue & NonLockBitsMask) != ID);
- fatLock->associatedObject = NULL;
-}
-
FatLock* ThinLock::changeToFatlock(gc* object, LockSystem& table) {
llvm_gcroot(object, 0);
if (!(object->header & FatMask)) {
@@ -262,8 +242,6 @@ FatLock::FatLock(uint32_t i, gc* a) {
firstThread = NULL;
index = i;
setAssociatedObject(a);
- waitingThreads = 0;
- lockingThreads = 0;
nextFreeLock = NULL;
}
@@ -275,11 +253,6 @@ void FatLock::release(gc* obj, LockSystem& table) {
llvm_gcroot(obj, 0);
assert(associatedObject && "No associated object when releasing");
assert(associatedObject == obj && "Mismatch object in lock");
- if (!waitingThreads && !lockingThreads &&
- internalLock.recursionCount() == 1) {
- vmkit::ThinLock::removeFatLock(this, table);
- table.deallocate(this);
- }
internalLock.unlock();
}
@@ -287,16 +260,8 @@ void FatLock::release(gc* obj, LockSystem& table) {
///
bool FatLock::acquire(gc* obj) {
llvm_gcroot(obj, 0);
-
- spinLock.lock();
- lockingThreads++;
- spinLock.unlock();
-
+
internalLock.lock();
-
- spinLock.lock();
- lockingThreads--;
- spinLock.unlock();
if (associatedObject != obj) {
internalLock.unlock();
@@ -421,8 +386,6 @@ bool LockingThread::wait(
bool timeout = false;
- l->waitingThreads++;
-
while (!this->interruptFlag && this->nextWaiting) {
if (timed) {
timeout = varcondThread.timedWait(&l->internalLock, info);
@@ -432,9 +395,7 @@ bool LockingThread::wait(
}
}
assert(vmkit::ThinLock::owner(self, table) && "Not owner after wait");
-
- l->waitingThreads--;
-
+
assert((!l->firstThread || (l->firstThread->prevWaiting &&
l->firstThread->nextWaiting)) && "Inconsistent list");
--
1.7.5.1
More information about the vmkit-commits
mailing list