summaryrefslogtreecommitdiff
path: root/rts/sm/GCUtils.c
diff options
context:
space:
mode:
Diffstat (limited to 'rts/sm/GCUtils.c')
-rw-r--r--rts/sm/GCUtils.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/rts/sm/GCUtils.c b/rts/sm/GCUtils.c
index d58fdc48ae..ea7d83ab8f 100644
--- a/rts/sm/GCUtils.c
+++ b/rts/sm/GCUtils.c
@@ -30,6 +30,8 @@
SpinLock gc_alloc_block_sync;
#endif
+static void push_todo_block(bdescr *bd, gen_workspace *ws);
+
bdescr* allocGroup_sync(uint32_t n)
{
bdescr *bd;
@@ -127,7 +129,8 @@ steal_todo_block (uint32_t g)
// look for work to steal
for (n = 0; n < n_gc_threads; n++) {
if (n == gct->thread_index) continue;
- bd = stealWSDeque(gc_threads[n]->gens[g].todo_q);
+ q = gc_threads[n]->gens[g].todo_q;
+ bd = stealWSDeque(q);
if (bd) {
return bd;
}
@@ -168,6 +171,26 @@ push_scanned_block (bdescr *bd, gen_workspace *ws)
}
}
+void
+push_todo_block(bdescr *bd, gen_workspace *ws)
+{
+ debugTrace(DEBUG_gc, "push todo block %p (%ld words), step %d, todo_q: %ld",
+ bd->start, (unsigned long)(bd->free - bd->u.scan),
+ ws->gen->no, dequeElements(ws->todo_q));
+
+ ASSERT(bd->link == NULL);
+
+ if(!pushWSDeque(ws->todo_q, bd)) {
+ bd->link = ws->todo_overflow;
+ ws->todo_overflow = bd;
+ ws->n_todo_overflow++;
+ }
+
+#if defined(THREADED_RTS)
+ notifyTodoBlock();
+#endif
+}
+
/* Note [big objects]
We can get an ordinary object (CONSTR, FUN, THUNK etc.) that is
@@ -277,17 +300,7 @@ todo_block_full (uint32_t size, gen_workspace *ws)
// Otherwise, push this block out to the global list.
else
{
- DEBUG_ONLY( generation *gen );
- DEBUG_ONLY( 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),
- gen->no, dequeElements(ws->todo_q));
-
- if (!pushWSDeque(ws->todo_q, bd)) {
- bd->link = ws->todo_overflow;
- ws->todo_overflow = bd;
- ws->n_todo_overflow++;
- }
+ push_todo_block(bd, ws);
}
}