start_gc_threads();
/* How many threads will be participating in this GC?
- * We don't try to parallelise minor GC.
+ * We don't try to parallelise minor GC, or mark/compact/sweep GC.
*/
#if defined(THREADED_RTS)
- if (n < (4*1024*1024 / BLOCK_SIZE)) {
+ if (n < (4*1024*1024 / BLOCK_SIZE) || oldest_gen->steps[0].mark) {
n_gc_threads = 1;
} else {
n_gc_threads = RtsFlags.ParFlags.gcThreads;
memInventory(traceClass(DEBUG_gc));
#endif
- // check stack sanity *before* GC (ToDo: check all threads)
+ // check stack sanity *before* GC
IF_DEBUG(sanity, checkFreeListSanity());
+ IF_DEBUG(sanity, checkMutableLists());
// Initialise all our gc_thread structures
for (t = 0; t < n_gc_threads; t++) {
/* Allocate a mark stack if we're doing a major collection.
*/
- if (major_gc) {
+ if (major_gc && oldest_gen->steps[0].mark) {
nat mark_stack_blocks;
mark_stack_blocks = stg_max(MARK_STACK_BLOCKS,
oldest_gen->steps[0].n_old_blocks / 100);
// follow all the roots that the application knows about.
gct->evac_step = 0;
- markSomeCapabilities(mark_root, gct, gct->thread_index, n_gc_threads);
+ markSomeCapabilities(mark_root, gct, gct->thread_index, n_gc_threads,
+ rtsTrue/*prune sparks*/);
#if defined(RTS_USER_SIGNALS)
// mark the signal handlers (signals should be already blocked)
// Update pointers from the Task list
update_task_list();
- // Update pointers from capabilities (probably just the spark queues)
- updateCapabilitiesPostGC();
-
// Now see which stable names are still alive.
gcStablePtrTable();
sweep(&oldest_gen->steps[0]);
}
- IF_DEBUG(sanity, checkGlobalTSOList(rtsFalse));
-
/* run through all the generations/steps and tidy up
*/
copied = 0;
// Every thread evacuates some roots.
gct->evac_step = 0;
- markSomeCapabilities(mark_root, gct, gct->thread_index, n_gc_threads);
+ markSomeCapabilities(mark_root, gct, gct->thread_index, n_gc_threads,
+ rtsTrue/*prune sparks*/);
scavenge_until_all_done();
}