X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FCapability.c;h=d748aee7e6b91a94dc28f5faebdd6e8ac99e8fba;hb=ff374b57fde43d3ef4e2449be631c7a8bafc68fe;hp=a2910ad4ee2b2f8c6afb745799be12e4ca08d40b;hpb=85aa72b9dc6803685595936c61f3cab6faab815a;p=ghc-hetmet.git diff --git a/ghc/rts/Capability.c b/ghc/rts/Capability.c index a2910ad..d748aee 100644 --- a/ghc/rts/Capability.c +++ b/ghc/rts/Capability.c @@ -149,9 +149,11 @@ void grabCapability(Capability** cap) free_capabilities = (*cap)->link; rts_n_free_capabilities--; #endif - IF_DEBUG(scheduler, - fprintf(stderr,"worker thread (%p): got capability\n", - osThreadId())); +#ifdef RTS_SUPPORTS_THREADS + IF_DEBUG(scheduler, + fprintf(stderr,"worker thread (%p): got capability\n", + osThreadId())); +#endif } /* @@ -197,11 +199,15 @@ 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 - IF_DEBUG(scheduler, - fprintf(stderr,"worker thread (%p): released capability\n", - osThreadId())); +#ifdef RTS_SUPPORTS_THREADS + IF_DEBUG(scheduler, + fprintf(stderr,"worker thread (%p): released capability\n", + osThreadId())); +#endif return; } @@ -320,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) @@ -330,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); @@ -349,7 +355,7 @@ waitForWorkCapability(Mutex* pMutex, Capability** pCap, Condition* pThreadCond) osThreadId())); } } - passTarget = NULL; + passingCapability = rtsFalse; grabCapability(pCap); return; } @@ -374,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 */