On x86, use thread-local storage instead of stealing a reg for gct
[ghc-hetmet.git] / rts / sm / GCThread.h
index aacef82..5646edd 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,12 +201,23 @@ 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);
 
-#if defined(sparc_HOST_ARCH)
+#define SET_GCT(to) gct = (to)
+
+#if defined(sparc_HOST_ARCH) || defined(i386_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
 
+// Using __thread is better than stealing a register on x86, because
+// we have too few registers available.  In my tests it was worth
+// about 5% in GC performance, but of course that might change as gcc
+// improves. -- SDM 2009/04/03
+
 extern __thread gc_thread* gct;
 #define DECLARE_GCT __thread gc_thread* gct;
 
@@ -235,5 +244,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