Commit 31373447 authored by simonmar@microsoft.com's avatar simonmar@microsoft.com
Browse files

have each GC thread call GetRoots()

parent eea6454f
......@@ -108,68 +108,65 @@ findSpark (Capability *cap)
* -------------------------------------------------------------------------- */
void
markSparkQueue (evac_fn evac)
markSparkQueue (evac_fn evac, Capability *cap)
{
StgClosure **sparkp, **to_sparkp;
nat i, n, pruned_sparks; // stats only
nat n, pruned_sparks; // stats only
StgSparkPool *pool;
Capability *cap;
PAR_TICKY_MARK_SPARK_QUEUE_START();
n = 0;
pruned_sparks = 0;
for (i = 0; i < n_capabilities; i++) {
cap = &capabilities[i];
pool = &(cap->r.rSparks);
ASSERT_SPARK_POOL_INVARIANTS(pool);
pool = &(cap->r.rSparks);
ASSERT_SPARK_POOL_INVARIANTS(pool);
#if defined(PARALLEL_HASKELL)
// stats only
n = 0;
pruned_sparks = 0;
// stats only
n = 0;
pruned_sparks = 0;
#endif
sparkp = pool->hd;
to_sparkp = pool->hd;
while (sparkp != pool->tl) {
ASSERT(*sparkp!=NULL);
ASSERT(LOOKS_LIKE_CLOSURE_PTR(((StgClosure *)*sparkp)));
// ToDo?: statistics gathering here (also for GUM!)
if (closure_SHOULD_SPARK(*sparkp)) {
evac(sparkp);
*to_sparkp++ = *sparkp;
if (to_sparkp == pool->lim) {
to_sparkp = pool->base;
}
n++;
} else {
pruned_sparks++;
}
sparkp++;
if (sparkp == pool->lim) {
sparkp = pool->base;
}
}
pool->tl = to_sparkp;
sparkp = pool->hd;
to_sparkp = pool->hd;
while (sparkp != pool->tl) {
ASSERT(*sparkp!=NULL);
ASSERT(LOOKS_LIKE_CLOSURE_PTR(((StgClosure *)*sparkp)));
// ToDo?: statistics gathering here (also for GUM!)
if (closure_SHOULD_SPARK(*sparkp)) {
evac(sparkp);
*to_sparkp++ = *sparkp;
if (to_sparkp == pool->lim) {
to_sparkp = pool->base;
}
n++;
} else {
pruned_sparks++;
}
sparkp++;
if (sparkp == pool->lim) {
sparkp = pool->base;
}
}
pool->tl = to_sparkp;
PAR_TICKY_MARK_SPARK_QUEUE_END(n);
PAR_TICKY_MARK_SPARK_QUEUE_END(n);
#if defined(PARALLEL_HASKELL)
debugTrace(DEBUG_sched,
"marked %d sparks and pruned %d sparks on [%x]",
n, pruned_sparks, mytid);
debugTrace(DEBUG_sched,
"marked %d sparks and pruned %d sparks on [%x]",
n, pruned_sparks, mytid);
#else
debugTrace(DEBUG_sched,
"marked %d sparks and pruned %d sparks",
n, pruned_sparks);
debugTrace(DEBUG_sched,
"marked %d sparks and pruned %d sparks",
n, pruned_sparks);
#endif
debugTrace(DEBUG_sched,
"new spark queue len=%d; (hd=%p; tl=%p)\n",
sparkPoolSize(pool), pool->hd, pool->tl);
}
debugTrace(DEBUG_sched,
"new spark queue len=%d; (hd=%p; tl=%p)\n",
sparkPoolSize(pool), pool->hd, pool->tl);
}
/* -----------------------------------------------------------------------------
......
......@@ -13,7 +13,7 @@
StgClosure * findSpark (Capability *cap);
void initSparkPools (void);
void freeSparkPool (StgSparkPool *pool);
void markSparkQueue (evac_fn evac);
void markSparkQueue (evac_fn evac, Capability *cap);
void createSparkThread (Capability *cap, StgClosure *p);
INLINE_HEADER void discardSparks (StgSparkPool *pool);
......
......@@ -344,6 +344,11 @@ GarbageCollect ( rtsBool force_major_gc )
gct->evac_step = 0;
GetRoots(mark_root);
#if defined(RTS_USER_SIGNALS)
// mark the signal handlers (signals should be already blocked)
markSignalHandlers(mark_root);
#endif
// Mark the weak pointer list, and prepare to detect dead weak pointers.
markWeakPtrList();
initWeakForGC();
......@@ -702,7 +707,12 @@ GetRoots( evac_fn evac )
Capability *cap;
Task *task;
for (i = 0; i < n_capabilities; i++) {
// Each GC thread is responsible for following roots from the
// Capability of the same number. There will usually be the same
// or fewer Capabilities as GC threads, but just in case there
// are more, we mark every Capability whose number is the GC
// thread's index plus a multiple of the number of GC threads.
for (i = gct->thread_index; i < n_capabilities; i += n_gc_threads) {
cap = &capabilities[i];
evac((StgClosure **)(void *)&cap->run_queue_hd);
evac((StgClosure **)(void *)&cap->run_queue_tl);
......@@ -717,6 +727,9 @@ GetRoots( evac_fn evac )
evac((StgClosure **)(void *)&task->suspended_tso);
}
#if defined(THREADED_RTS)
markSparkQueue(evac,cap);
#endif
}
#if !defined(THREADED_RTS)
......@@ -724,17 +737,6 @@ GetRoots( evac_fn evac )
evac((StgClosure **)(void *)&blocked_queue_tl);
evac((StgClosure **)(void *)&sleeping_queue);
#endif
// evac((StgClosure **)&blackhole_queue);
#if defined(THREADED_RTS)
markSparkQueue(evac);
#endif
#if defined(RTS_USER_SIGNALS)
// mark the signal handlers (signals should be already blocked)
markSignalHandlers(evac);
#endif
}
/* -----------------------------------------------------------------------------
......@@ -973,6 +975,10 @@ gc_thread_work (void)
// GarbageCollect(), or this is a worker thread and the main
// thread bumped gc_running_threads before waking us up.
// Every thread evacuates some roots.
gct->evac_step = 0;
GetRoots(mark_root);
loop:
scavenge_loop();
// scavenge_loop() only exits when there's no work to do
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment