X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2Fsm%2FGCUtils.c;h=70c53cb8bfa0541a163990ee16e08063d8b5f70f;hb=6cf8982ac30be6836a0cdd8be5a6ac1a1a144213;hp=86d2282980d07cd44f53b9e9659c547457f09140;hpb=8b18faef8aeaf40150c208272a2fc117611e8ae8;p=ghc-hetmet.git diff --git a/rts/sm/GCUtils.c b/rts/sm/GCUtils.c index 86d2282..70c53cb 100644 --- a/rts/sm/GCUtils.c +++ b/rts/sm/GCUtils.c @@ -11,8 +11,9 @@ * * ---------------------------------------------------------------------------*/ +#include "PosixSource.h" #include "Rts.h" -#include "RtsFlags.h" + #include "Storage.h" #include "GC.h" #include "GCThread.h" @@ -37,6 +38,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 @@ -101,6 +112,7 @@ grab_local_todo_block (step_workspace *ws) return NULL; } +#if defined(THREADED_RTS) bdescr * steal_todo_block (nat s) { @@ -117,6 +129,7 @@ steal_todo_block (nat s) } return NULL; } +#endif void push_scanned_block (bdescr *bd, step_workspace *ws) @@ -126,12 +139,12 @@ push_scanned_block (bdescr *bd, step_workspace *ws) ASSERT(bd->step == ws->step); 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)); } @@ -140,7 +153,7 @@ 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)); } @@ -149,8 +162,13 @@ push_scanned_block (bdescr *bd, step_workspace *ws) StgPtr todo_block_full (nat size, step_workspace *ws) { + StgPtr p; bdescr *bd; + // todo_free has been pre-incremented by Evac.c:alloc_for_copy(). We + // are expected to leave it bumped when we've finished here. + ws->todo_free -= size; + bd = ws->todo_bd; ASSERT(bd != NULL); @@ -163,11 +181,13 @@ 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); - return ws->todo_free; + p = ws->todo_free; + ws->todo_free += size; + return p; } } @@ -212,7 +232,9 @@ todo_block_full (nat size, step_workspace *ws) alloc_todo_block(ws, size); - return ws->todo_free; + p = ws->todo_free; + ws->todo_free += size; + return p; } StgPtr @@ -221,12 +243,12 @@ alloc_todo_block (step_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 { @@ -241,7 +263,12 @@ alloc_todo_block (step_workspace *ws, nat size) // // bd = hd; - bd = allocBlock_sync(); + if (size > BLOCK_SIZE_W) { + bd = allocGroup_sync((lnat)BLOCK_ROUND_UP(size*sizeof(W_)) + / BLOCK_SIZE); + } else { + bd = allocBlock_sync(); + } bd->step = ws->step; bd->gen_no = ws->step->gen_no; bd->flags = BF_EVACUATED; @@ -252,7 +279,7 @@ 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",