X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2Fsm%2FGCUtils.c;h=8b63674c77932ad6970cfa82a70542444a84ff66;hb=bef3da1e26639303fccbf26c312d2833eedb486e;hp=6c6f10e01f2b6fdc51261cf47dbdbe75c487b273;hpb=a2a67cd520b9841114d69a87a423dabcb3b4368e;p=ghc-hetmet.git diff --git a/rts/sm/GCUtils.c b/rts/sm/GCUtils.c index 6c6f10e..8b63674 100644 --- a/rts/sm/GCUtils.c +++ b/rts/sm/GCUtils.c @@ -14,6 +14,7 @@ #include "PosixSource.h" #include "Rts.h" +#include "BlockAlloc.h" #include "Storage.h" #include "GC.h" #include "GCThread.h" @@ -38,6 +39,16 @@ allocBlock_sync(void) return bd; } +static bdescr * +allocGroup_sync(nat n) +{ + bdescr *bd; + ACQUIRE_SPIN_LOCK(&gc_alloc_block_sync); + bd = allocGroup(n); + RELEASE_SPIN_LOCK(&gc_alloc_block_sync); + return bd; +} + #if 0 static void @@ -76,12 +87,12 @@ freeChain_sync(bdescr *bd) -------------------------------------------------------------------------- */ bdescr * -grab_local_todo_block (step_workspace *ws) +grab_local_todo_block (gen_workspace *ws) { bdescr *bd; - step *stp; + generation *gen; - stp = ws->step; + gen = ws->gen; bd = ws->todo_overflow; if (bd != NULL) @@ -104,7 +115,7 @@ grab_local_todo_block (step_workspace *ws) #if defined(THREADED_RTS) bdescr * -steal_todo_block (nat s) +steal_todo_block (nat g) { nat n; bdescr *bd; @@ -112,7 +123,7 @@ steal_todo_block (nat s) // look for work to steal for (n = 0; n < n_gc_threads; n++) { if (n == gct->thread_index) continue; - bd = stealWSDeque(gc_threads[n]->steps[s].todo_q); + bd = stealWSDeque(gc_threads[n]->gens[g].todo_q); if (bd) { return bd; } @@ -122,19 +133,19 @@ steal_todo_block (nat s) #endif void -push_scanned_block (bdescr *bd, step_workspace *ws) +push_scanned_block (bdescr *bd, gen_workspace *ws) { ASSERT(bd != NULL); ASSERT(bd->link == NULL); - ASSERT(bd->step == ws->step); + ASSERT(bd->gen == ws->gen); ASSERT(bd->u.scan == bd->free); - if (bd->start + BLOCK_SIZE_W - bd->free > WORK_UNIT_WORDS) + if (bd->start + bd->blocks * BLOCK_SIZE_W - bd->free > WORK_UNIT_WORDS) { // a partially full block: put it on the part_list list. bd->link = ws->part_list; ws->part_list = bd; - ws->n_part_blocks++; + ws->n_part_blocks += bd->blocks; IF_DEBUG(sanity, ASSERT(countBlocks(ws->part_list) == ws->n_part_blocks)); } @@ -143,14 +154,14 @@ push_scanned_block (bdescr *bd, step_workspace *ws) // put the scan block on the ws->scavd_list. bd->link = ws->scavd_list; ws->scavd_list = bd; - ws->n_scavd_blocks ++; + ws->n_scavd_blocks += bd->blocks; IF_DEBUG(sanity, ASSERT(countBlocks(ws->scavd_list) == ws->n_scavd_blocks)); } } StgPtr -todo_block_full (nat size, step_workspace *ws) +todo_block_full (nat size, gen_workspace *ws) { StgPtr p; bdescr *bd; @@ -163,7 +174,7 @@ todo_block_full (nat size, step_workspace *ws) ASSERT(bd != NULL); ASSERT(bd->link == NULL); - ASSERT(bd->step == ws->step); + ASSERT(bd->gen == ws->gen); // If the global list is not empty, or there's not much work in // this block to push, and there's enough room in @@ -171,8 +182,8 @@ todo_block_full (nat size, step_workspace *ws) // the limit. if (!looksEmptyWSDeque(ws->todo_q) || (ws->todo_free - bd->u.scan < WORK_UNIT_WORDS / 2)) { - if (ws->todo_free + size < bd->start + BLOCK_SIZE_W) { - ws->todo_lim = stg_min(bd->start + BLOCK_SIZE_W, + if (ws->todo_free + size < bd->start + bd->blocks * BLOCK_SIZE_W) { + ws->todo_lim = stg_min(bd->start + bd->blocks * BLOCK_SIZE_W, ws->todo_lim + stg_max(WORK_UNIT_WORDS,size)); debugTrace(DEBUG_gc, "increasing limit for %p to %p", bd->start, ws->todo_lim); p = ws->todo_free; @@ -202,11 +213,11 @@ todo_block_full (nat size, step_workspace *ws) // Otherwise, push this block out to the global list. else { - step *stp; - stp = ws->step; + generation *gen; + gen = ws->gen; debugTrace(DEBUG_gc, "push todo block %p (%ld words), step %d, todo_q: %ld", bd->start, (unsigned long)(bd->free - bd->u.scan), - stp->abs_no, dequeElements(ws->todo_q)); + gen->no, dequeElements(ws->todo_q)); if (!pushWSDeque(ws->todo_q, bd)) { bd->link = ws->todo_overflow; @@ -228,17 +239,17 @@ todo_block_full (nat size, step_workspace *ws) } StgPtr -alloc_todo_block (step_workspace *ws, nat size) +alloc_todo_block (gen_workspace *ws, nat size) { bdescr *bd/*, *hd, *tl */; // Grab a part block if we have one, and it has enough room - if (ws->part_list != NULL && - ws->part_list->start + BLOCK_SIZE_W - ws->part_list->free > (int)size) + bd = ws->part_list; + if (bd != NULL && + bd->start + bd->blocks * BLOCK_SIZE_W - bd->free > (int)size) { - bd = ws->part_list; ws->part_list = bd->link; - ws->n_part_blocks--; + ws->n_part_blocks -= bd->blocks; } else { @@ -253,9 +264,13 @@ alloc_todo_block (step_workspace *ws, nat size) // // bd = hd; - bd = allocBlock_sync(); - bd->step = ws->step; - bd->gen_no = ws->step->gen_no; + if (size > BLOCK_SIZE_W) { + bd = allocGroup_sync((lnat)BLOCK_ROUND_UP(size*sizeof(W_)) + / BLOCK_SIZE); + } else { + bd = allocBlock_sync(); + } + initBdescr(bd, ws->gen, ws->gen->to); bd->flags = BF_EVACUATED; bd->u.scan = bd->free = bd->start; } @@ -264,11 +279,11 @@ alloc_todo_block (step_workspace *ws, nat size) ws->todo_bd = bd; ws->todo_free = bd->free; - ws->todo_lim = stg_min(bd->start + BLOCK_SIZE_W, + ws->todo_lim = stg_min(bd->start + bd->blocks * BLOCK_SIZE_W, bd->free + stg_max(WORK_UNIT_WORDS,size)); - debugTrace(DEBUG_gc, "alloc new todo block %p for step %d", - bd->free, ws->step->abs_no); + debugTrace(DEBUG_gc, "alloc new todo block %p for gen %d", + bd->free, ws->gen->no); return ws->todo_free; } @@ -279,14 +294,13 @@ alloc_todo_block (step_workspace *ws, nat size) #if DEBUG void -printMutableList(generation *gen) +printMutableList(bdescr *bd) { - bdescr *bd; StgPtr p; - debugBelch("mutable list %p: ", gen->mut_list); + debugBelch("mutable list %p: ", bd); - for (bd = gen->mut_list; bd != NULL; bd = bd->link) { + for (; bd != NULL; bd = bd->link) { for (p = bd->start; p < bd->free; p++) { debugBelch("%p (%s), ", (void *)*p, info_type((StgClosure *)*p)); }