X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FCapability.c;h=d748aee7e6b91a94dc28f5faebdd6e8ac99e8fba;hb=324e96d2ebfcb113cd97c43ef043d591ef87de71;hp=74d50acea205f22185dfde92ca007570725a501b;hpb=aefc6956f4828708e1343cf4858296fc3141a176;p=ghc-hetmet.git diff --git a/ghc/rts/Capability.c b/ghc/rts/Capability.c index 74d50ac..d748aee 100644 --- a/ghc/rts/Capability.c +++ b/ghc/rts/Capability.c @@ -199,6 +199,8 @@ void releaseCapability(Capability* cap #endif /* Signal that a capability is available */ signalCondition(&thread_ready_cond); + startSchedulerTaskIfNecessary(); // if there is more work to be done, + // we'll need a new thread } #endif #ifdef RTS_SUPPORTS_THREADS @@ -324,6 +326,7 @@ yieldToReturningWorker(Mutex* pMutex, Capability** pCap, Condition* pThreadCond) */ static Condition *passTarget = NULL; +static rtsBool passingCapability = rtsFalse; void waitForWorkCapability(Mutex* pMutex, Capability** pCap, Condition* pThreadCond) @@ -334,8 +337,7 @@ waitForWorkCapability(Mutex* pMutex, Capability** pCap, Condition* pThreadCond) IF_DEBUG(scheduler, fprintf(stderr,"worker thread (%p): wait for cap (cond: %p)\n", osThreadId(),pThreadCond)); - while ( noCapabilities() || (pThreadCond && passTarget != pThreadCond) - || (!pThreadCond && passTarget)) { + while ( noCapabilities() || (passingCapability && passTarget != pThreadCond)) { if(pThreadCond) { waitCondition(pThreadCond, pMutex); @@ -353,7 +355,7 @@ waitForWorkCapability(Mutex* pMutex, Capability** pCap, Condition* pThreadCond) osThreadId())); } } - passTarget = NULL; + passingCapability = rtsFalse; grabCapability(pCap); return; } @@ -378,11 +380,40 @@ passCapability(Mutex* pMutex, Capability* cap, Condition *pTargetThreadCond) rts_n_free_capabilities = 1; signalCondition(pTargetThreadCond); passTarget = pTargetThreadCond; + passingCapability = rtsTrue; IF_DEBUG(scheduler, fprintf(stderr,"worker thread (%p): passCapability\n", osThreadId())); } +/* + * Function: passCapabilityToWorker(Mutex*, Capability*) + * + * Purpose: Let go of the capability and make sure that a + * "plain" worker thread (not a bound thread) gets it next. + * + * Pre-condition: pMutex is held and cap is held by the current thread + * Post-condition: pMutex is held; cap will be grabbed by the "target" + * thread when pMutex is released. + */ + +void +passCapabilityToWorker(Mutex* pMutex, Capability* cap) +{ +#ifdef SMP + #error SMP version not implemented +#endif + rts_n_free_capabilities = 1; + signalCondition(&thread_ready_cond); + startSchedulerTaskIfNecessary(); + passTarget = NULL; + passingCapability = rtsTrue; + IF_DEBUG(scheduler, + fprintf(stderr,"worker thread (%p): passCapabilityToWorker\n", + osThreadId())); +} + + #endif /* RTS_SUPPORTS_THREADS */