From: <pi...@us...> - 2008-06-24 22:35:31
|
Revision: 14562 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=14562&view=rev Author: pizlo Date: 2008-06-24 15:35:29 -0700 (Tue, 24 Jun 2008) Log Message: ----------- potential fix for current eclipse crash having to due with queue mismanagement; as well I finally removed the dead code that should have been removed before Modified Paths: -------------- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/RVMThread.java Removed Paths: ------------- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/greenthreads/ rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/nativethreads/ Modified: rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/RVMThread.java =================================================================== --- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/RVMThread.java 2008-06-24 21:48:29 UTC (rev 14561) +++ rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/RVMThread.java 2008-06-24 22:35:29 UTC (rev 14562) @@ -1971,7 +1971,6 @@ waitObject = l.getLockedObject(); waitCount = l.getRecursionCount(); l.setOwnerId(0); - // PNT: FIXME: waiting cannot be protected by the lock itself! l.waiting.enqueue(this); l.mutex.unlock(); @@ -2004,10 +2003,19 @@ } monitor().unlock(); + if (l.waiting.isQueued(this)) { + l.mutex.lock(); + l.waiting.remove(this); /* in case we got here due to an interrupt + or a stop() rather than a notify */ + l.mutex.unlock(); + + // Note that the above must be done before attempting to acquire + // the lock, since acquiring the lock may require queueing the thread. + // But we cannot queue the thread if it is already on another + // queue. + } + // reacquire the lock, restoring the recursion count - // PNT: FIXME: waiting cannot be protected by the lock itself!! - l.waiting.remove(this); /* in case we got here due to an interrupt - or a stop() rather than a notify */ ObjectModel.genericLock(o); waitObject=null; if (waitCount != 1) { // reset recursion count This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pi...@us...> - 2008-06-28 06:52:12
|
Revision: 14614 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=14614&view=rev Author: pizlo Date: 2008-06-27 23:52:11 -0700 (Fri, 27 Jun 2008) Log Message: ----------- added a bunch of assertions and debug traces for figuring out the spinlock heisenbug, where spinlocks seem to remain to be held when they in fact shouldn't be Modified Paths: -------------- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/Lock.java rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/RVMThread.java rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/SpinLock.java rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/ThinLock.java Modified: rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/Lock.java =================================================================== --- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/Lock.java 2008-06-28 04:11:57 UTC (rev 14613) +++ rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/Lock.java 2008-06-28 06:52:11 UTC (rev 14614) @@ -120,6 +120,9 @@ * Constants */ + /** do debug tracing? */ + protected static final boolean trace = true; + /** Control the gathering of statistics */ public static final boolean STATS = false; @@ -465,6 +468,8 @@ if (me.cachedFreeLock != null) { Lock l = me.cachedFreeLock; me.cachedFreeLock = null; + VM.sysWriteln("Lock.allocate: returning ",Magic.objectAsAddress(l), + ", a cached free lock from Thread #",me.getThreadSlot()); return l; } @@ -480,6 +485,10 @@ globalFreeLocks--; } lockAllocationMutex.unlock(); + if (l!=null) { + VM.sysWriteln("Lock.allocate: returning ",Magic.objectAsAddress(l), + " from the global freelist for Thread #",me.getThreadSlot()); + } } else { l = new Lock(); // may cause thread switch (and processor loss) lockAllocationMutex.lock(); @@ -506,6 +515,11 @@ * Note: Derek and I BELIEVE that an isync is not required in the other processor because the lock is newly allocated - Bowen */ Magic.sync(); } + if (l!=null) { + VM.sysWriteln("Lock.allocate: returning ",Magic.objectAsAddress(l), + ", a freshly allocated lock for Thread #", + me.getThreadSlot()); + } } } return l; @@ -520,13 +534,22 @@ l.active = false; RVMThread me = RVMThread.getCurrentThread(); if (me.cachedFreeLock == null) { + VM.sysWriteln("Lock.free: setting ",Magic.objectAsAddress(l), + " as the cached free lock for Thread #", + me.getThreadSlot()); me.cachedFreeLock = l; } else { + VM.sysWriteln("Lock.free: returning ",Magic.objectAsAddress(l), + " to the global freelist for Thread #", + me.getThreadSlot()); returnLock(l); } } static void returnLock(Lock l) { + VM.sysWriteln("Lock.returnLock: returning ",Magic.objectAsAddress(l), + " to the global freelist for Thread #", + RVMThread.getCurrentThreadSlot()); lockAllocationMutex.lock(); l.nextFreeLock = globalFreeLock; globalFreeLock = l; @@ -695,3 +718,9 @@ } } } + +/* +Local Variables: + c-basic-offset: 2 +End: +*/ Modified: rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/RVMThread.java =================================================================== --- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/RVMThread.java 2008-06-28 04:11:57 UTC (rev 14613) +++ rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/RVMThread.java 2008-06-28 06:52:11 UTC (rev 14614) @@ -1810,6 +1810,7 @@ // returned cached free lock if (cachedFreeLock != null) { + if (VM.VerifyAssertions) VM._assert(!cachedFreeLock.mutex.lockHeld()); Lock.returnLock(cachedFreeLock); cachedFreeLock = null; } Modified: rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/SpinLock.java =================================================================== --- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/SpinLock.java 2008-06-28 04:11:57 UTC (rev 14613) +++ rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/SpinLock.java 2008-06-28 06:52:11 UTC (rev 14614) @@ -105,6 +105,8 @@ @Untraced RVMThread latestContender; + public boolean lockHeld() { return latestContender!=null; } + /** * Acquire a processor lock. */ @@ -228,6 +230,9 @@ VM.sysWriteln("Unexpectedly large spin lock contention in ",RVMThread.getCurrentThreadSlot(),"; lock held by nobody"); } else { VM.sysWriteln("Unexpectedly large spin lock contention in ",RVMThread.getCurrentThreadSlot(),"; lock held by ",t.getThreadSlot()); + if (t!=RVMThread.getCurrentThread()) { + VM.sysWriteln("But -- at least the spin lock is held by a different thread."); + } } RVMThread.dumpStack(); VM.sysFail("Unexpectedly large spin lock contention"); Modified: rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/ThinLock.java =================================================================== --- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/ThinLock.java 2008-06-28 04:11:57 UTC (rev 14613) +++ rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/ThinLock.java 2008-06-28 06:52:11 UTC (rev 14614) @@ -295,6 +295,9 @@ old = Magic.prepareWord(o, lockOffset); // check to see if another thread has already created a fat lock if (!(old.and(TL_FAT_LOCK_MASK).isZero())) { // already a fat lock in place + VM.sysWriteln("Thread #",RVMThread.getCurrentThreadSlot(), + ": freeing lock ",Magic.objectAsAddress(l), + " because we had a double-inflate"); Lock.free(l); l.mutex.unlock(); l = Lock.getLock(getLockIndex(old)); @@ -419,3 +422,9 @@ } } + +/* +Local Variables: + c-basic-offset: 2 +End: +*/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pi...@us...> - 2008-06-28 15:32:56
|
Revision: 14618 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=14618&view=rev Author: pizlo Date: 2008-06-28 08:32:55 -0700 (Sat, 28 Jun 2008) Log Message: ----------- fixed the spinlock heisenbug - it appears to have been a problem with my port of thin locks, where I was releasing the wrong spinlock Modified Paths: -------------- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/RVMThread.java rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/ThinLock.java Modified: rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/RVMThread.java =================================================================== --- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/RVMThread.java 2008-06-28 09:50:59 UTC (rev 14617) +++ rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/RVMThread.java 2008-06-28 15:32:55 UTC (rev 14618) @@ -1810,6 +1810,8 @@ // returned cached free lock if (cachedFreeLock != null) { + VM.sysWriteln("Thread #",threadSlot,": about to free lock ", + Magic.objectAsAddress(cachedFreeLock)); if (VM.VerifyAssertions) VM._assert(!cachedFreeLock.mutex.lockHeld()); Lock.returnLock(cachedFreeLock); cachedFreeLock = null; Modified: rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/ThinLock.java =================================================================== --- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/ThinLock.java 2008-06-28 09:50:59 UTC (rev 14617) +++ rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/ThinLock.java 2008-06-28 15:32:55 UTC (rev 14618) @@ -275,8 +275,8 @@ if (l == null) return false; // can't allocate locks during GC Lock rtn = attemptToInflate(o, lockOffset, l); if (l != rtn) { + l = rtn; l.mutex.lock(); - l = rtn; } return l.lockHeavyLocked(o); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pi...@us...> - 2008-06-28 17:05:09
|
Revision: 14619 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=14619&view=rev Author: pizlo Date: 2008-06-28 10:05:04 -0700 (Sat, 28 Jun 2008) Log Message: ----------- forgotten files Modified Paths: -------------- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/Lock.java rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/RVMThread.java rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/ThinLock.java Modified: rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/Lock.java =================================================================== --- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/Lock.java 2008-06-28 15:32:55 UTC (rev 14618) +++ rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/Lock.java 2008-06-28 17:05:04 UTC (rev 14619) @@ -468,8 +468,10 @@ if (me.cachedFreeLock != null) { Lock l = me.cachedFreeLock; me.cachedFreeLock = null; - VM.sysWriteln("Lock.allocate: returning ",Magic.objectAsAddress(l), - ", a cached free lock from Thread #",me.getThreadSlot()); + if (trace) { + VM.sysWriteln("Lock.allocate: returning ",Magic.objectAsAddress(l), + ", a cached free lock from Thread #",me.getThreadSlot()); + } return l; } @@ -485,7 +487,7 @@ globalFreeLocks--; } lockAllocationMutex.unlock(); - if (l!=null) { + if (trace && l!=null) { VM.sysWriteln("Lock.allocate: returning ",Magic.objectAsAddress(l), " from the global freelist for Thread #",me.getThreadSlot()); } @@ -515,7 +517,7 @@ * Note: Derek and I BELIEVE that an isync is not required in the other processor because the lock is newly allocated - Bowen */ Magic.sync(); } - if (l!=null) { + if (trace && l!=null) { VM.sysWriteln("Lock.allocate: returning ",Magic.objectAsAddress(l), ", a freshly allocated lock for Thread #", me.getThreadSlot()); @@ -534,22 +536,28 @@ l.active = false; RVMThread me = RVMThread.getCurrentThread(); if (me.cachedFreeLock == null) { - VM.sysWriteln("Lock.free: setting ",Magic.objectAsAddress(l), - " as the cached free lock for Thread #", - me.getThreadSlot()); + if (trace) { + VM.sysWriteln("Lock.free: setting ",Magic.objectAsAddress(l), + " as the cached free lock for Thread #", + me.getThreadSlot()); + } me.cachedFreeLock = l; } else { - VM.sysWriteln("Lock.free: returning ",Magic.objectAsAddress(l), - " to the global freelist for Thread #", - me.getThreadSlot()); + if (trace) { + VM.sysWriteln("Lock.free: returning ",Magic.objectAsAddress(l), + " to the global freelist for Thread #", + me.getThreadSlot()); + } returnLock(l); } } static void returnLock(Lock l) { - VM.sysWriteln("Lock.returnLock: returning ",Magic.objectAsAddress(l), - " to the global freelist for Thread #", - RVMThread.getCurrentThreadSlot()); + if (trace) { + VM.sysWriteln("Lock.returnLock: returning ",Magic.objectAsAddress(l), + " to the global freelist for Thread #", + RVMThread.getCurrentThreadSlot()); + } lockAllocationMutex.lock(); l.nextFreeLock = globalFreeLock; globalFreeLock = l; Modified: rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/RVMThread.java =================================================================== --- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/RVMThread.java 2008-06-28 15:32:55 UTC (rev 14618) +++ rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/RVMThread.java 2008-06-28 17:05:04 UTC (rev 14619) @@ -86,6 +86,8 @@ */ /** Trace thread blockage */ protected static final boolean traceBlock = false; + /** Trace thread start/stop */ + protected static final boolean traceAcct = false; /** Trace execution */ protected static final boolean trace = false; /** Trace thread termination */ @@ -1209,7 +1211,7 @@ break; } - /*if (traceBlock)*/ VM.sysWriteln("Thread #",threadSlot," is really blocked"); + if (traceBlock) VM.sysWriteln("Thread #",threadSlot," is really blocked"); // what if a GC request comes while we're here for a suspend() // request? @@ -1654,7 +1656,7 @@ sysCall.sysStashVmThreadInPthread(currentThread); - VM.sysWriteln("Thread #",currentThread.threadSlot," running!"); + if (traceAcct) VM.sysWriteln("Thread #",currentThread.threadSlot," running!"); if (trace) { VM.sysWriteln("Thread.startoff(): about to call ", currentThread.toString(), ".run()"); @@ -1684,7 +1686,7 @@ numActiveDaemons++; } acctLock.unlock(); - VM.sysWriteln("Thread #",threadSlot," starting!"); + if (traceAcct) VM.sysWriteln("Thread #",threadSlot," starting!"); sysCall.sysNativeThreadCreate(Magic.objectAsAddress(this), contextRegisters.ip, contextRegisters.getInnermostFramePointer()); @@ -1696,10 +1698,9 @@ */ @Interruptible public final void terminate() { - VM.sysWriteln("in terminate() for Thread #",threadSlot); + if (traceAcct) VM.sysWriteln("in terminate() for Thread #",threadSlot); if (VM.VerifyAssertions) VM._assert(getCurrentThread() == this); boolean terminateSystem = false; - if (trace) trace("Thread", "terminate"); if (traceTermination) { VM.disableGC(); VM.sysWriteln("[ BEGIN Verbosely dumping stack at time of thread termination"); @@ -1722,7 +1723,7 @@ } } - VM.sysWriteln("doing accounting..."); + if (traceAcct) VM.sysWriteln("doing accounting..."); acctLock.lock(); @@ -1736,7 +1737,7 @@ if (daemon) { numActiveDaemons -= 1; } - VM.sysWriteln("active = ",numActiveThreads,", daemons = ",numActiveDaemons); + if (traceAcct) VM.sysWriteln("active = ",numActiveThreads,", daemons = ",numActiveDaemons); if ((numActiveDaemons == numActiveThreads) && (VM.mainThread != null) && VM.mainThread.launched) { @@ -1759,10 +1760,10 @@ acctLock.unlock(); - VM.sysWriteln("done with accounting."); + if (traceAcct) VM.sysWriteln("done with accounting."); if (terminateSystem) { - VM.sysWriteln("terminating system."); + if (traceAcct) VM.sysWriteln("terminating system."); if (uncaughtExceptionCount > 0) /* Use System.exit so that any shutdown hooks are run. */ { if (VM.TraceExceptionDelivery) { @@ -1788,7 +1789,7 @@ if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); } - VM.sysWriteln("making joinable..."); + if (traceAcct) VM.sysWriteln("making joinable..."); // PNT: this is really iffy synchronized (this) { @@ -1796,9 +1797,9 @@ notifyAll(); } - VM.sysWriteln("Thread #",threadSlot," is joinable."); + if (traceAcct) VM.sysWriteln("Thread #",threadSlot," is joinable."); - VM.sysWriteln("killing jnienv..."); + if (traceAcct) VM.sysWriteln("killing jnienv..."); if (jniEnv != null) { // warning: this is synchronized! @@ -1806,27 +1807,31 @@ jniEnv = null; } - VM.sysWriteln("returning cached lock..."); + if (traceAcct) VM.sysWriteln("returning cached lock..."); // returned cached free lock if (cachedFreeLock != null) { - VM.sysWriteln("Thread #",threadSlot,": about to free lock ", - Magic.objectAsAddress(cachedFreeLock)); + if (Lock.trace) { + VM.sysWriteln("Thread #",threadSlot,": about to free lock ", + Magic.objectAsAddress(cachedFreeLock)); + } if (VM.VerifyAssertions) VM._assert(!cachedFreeLock.mutex.lockHeld()); Lock.returnLock(cachedFreeLock); cachedFreeLock = null; } - VM.sysWriteln("adding to aboutToTerminate..."); + if (traceAcct) VM.sysWriteln("adding to aboutToTerminate..."); addAboutToTerminate(); - VM.sysWriteln("acquireCount for my monitor: ",monitor().acquireCount); - VM.sysWriteln("timer ticks: ",timerTicks); - VM.sysWriteln("yieldpoints taken: ",yieldpointsTaken); - VM.sysWriteln("yieldpoints taken fully: ",yieldpointsTakenFully); + if (traceAcct) { + VM.sysWriteln("acquireCount for my monitor: ",monitor().acquireCount); + VM.sysWriteln("timer ticks: ",timerTicks); + VM.sysWriteln("yieldpoints taken: ",yieldpointsTaken); + VM.sysWriteln("yieldpoints taken fully: ",yieldpointsTakenFully); + } - VM.sysWriteln("finishing thread termination..."); + if (traceAcct) VM.sysWriteln("finishing thread termination..."); finishThreadTermination(); } @@ -3001,12 +3006,12 @@ public final void join(long ms, int ns) throws InterruptedException { RVMThread myThread = getCurrentThread(); if (VM.VerifyAssertions) VM._assert(myThread != this); - VM.sysWriteln("Joining on Thread #",threadSlot); + if (traceBlock) VM.sysWriteln("Joining on Thread #",threadSlot); synchronized(this) { if (ms == 0 && ns == 0) { while (!isJoinable) { wait(this); - VM.sysWriteln("relooping in join on Thread #",threadSlot); + if (traceBlock) VM.sysWriteln("relooping in join on Thread #",threadSlot); } } else { long startNano = Time.nanoTime(); Modified: rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/ThinLock.java =================================================================== --- rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/ThinLock.java 2008-06-28 15:32:55 UTC (rev 14618) +++ rvmroot/branches/RVM-PureNativeThread/working/rvm/src/org/jikesrvm/scheduler/ThinLock.java 2008-06-28 17:05:04 UTC (rev 14619) @@ -295,9 +295,11 @@ old = Magic.prepareWord(o, lockOffset); // check to see if another thread has already created a fat lock if (!(old.and(TL_FAT_LOCK_MASK).isZero())) { // already a fat lock in place - VM.sysWriteln("Thread #",RVMThread.getCurrentThreadSlot(), - ": freeing lock ",Magic.objectAsAddress(l), - " because we had a double-inflate"); + if (Lock.trace) { + VM.sysWriteln("Thread #",RVMThread.getCurrentThreadSlot(), + ": freeing lock ",Magic.objectAsAddress(l), + " because we had a double-inflate"); + } Lock.free(l); l.mutex.unlock(); l = Lock.getLock(getLockIndex(old)); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |