X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2Fsm%2FGC.c;h=622547821cab336e12f063a7c4a49d4d195bbf45;hb=01ccdeea34b4853750326126f3bff9b2bdfa9a32;hp=85e63354be51b9f29de62b639f413de5bd52859b;hpb=77798610bc585a1eea3b6695c4a3fee1ccba70ba;p=ghc-hetmet.git diff --git a/rts/sm/GC.c b/rts/sm/GC.c index 85e6335..6225478 100644 --- a/rts/sm/GC.c +++ b/rts/sm/GC.c @@ -39,7 +39,6 @@ #include "Trace.h" #include "RetainerProfile.h" #include "RaiseAsync.h" -#include "Sparks.h" #include "Papi.h" #include "GC.h" @@ -377,6 +376,9 @@ GarbageCollect ( rtsBool force_major_gc ) // 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(); @@ -408,9 +410,7 @@ GarbageCollect ( rtsBool force_major_gc ) } } - // For each workspace, in each thread: - // * clear the BF_EVACUATED flag from each copied block - // * move the copied blocks to the step + // For each workspace, in each thread, move the copied blocks to the step { gc_thread *thr; step_workspace *ws; @@ -446,6 +446,23 @@ GarbageCollect ( rtsBool force_major_gc ) ws->step->blocks = ws->scavd_list; } ws->step->n_blocks += ws->n_scavd_blocks; + } + } + + // Add all the partial blocks *after* we've added all the full + // blocks. This is so that we can grab the partial blocks back + // again and try to fill them up in the next GC. + for (t = 0; t < n_gc_threads; t++) { + thr = gc_threads[t]; + + // not step 0 + if (RtsFlags.GcFlags.generations == 1) { + s = 0; + } else { + s = 1; + } + for (; s < total_steps; s++) { + ws = &thr->steps[s]; prev = NULL; for (bd = ws->part_list; bd != NULL; bd = next) { @@ -677,6 +694,7 @@ GarbageCollect ( rtsBool force_major_gc ) // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); + performPendingThrowTos(exception_threads); ACQUIRE_SM_LOCK; // Update the stable pointer hash table. @@ -891,7 +909,7 @@ loop: gct->thread_index, r); while (gc_running_threads != 0) { - usleep(1); + // usleep(1); if (any_work()) { inc_running(); goto loop; @@ -1063,14 +1081,19 @@ init_collected_gen (nat g, nat n_threads) for (s = 0; s < generations[g].n_steps; s++) { + stp = &generations[g].steps[s]; + ASSERT(stp->gen_no == g); + + // we'll construct a new list of threads in this step + // during GC, throw away the current list. + stp->old_threads = stp->threads; + stp->threads = END_TSO_QUEUE; + // generation 0, step 0 doesn't need to-space if (g == 0 && s == 0 && RtsFlags.GcFlags.generations > 1) { continue; } - stp = &generations[g].steps[s]; - ASSERT(stp->gen_no == g); - // deprecate the existing blocks stp->old_blocks = stp->blocks; stp->n_old_blocks = stp->n_blocks; @@ -1181,11 +1204,12 @@ init_uncollected_gen (nat g, nat threads) stp->n_scavenged_large_blocks = 0; } - for (t = 0; t < threads; t++) { - for (s = 0; s < generations[g].n_steps; s++) { + for (s = 0; s < generations[g].n_steps; s++) { + stp = &generations[g].steps[s]; + + for (t = 0; t < threads; t++) { ws = &gc_threads[t]->steps[g * RtsFlags.GcFlags.steps + s]; - stp = ws->step; ws->buffer_todo_bd = NULL; ws->todo_large_objects = NULL; @@ -1216,8 +1240,26 @@ init_uncollected_gen (nat g, nat threads) alloc_todo_block(ws,0); } } + + // deal out any more partial blocks to the threads' part_lists + t = 0; + while (stp->blocks && isPartiallyFull(stp->blocks)) + { + bd = stp->blocks; + stp->blocks = bd->link; + ws = &gc_threads[t]->steps[g * RtsFlags.GcFlags.steps + s]; + bd->link = ws->part_list; + ws->part_list = bd; + ws->n_part_blocks += 1; + bd->u.scan = bd->free; + stp->n_blocks -= 1; + stp->n_words -= bd->free - bd->start; + t++; + if (t == n_gc_threads) t = 0; + } } + // Move the private mutable lists from each capability onto the // main mutable list for the generation. for (i = 0; i < n_capabilities; i++) {