treat the global work list as a queue rather than a stack
authorSimon Marlow <simonmarhaskell@gmail.com>
Wed, 16 Apr 2008 21:51:09 +0000 (21:51 +0000)
committerSimon Marlow <simonmarhaskell@gmail.com>
Wed, 16 Apr 2008 21:51:09 +0000 (21:51 +0000)
includes/Storage.h
rts/sm/GC.c
rts/sm/GCUtils.c

index c51f51b..32d4e9b 100644 (file)
@@ -88,6 +88,7 @@ typedef struct step_ {
     unsigned int n_old_blocks;         // number of blocks in from-space
     
     bdescr *     todos;                        // blocks waiting to be scavenged
+    bdescr *     todos_last;
     unsigned int n_todos;               // count of above
 
     bdescr *     scavenged_large_objects;  // live large objs after GC (d-link)
index 5b16694..934c91f 100644 (file)
@@ -1197,6 +1197,7 @@ init_collected_gen (nat g, nat n_threads)
 
        // we don't have any to-be-scavenged blocks yet
        stp->todos = NULL;
+        stp->todos_last = NULL;
        stp->n_todos = 0;
 
        // initialise the large object queues.
index 636f23d..b400744 100644 (file)
@@ -65,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;
@@ -78,8 +81,13 @@ 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);
     RELEASE_SPIN_LOCK(&stp->sync_todo);