X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=rts%2FSparks.c;h=a826190941ce7cd5c033af3d3ed084ff33e618c9;hp=0fe8b61b81665be44e5c39d79ffe3eefcea0606f;hb=cf5905ea24904cf73a041fd7535e8723a668cb9a;hpb=dd56e9ab4544e83d27532a8d9058140bfe81825c diff --git a/rts/Sparks.c b/rts/Sparks.c index 0fe8b61..a826190 100644 --- a/rts/Sparks.c +++ b/rts/Sparks.c @@ -8,17 +8,11 @@ #include "PosixSource.h" #include "Rts.h" -#include "Storage.h" + #include "Schedule.h" -#include "SchedAPI.h" -#include "RtsFlags.h" #include "RtsUtils.h" -#include "ParTicky.h" #include "Trace.h" #include "Prelude.h" - -#include "SMP.h" // for cas - #include "Sparks.h" #if defined(THREADED_RTS) @@ -51,9 +45,9 @@ createSparkThread (Capability *cap) StgTSO *tso; tso = createIOThread (cap, RtsFlags.GcFlags.initialStkSize, - &base_GHCziConc_runSparks_closure); + (StgClosure *)runSparks_closure); - postEvent(cap, EVENT_CREATE_SPARK_THREAD, 0, tso->id); + traceEventCreateSparkThread(cap, tso->id); appendToRunQueue(cap,tso); } @@ -77,11 +71,10 @@ newSpark (StgRegTable *reg, StgClosure *p) if (closure_SHOULD_SPARK(p)) { pushWSDeque(pool,p); - } - - cap->sparks_created++; - - postEvent(cap, EVENT_CREATE_SPARK, cap->r.rCurrentTSO->id, 0); + cap->sparks_created++; + } else { + cap->sparks_dud++; + } return 1; } @@ -120,7 +113,7 @@ tryStealSpark (Capability *cap) * -------------------------------------------------------------------------- */ void -pruneSparkQueue (evac_fn evac, void *user, Capability *cap) +pruneSparkQueue (Capability *cap) { SparkPool *pool; StgClosurePtr spark, tmp, *elements; @@ -128,8 +121,6 @@ pruneSparkQueue (evac_fn evac, void *user, Capability *cap) StgWord botInd,oldBotInd,currInd; // indices in array (always < size) const StgInfoTable *info; - PAR_TICKY_MARK_SPARK_QUEUE_START(); - n = 0; pruned_sparks = 0; @@ -148,7 +139,7 @@ pruneSparkQueue (evac_fn evac, void *user, Capability *cap) pool->top &= pool->moduloSize; pool->topBound = pool->top; - debugTrace(DEBUG_sched, + debugTrace(DEBUG_sparks, "markSparkQueue: current spark queue len=%ld; (hd=%ld; tl=%ld)", sparkPoolSize(pool), pool->bottom, pool->top); @@ -206,29 +197,59 @@ pruneSparkQueue (evac_fn evac, void *user, Capability *cap) // We have to be careful here: in the parallel GC, another // thread might evacuate this closure while we're looking at it, // so grab the info pointer just once. - info = spark->header.info; - if (IS_FORWARDING_PTR(info)) { - tmp = (StgClosure*)UN_FORWARDING_PTR(info); - /* if valuable work: shift inside the pool */ - if (closure_SHOULD_SPARK(tmp)) { - elements[botInd] = tmp; // keep entry (new address) - botInd++; - n++; - } else { - pruned_sparks++; // discard spark - cap->sparks_pruned++; - } + if (GET_CLOSURE_TAG(spark) != 0) { + // Tagged pointer is a value, so the spark has fizzled. It + // probably never happens that we get a tagged pointer in + // the spark pool, because we would have pruned the spark + // during the previous GC cycle if it turned out to be + // evaluated, but it doesn't hurt to have this check for + // robustness. + pruned_sparks++; + cap->sparks_fizzled++; } else { - if (!(closure_flags[INFO_PTR_TO_STRUCT(info)->type] & _NS)) { - elements[botInd] = spark; // keep entry (new address) - evac (user, &elements[botInd]); - botInd++; - n++; + info = spark->header.info; + if (IS_FORWARDING_PTR(info)) { + tmp = (StgClosure*)UN_FORWARDING_PTR(info); + /* if valuable work: shift inside the pool */ + if (closure_SHOULD_SPARK(tmp)) { + elements[botInd] = tmp; // keep entry (new address) + botInd++; + n++; + } else { + pruned_sparks++; // discard spark + cap->sparks_fizzled++; + } + } else if (HEAP_ALLOCED(spark)) { + if ((Bdescr((P_)spark)->flags & BF_EVACUATED)) { + if (closure_SHOULD_SPARK(spark)) { + elements[botInd] = spark; // keep entry (new address) + botInd++; + n++; + } else { + pruned_sparks++; // discard spark + cap->sparks_fizzled++; + } + } else { + pruned_sparks++; // discard spark + cap->sparks_gcd++; + } } else { - pruned_sparks++; // discard spark - cap->sparks_pruned++; + if (INFO_PTR_TO_STRUCT(info)->type == THUNK_STATIC) { + if (*THUNK_STATIC_LINK(spark) != NULL) { + elements[botInd] = spark; // keep entry (new address) + botInd++; + n++; + } else { + pruned_sparks++; // discard spark + cap->sparks_gcd++; + } + } else { + pruned_sparks++; // discard spark + cap->sparks_fizzled++; + } } } + currInd++; // in the loop, we may reach the bounds, and instantly wrap around @@ -246,11 +267,9 @@ pruneSparkQueue (evac_fn evac, void *user, Capability *cap) pool->bottom = (oldBotInd <= botInd) ? botInd : (botInd + pool->size); // first free place we did not use (corrected by wraparound) - PAR_TICKY_MARK_SPARK_QUEUE_END(n); - - debugTrace(DEBUG_sched, "pruned %d sparks", pruned_sparks); + debugTrace(DEBUG_sparks, "pruned %d sparks", pruned_sparks); - debugTrace(DEBUG_sched, + debugTrace(DEBUG_sparks, "new spark queue len=%ld; (hd=%ld; tl=%ld)", sparkPoolSize(pool), pool->bottom, pool->top); @@ -284,7 +303,7 @@ traverseSparkQueue (evac_fn evac, void *user, Capability *cap) top++; } - debugTrace(DEBUG_sched, + debugTrace(DEBUG_sparks, "traversed spark queue, len=%ld; (hd=%ld; tl=%ld)", sparkPoolSize(pool), pool->bottom, pool->top); } @@ -296,7 +315,8 @@ traverseSparkQueue (evac_fn evac, void *user, Capability *cap) * * Could be called after GC, before Cap. release, from scheduler. * -------------------------------------------------------------------------- */ -void balanceSparkPoolsCaps(nat n_caps, Capability caps[]); +void balanceSparkPoolsCaps(nat n_caps, Capability caps[]) + GNUC3_ATTRIBUTE(__noreturn__); void balanceSparkPoolsCaps(nat n_caps STG_UNUSED, Capability caps[] STG_UNUSED) {