X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FCapability.c;h=ddb47b4ac813be223b852ecdc9e8c69939c8e93c;hb=2b16fa4791b08b02df8461f3b79d0e44d72d0960;hp=92396e9ef05d2d720d2648f42ee5fc2314cc88ba;hpb=bc2528b8ecae61495e7e94012fa17e2f97e8b346;p=ghc-hetmet.git diff --git a/rts/Capability.c b/rts/Capability.c index 92396e9..ddb47b4 100644 --- a/rts/Capability.c +++ b/rts/Capability.c @@ -54,7 +54,7 @@ globalWorkToDo (void) #endif #if defined(THREADED_RTS) -rtsBool +StgClosure * stealWork (Capability *cap) { /* use the normal Sparks.h interface (internally modified to enable @@ -70,7 +70,7 @@ stealWork (Capability *cap) "cap %d: Trying to steal work from other capabilities", cap->no); - if (n_capabilities == 1) { return rtsFalse; } // makes no sense... + if (n_capabilities == 1) { return NULL; } // makes no sense... do { retry = rtsFalse; @@ -85,7 +85,7 @@ stealWork (Capability *cap) if (emptySparkPoolCap(robbed)) // nothing to steal here continue; - spark = tryStealSpark(robbed->sparks); + spark = tryStealSpark(robbed); if (spark == NULL && !emptySparkPoolCap(robbed)) { // we conflicted with another thread while trying to steal; // try again later. @@ -96,16 +96,31 @@ stealWork (Capability *cap) debugTrace(DEBUG_sched, "cap %d: Stole a spark from capability %d", cap->no, robbed->no); - - createSparkThread(cap,spark); - return rtsTrue; + return spark; } // otherwise: no success, try next one } } while (retry); debugTrace(DEBUG_sched, "No sparks stolen"); - return rtsFalse; + return NULL; +} + +// Returns True if any spark pool is non-empty at this moment in time +// The result is only valid for an instant, of course, so in a sense +// is immediately invalid, and should not be relied upon for +// correctness. +rtsBool +anySparks (void) +{ + nat i; + + for (i=0; i < n_capabilities; i++) { + if (!emptySparkPoolCap(&capabilities[i])) { + return rtsTrue; + } + } + return rtsFalse; } #endif @@ -767,7 +782,6 @@ shutdownCapability (Capability *cap, Task *task, rtsBool safe) } debugTrace(DEBUG_sched, "capability %d is stopped.", cap->no); - freeCapability(cap); RELEASE_LOCK(&cap->lock); break; } @@ -805,14 +819,28 @@ tryGrabCapability (Capability *cap, Task *task) #endif /* THREADED_RTS */ -void -freeCapability (Capability *cap) { +static void +freeCapability (Capability *cap) +{ stgFree(cap->mut_lists); #if defined(THREADED_RTS) || defined(PARALLEL_HASKELL) freeSparkPool(cap->sparks); #endif } +void +freeCapabilities (void) +{ +#if defined(THREADED_RTS) + nat i; + for (i=0; i < n_capabilities; i++) { + freeCapability(&capabilities[i]); + } +#else + freeCapability(&MainCapability); +#endif +} + /* --------------------------------------------------------------------------- Mark everything directly reachable from the Capabilities. When using multiple GC threads, each GC thread marks all Capabilities