diff options
author | Simon Marlow <marlowsd@gmail.com> | 2008-11-06 11:36:39 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2008-11-06 11:36:39 +0000 |
commit | 2b16fa4791b08b02df8461f3b79d0e44d72d0960 (patch) | |
tree | 53d0bba9254703d7d569e91c0f0f7b19ba8f25f8 /rts/Capability.c | |
parent | ebfa6fde6d9797ad2434a2af73a4c85b2984e00a (diff) | |
download | haskell-2b16fa4791b08b02df8461f3b79d0e44d72d0960.tar.gz |
Run sparks in batches, instead of creating a new thread for each one
Signficantly reduces the overhead for par, which means that we can
make use of paralellism at a much finer granularity.
Diffstat (limited to 'rts/Capability.c')
-rw-r--r-- | rts/Capability.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/rts/Capability.c b/rts/Capability.c index c8103117c9..ddb47b4ac8 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 |