diff options
Diffstat (limited to 'rts/sm/GC.c')
-rw-r--r-- | rts/sm/GC.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/rts/sm/GC.c b/rts/sm/GC.c index 3b65219927..928f4448d3 100644 --- a/rts/sm/GC.c +++ b/rts/sm/GC.c @@ -338,6 +338,13 @@ GarbageCollect (rtsBool force_major_gc, } } else { scavenge_capability_mut_lists(gct->cap); + for (n = 0; n < n_capabilities; n++) { + if (gc_threads[n]->idle) { + markCapability(mark_root, gct, &capabilities[n], + rtsTrue/*don't mark sparks*/); + scavenge_capability_mut_lists(&capabilities[n]); + } + } } // follow roots from the CAF list (used by GHCi) @@ -401,7 +408,11 @@ GarbageCollect (rtsBool force_major_gc, pruneSparkQueue(&capabilities[n]); } } else { - pruneSparkQueue(gct->cap); + for (n = 0; n < n_capabilities; n++) { + if (n == cap->no || gc_threads[n]->idle) { + pruneSparkQueue(&capabilities[n]); + } + } } #endif @@ -808,6 +819,7 @@ new_gc_thread (nat n, gc_thread *t) #endif t->thread_index = n; + t->idle = rtsFalse; t->free_blocks = NULL; t->gc_count = 0; @@ -1114,7 +1126,7 @@ waitForGcThreads (Capability *cap USED_IF_THREADS) while(retry) { for (i=0; i < n_threads; i++) { - if (i == me) continue; + if (i == me || gc_threads[i]->idle) continue; if (gc_threads[i]->wakeup != GC_THREAD_STANDING_BY) { prodCapability(&capabilities[i], cap->running_task); } @@ -1122,7 +1134,7 @@ waitForGcThreads (Capability *cap USED_IF_THREADS) for (j=0; j < 10; j++) { retry = rtsFalse; for (i=0; i < n_threads; i++) { - if (i == me) continue; + if (i == me || gc_threads[i]->idle) continue; write_barrier(); interruptCapability(&capabilities[i]); if (gc_threads[i]->wakeup != GC_THREAD_STANDING_BY) { @@ -1154,8 +1166,8 @@ wakeup_gc_threads (nat me USED_IF_THREADS) if (n_gc_threads == 1) return; for (i=0; i < n_gc_threads; i++) { - if (i == me) continue; - inc_running(); + if (i == me || gc_threads[i]->idle) continue; + inc_running(); debugTrace(DEBUG_gc, "waking up gc thread %d", i); if (gc_threads[i]->wakeup != GC_THREAD_STANDING_BY) barf("wakeup_gc_threads"); @@ -1178,7 +1190,7 @@ shutdown_gc_threads (nat me USED_IF_THREADS) if (n_gc_threads == 1) return; for (i=0; i < n_gc_threads; i++) { - if (i == me) continue; + if (i == me || gc_threads[i]->idle) continue; while (gc_threads[i]->wakeup != GC_THREAD_WAITING_TO_CONTINUE) { write_barrier(); } } #endif @@ -1192,8 +1204,8 @@ releaseGCThreads (Capability *cap USED_IF_THREADS) const nat me = cap->no; nat i; for (i=0; i < n_threads; i++) { - if (i == me) continue; - if (gc_threads[i]->wakeup != GC_THREAD_WAITING_TO_CONTINUE) + if (i == me || gc_threads[i]->idle) continue; + if (gc_threads[i]->wakeup != GC_THREAD_WAITING_TO_CONTINUE) barf("releaseGCThreads"); gc_threads[i]->wakeup = GC_THREAD_INACTIVE; |