Fix generational GC bug (#3348)
[ghc-hetmet.git] / rts / sm / GC.c
index cb5623a..cfe4c6b 100644 (file)
@@ -116,7 +116,10 @@ nat mutlist_MUTVARS,
 /* Thread-local data for each GC thread
  */
 gc_thread **gc_threads = NULL;
-// gc_thread *gct = NULL;  // this thread's gct TODO: make thread-local
+
+#if !defined(THREADED_RTS)
+StgWord8 the_gc_thread[sizeof(gc_thread) + 64 * sizeof(step_workspace)];
+#endif
 
 // Number of threads running in *this* GC.  Affects how many
 // step->todos[] lists we have to look in to find work.
@@ -212,6 +215,9 @@ GarbageCollect (rtsBool force_major_gc,
   // tell the STM to discard any cached closures it's hoping to re-use
   stmPreGCHook();
 
+  // lock the StablePtr table
+  stablePtrPreGC();
+
 #ifdef DEBUG
   mutlist_MUTVARS = 0;
   mutlist_MUTARRS = 0;
@@ -314,12 +320,12 @@ GarbageCollect (rtsBool force_major_gc,
   // this is the main thread
 #ifdef THREADED_RTS
   if (n_gc_threads == 1) {
-      gct = gc_threads[0];
+      SET_GCT(gc_threads[0]);
   } else {
-      gct = gc_threads[cap->no];
+      SET_GCT(gc_threads[cap->no]);
   }
 #else
-  gct = gc_threads[0];
+SET_GCT(gc_threads[0]);
 #endif
 
   /* -----------------------------------------------------------------------
@@ -791,6 +797,9 @@ GarbageCollect (rtsBool force_major_gc,
   slop = calcLiveBlocks() * BLOCK_SIZE_W - live;
   stat_endGC(allocated, live, copied, N, max_copied, avg_copied, slop);
 
+  // unlock the StablePtr table
+  stablePtrPostGC();
+
   // Guess which generation we'll collect *next* time
   initialise_N(force_major_gc);
 
@@ -803,7 +812,7 @@ GarbageCollect (rtsBool force_major_gc,
 
   RELEASE_SM_LOCK;
 
-  gct = saved_gct;
+  SET_GCT(saved_gct);
 }
 
 /* -----------------------------------------------------------------------------
@@ -857,15 +866,11 @@ initialise_N (rtsBool force_major_gc)
 #define GC_THREAD_RUNNING              2
 #define GC_THREAD_WAITING_TO_CONTINUE  3
 
-static gc_thread *
-alloc_gc_thread (int n)
+static void
+new_gc_thread (nat n, gc_thread *t)
 {
     nat s;
     step_workspace *ws;
-    gc_thread *t;
-
-    t = stgMallocBytes(sizeof(gc_thread) + total_steps * sizeof(step_workspace),
-                       "alloc_gc_thread");
 
 #ifdef THREADED_RTS
     t->id = 0;
@@ -891,7 +896,7 @@ alloc_gc_thread (int n)
         ws = &t->steps[s];
         ws->step = &all_steps[s];
         ASSERT(s == ws->step->abs_no);
-        ws->gct = t;
+        ws->my_gct = t;
         
         ws->todo_bd = NULL;
         ws->todo_q = newWSDeque(128);
@@ -904,8 +909,6 @@ alloc_gc_thread (int n)
         ws->scavd_list = NULL;
         ws->n_scavd_blocks = 0;
     }
-
-    return t;
 }
 
 
@@ -920,13 +923,16 @@ initGcThreads (void)
                                     "alloc_gc_threads");
 
        for (i = 0; i < RtsFlags.ParFlags.nNodes; i++) {
-           gc_threads[i] = alloc_gc_thread(i);
+            gc_threads[i] = 
+                stgMallocBytes(sizeof(gc_thread) + total_steps * sizeof(step_workspace),
+                               "alloc_gc_threads");
+
+            new_gc_thread(i, gc_threads[i]);
        }
 #else
-       gc_threads = stgMallocBytes (sizeof(gc_thread*), 
-                                    "alloc_gc_threads");
-
-       gc_threads[0] = alloc_gc_thread(0);
+        gc_threads = stgMallocBytes (sizeof(gc_thread*),"alloc_gc_threads");
+       gc_threads[0] = gct;
+        new_gc_thread(0,gc_threads[0]);
 #endif
     }
 }
@@ -1435,7 +1441,7 @@ init_gc_thread (gc_thread *t)
    -------------------------------------------------------------------------- */
 
 static void
-mark_root(void *user, StgClosure **root)
+mark_root(void *user USED_IF_THREADS, StgClosure **root)
 {
     // we stole a register for gct, but this function is called from
     // *outside* the GC where the register variable is not in effect,
@@ -1444,11 +1450,11 @@ mark_root(void *user, StgClosure **root)
     // incorrect.
     gc_thread *saved_gct;
     saved_gct = gct;
-    gct = user;
+    SET_GCT(user);
     
     evacuate(root);
     
-    gct = saved_gct;
+    SET_GCT(saved_gct);
 }
 
 /* -----------------------------------------------------------------------------