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.c28
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;