summaryrefslogtreecommitdiff
path: root/rts/sm/GC.c
diff options
context:
space:
mode:
Diffstat (limited to 'rts/sm/GC.c')
-rw-r--r--rts/sm/GC.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/rts/sm/GC.c b/rts/sm/GC.c
index 847f85667c..af35150072 100644
--- a/rts/sm/GC.c
+++ b/rts/sm/GC.c
@@ -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