comment updates
[ghc-hetmet.git] / rts / sm / GCThread.h
index 8d171ae..d4376f7 100644 (file)
@@ -95,13 +95,17 @@ typedef struct step_workspace_ {
     bdescr *     part_list;
     unsigned int n_part_blocks;      // count of above
 
-} step_workspace;
+    StgWord pad[5];
+
+} step_workspace ATTRIBUTE_ALIGNED(64);
+// align so that computing gct->steps[n] is a shift, not a multiply
+// fails if the size is <64, which is why we need the pad above
 
 /* ----------------------------------------------------------------------------
    GC thread object
 
    Every GC thread has one of these. It contains all the step specific
-   workspaces and other GC thread loacl information. At some later
+   workspaces and other GC thread local information. At some later
    point it maybe useful to move this other into the TLS store of the
    GC threads
    ------------------------------------------------------------------------- */
@@ -177,8 +181,41 @@ typedef struct gc_thread_ {
 extern nat n_gc_threads;
 
 extern gc_thread **gc_threads;
-register gc_thread *gct __asm__("%rbx");
-// extern gc_thread *gct;  // this thread's gct TODO: make thread-local
+
+/* -----------------------------------------------------------------------------
+   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
+   into a global register variable if possible; if we don't have a
+   register then use gcc's __thread extension to create a thread-local
+   variable.
+
+   Even on x86 where registers are scarce, it is worthwhile using a
+   register variable here: I measured about a 2-5% slowdown with the
+   __thread version.
+   -------------------------------------------------------------------------- */
+
+#define GLOBAL_REG_DECL(type,name,reg) register type name REG(reg);
+
+#if defined(REG_Base)
+
+GLOBAL_REG_DECL(gc_thread*, gct, REG_Base)
+#define DECLARE_GCT /* nothing */
+
+#elif defined(REG_R1)
+
+GLOBAL_REG_DECL(gc_thread*, gct, REG_R1)
+#define DECLARE_GCT /* nothing */
+
+#elif defined(__GNUC__)
+
+extern __thread gc_thread* gct;
+#define DECLARE_GCT __thread gc_thread* gct;
+
+#else
+
+#error Cannot find a way to declare the thread-local gct
+
+#endif
 
 #endif // GCTHREAD_H