From: simonmar Date: Mon, 15 Dec 2003 16:23:54 +0000 (+0000) Subject: [project @ 2003-12-15 16:23:54 by simonmar] X-Git-Tag: Approx_11550_changesets_converted~200 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=56a125f20635ab93b34b50bbfe0d2c1280d560ba;p=ghc-hetmet.git [project @ 2003-12-15 16:23:54 by simonmar] Fix a deadlock: an OS thread returning from a C call could enter grabReturnCapability, grabbing the capability that was in the process of being passed to another thread via passCapability. This leads to a deadlock shortly afterward, because the passCapability flag is still set, so a normal worker won't pick up the capability when it is released. Fix (not sure if this is the best fix, though): don't grab the capability in grabReturnCapability() if passCapabilty is set. --- diff --git a/ghc/rts/Capability.c b/ghc/rts/Capability.c index 234962b..dd5d0e7 100644 --- a/ghc/rts/Capability.c +++ b/ghc/rts/Capability.c @@ -69,6 +69,9 @@ Condition thread_ready_cond = INIT_COND_VAR; * Task.startTask() uses its current value. */ nat rts_n_waiting_tasks = 0; + +static Condition *passTarget = NULL; +static rtsBool passingCapability = rtsFalse; #endif /* ----------------------------------------------------------------------------- @@ -245,7 +248,7 @@ grabReturnCapability(Mutex* pMutex, Capability** pCap) IF_DEBUG(scheduler, sched_belch("worker: returning; workers waiting: %d", rts_n_waiting_workers)); - if ( noCapabilities() ) { + if ( noCapabilities() || passingCapability ) { rts_n_waiting_workers++; wakeBlockedWorkerThread(); context_switch = 1; // make sure it's our turn soon @@ -316,9 +319,6 @@ yieldToReturningWorker(Mutex* pMutex, Capability** pCap, Condition* pThreadCond) * Post-condition: pMutex is held and *pCap is held by the current thread */ -static Condition *passTarget = NULL; -static rtsBool passingCapability = rtsFalse; - void waitForWorkCapability(Mutex* pMutex, Capability** pCap, Condition* pThreadCond) {