X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;ds=sidebyside;f=rts%2FSparks.c;h=571529afbbc31b6f8d7c2e366f4b7635b754dde2;hb=65914a2cb71caf01655b16a75b283871e2482041;hp=8f52a611699c07f6d9403a452640feaeb7e74975;hpb=17a596022d01987d5ffe7db0742aa8db267b8cc3;p=ghc-hetmet.git diff --git a/rts/Sparks.c b/rts/Sparks.c index 8f52a61..571529a 100644 --- a/rts/Sparks.c +++ b/rts/Sparks.c @@ -44,6 +44,7 @@ #include "RtsUtils.h" #include "ParTicky.h" #include "Trace.h" +#include "Prelude.h" #include "SMP.h" // for cas @@ -201,10 +202,12 @@ steal(SparkPool *deque) StgClosurePtr stolen; StgWord b,t; - ASSERT_SPARK_POOL_INVARIANTS(deque); +// Can't do this on someone else's spark pool: +// ASSERT_SPARK_POOL_INVARIANTS(deque); b = deque->bottom; t = deque->top; + if (b - t <= 0 ) { return NULL; /* already looks empty, abort */ } @@ -221,14 +224,17 @@ steal(SparkPool *deque) return NULL; } /* else: OK, top has been incremented by the cas call */ - ASSERT_SPARK_POOL_INVARIANTS(deque); +// Can't do this on someone else's spark pool: +// ASSERT_SPARK_POOL_INVARIANTS(deque); + /* return stolen element */ return stolen; } StgClosure * -tryStealSpark (SparkPool *pool) +tryStealSpark (Capability *cap) { + SparkPool *pool = cap->sparks; StgClosure *stolen; do { @@ -264,13 +270,13 @@ looksEmpty(SparkPool* deque) * -------------------------------------------------------------------------- */ void -createSparkThread (Capability *cap, StgClosure *p) +createSparkThread (Capability *cap) { StgTSO *tso; - tso = createGenThread (cap, RtsFlags.GcFlags.initialStkSize, p); + tso = createIOThread (cap, RtsFlags.GcFlags.initialStkSize, + &base_GHCziConc_runSparks_closure); appendToRunQueue(cap,tso); - cap->sparks_converted++; } /* ----------------------------------------------------------------------------- @@ -387,6 +393,19 @@ pruneSparkQueue (evac_fn evac, void *user, Capability *cap) pool = cap->sparks; + // it is possible that top > bottom, indicating an empty pool. We + // fix that here; this is only necessary because the loop below + // assumes it. + if (pool->top > pool->bottom) + pool->top = pool->bottom; + + // Take this opportunity to reset top/bottom modulo the size of + // the array, to avoid overflow. This is only possible because no + // stealing is happening during GC. + pool->bottom -= pool->top & ~pool->moduloSize; + pool->top &= pool->moduloSize; + pool->topBound = pool->top; + debugTrace(DEBUG_sched, "markSparkQueue: current spark queue len=%d; (hd=%ld; tl=%ld)", sparkPoolSize(pool), pool->bottom, pool->top);