#include "RtsUtils.h"
#include "ParTicky.h"
#include "Trace.h"
+#include "Prelude.h"
#include "SMP.h" // for cas
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 */
}
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 {
* -------------------------------------------------------------------------- */
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++;
}
/* -----------------------------------------------------------------------------
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);