summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2009-04-03 12:14:43 +0000
committerSimon Marlow <marlowsd@gmail.com>2009-04-03 12:14:43 +0000
commited45b268cba82ed698853b4a1c3d35e904ec020d (patch)
tree383063927d974d3f5de3ee23127c0b1de10a9031
parentc36ca010c5f7e019c9dd4d122be5c22905777e38 (diff)
downloadhaskell-ed45b268cba82ed698853b4a1c3d35e904ec020d.tar.gz
in the non-threaded RTS, use a static gc_thread structure
-rw-r--r--rts/sm/GC.c44
-rw-r--r--rts/sm/GCThread.h20
2 files changed, 39 insertions, 25 deletions
diff --git a/rts/sm/GC.c b/rts/sm/GC.c
index cb5623ab86..e0c8b05436 100644
--- a/rts/sm/GC.c
+++ b/rts/sm/GC.c
@@ -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);
}
/* -----------------------------------------------------------------------------
diff --git a/rts/sm/GCThread.h b/rts/sm/GCThread.h
index aacef82cbc..c563d95efd 100644
--- a/rts/sm/GCThread.h
+++ b/rts/sm/GCThread.h
@@ -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