small debug output improvements
[ghc-hetmet.git] / rts / sm / GCUtils.c
index 6341067..98e6f8a 100644 (file)
@@ -33,6 +33,14 @@ allocBlock_sync(void)
     return bd;
 }
 
+void
+freeChain_sync(bdescr *bd)
+{
+    ACQUIRE_SPIN_LOCK(&gc_alloc_block_sync);
+    freeChain(bd);
+    RELEASE_SPIN_LOCK(&gc_alloc_block_sync);
+}
+
 /* -----------------------------------------------------------------------------
    Workspace utilities
    -------------------------------------------------------------------------- */
@@ -57,6 +65,9 @@ grab_todo_block (step_workspace *ws)
     ACQUIRE_SPIN_LOCK(&stp->sync_todo);
     if (stp->todos) {
        bd = stp->todos;
+        if (stp->todos == stp->todos_last) {
+            stp->todos_last = NULL;
+        }
        stp->todos = bd->link;
         stp->n_todos--;
        bd->link = NULL;
@@ -70,10 +81,15 @@ push_todo_block (bdescr *bd, step *stp)
 {
     ASSERT(bd->link == NULL);
     ACQUIRE_SPIN_LOCK(&stp->sync_todo);
-    bd->link = stp->todos;
-    stp->todos = bd;
+    if (stp->todos_last == NULL) {
+        stp->todos_last = bd;
+        stp->todos = bd;
+    } else {
+        stp->todos_last->link = bd;
+        stp->todos_last = bd;
+    }
     stp->n_todos++;
-    trace(TRACE_gc, "step %d, n_todos: %d", stp->abs_no, stp->n_todos);
+    trace(TRACE_gc|DEBUG_gc, "step %d, n_todos: %d", stp->abs_no, stp->n_todos);
     RELEASE_SPIN_LOCK(&stp->sync_todo);
 }
 
@@ -84,7 +100,7 @@ push_scan_block (bdescr *bd, step_workspace *ws)
     ASSERT(bd->link == NULL);
 
     // update stats: this is a block that has been copied & scavenged
-    copied += bd->free - bd->start;
+    gct->copied += bd->free - bd->start;
 
     // put the scan block on the ws->scavd_list.
     bd->link = ws->scavd_list;
@@ -109,11 +125,21 @@ gc_alloc_todo_block (step_workspace *ws)
     // push out the block out if it is already the scan block.
     if (ws->todo_bd != NULL && ws->scan_bd != ws->todo_bd) {
        ASSERT(ws->todo_bd->link == NULL);
-       if (ws->buffer_todo_bd != NULL) {
+        if (ws->buffer_todo_bd == NULL) {
+            // If the global todo list is empty, push this block
+            // out immediately rather than caching it in
+            // buffer_todo_bd, because there might be other threads
+            // waiting for work.
+            if (ws->stp->todos == NULL) {
+                push_todo_block(ws->todo_bd, ws->stp);
+            } else {
+                ws->buffer_todo_bd = ws->todo_bd;
+            }
+        } else {            
            ASSERT(ws->buffer_todo_bd->link == NULL);
            push_todo_block(ws->buffer_todo_bd, ws->stp);
-       }
-       ws->buffer_todo_bd = ws->todo_bd;
+            ws->buffer_todo_bd = ws->todo_bd;
+        }
        ws->todo_bd = NULL;
     }