in the non-threaded RTS, use a static gc_thread structure
authorSimon Marlow <marlowsd@gmail.com>
Fri, 3 Apr 2009 12:14:43 +0000 (12:14 +0000)
committerSimon Marlow <marlowsd@gmail.com>
Fri, 3 Apr 2009 12:14:43 +0000 (12:14 +0000)
rts/sm/GC.c
rts/sm/GCThread.h

index cb5623a..e0c8b05 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.
@@ -314,12 +317,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
 
   /* -----------------------------------------------------------------------
@@ -803,7 +806,7 @@ GarbageCollect (rtsBool force_major_gc,
 
   RELEASE_SM_LOCK;
 
-  gct = saved_gct;
+  SET_GCT(saved_gct);
 }
 
 /* -----------------------------------------------------------------------------
@@ -857,15 +860,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 +890,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 +903,6 @@ alloc_gc_thread (int n)
         ws->scavd_list = NULL;
         ws->n_scavd_blocks = 0;
     }
-
-    return t;
 }
 
 
@@ -920,13 +917,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 +1435,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 +1444,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);
 }
 
 /* -----------------------------------------------------------------------------
index aacef82..c563d95 100644 (file)
@@ -75,7 +75,7 @@
 
 typedef struct step_workspace_ {
     step * step;               // the step for this workspace 
-    struct gc_thread_ * gct;    // the gc_thread that contains this workspace
+    struct gc_thread_ * my_gct; // the gc_thread that contains this workspace
 
     // where objects to be scavenged go
     bdescr *     todo_bd;
@@ -189,8 +189,6 @@ typedef struct gc_thread_ {
 
 extern nat n_gc_threads;
 
-extern gc_thread **gc_threads;
-
 /* -----------------------------------------------------------------------------
    The gct variable is thread-local and points to the current thread's
    gc_thread structure.  It is heavily accessed, so we try to put gct
@@ -203,8 +201,14 @@ extern gc_thread **gc_threads;
    __thread version.
    -------------------------------------------------------------------------- */
 
+extern gc_thread **gc_threads;
+
+#if defined(THREADED_RTS)
+
 #define GLOBAL_REG_DECL(type,name,reg) register type name REG(reg);
 
+#define SET_GCT(to) gct = (to)
+
 #if defined(sparc_HOST_ARCH)
 // Don't use REG_base or R1 for gct on SPARC because they're getting clobbered 
 //     by something else. Not sure what yet. -- BL 2009/01/03
@@ -235,5 +239,15 @@ extern __thread gc_thread* gct;
 
 #endif
 
+#else  // not the threaded RTS
+
+extern StgWord8 the_gc_thread[];
+
+#define gct ((gc_thread*)&the_gc_thread)
+#define SET_GCT(to) /*nothing*/
+#define DECLARE_GCT /*nothing*/
+
+#endif
+
 #endif // GCTHREAD_H