summaryrefslogtreecommitdiff
path: root/rts/sm
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2011-11-22 11:26:28 +0000
committerSimon Marlow <marlowsd@gmail.com>2011-11-22 11:26:28 +0000
commitd681f8700ad2c034d5b9dacf4e681b8e7279f6ee (patch)
treec808d7d5e623679e13b67d8e82d46ebbb0130005 /rts/sm
parenta5762b71d1aaf9037d14fc706bb04976a231bf22 (diff)
parent6247b59e5d31de58ee51273916bc44ac2118240a (diff)
downloadhaskell-d681f8700ad2c034d5b9dacf4e681b8e7279f6ee.tar.gz
merge
Diffstat (limited to 'rts/sm')
-rw-r--r--rts/sm/GC.c2
-rw-r--r--rts/sm/GCTDecl.h15
2 files changed, 14 insertions, 3 deletions
diff --git a/rts/sm/GC.c b/rts/sm/GC.c
index b97ff12464..7892280dca 100644
--- a/rts/sm/GC.c
+++ b/rts/sm/GC.c
@@ -1029,7 +1029,7 @@ gcWorkerThread (Capability *cap)
// necessary if we stole a callee-saves register for gct:
saved_gct = gct;
- gct = gc_threads[cap->no];
+ SET_GCT(gc_threads[cap->no]);
gct->id = osThreadId();
stat_gcWorkerThreadStart(gct);
diff --git a/rts/sm/GCTDecl.h b/rts/sm/GCTDecl.h
index 11795ca7fd..f9c8fcb137 100644
--- a/rts/sm/GCTDecl.h
+++ b/rts/sm/GCTDecl.h
@@ -26,7 +26,11 @@
#define GLOBAL_REG_DECL(type,name,reg) register type name REG(reg);
+#ifdef llvm_CC_FLAVOR
+#define SET_GCT(to) (pthread_setspecific(gctKey, to))
+#else
#define SET_GCT(to) gct = (to)
+#endif
@@ -36,12 +40,19 @@
// about 5% in GC performance, but of course that might change as gcc
// improves. -- SDM 2009/04/03
//
-// We ought to do the same on MacOS X, but __thread is not
-// supported there yet (gcc 4.0.1).
+// For MacOSX, we can use an llvm-based C compiler which will store the gct
+// in a thread local variable using pthreads.
extern __thread gc_thread* gct;
#define DECLARE_GCT __thread gc_thread* gct;
+#elif defined(llvm_CC_FLAVOR)
+// LLVM does not support the __thread extension and will generate
+// incorrect code for global register variables. If we are compiling
+// with a C compiler that uses an LLVM back end (clang or llvm-gcc) then we
+// use pthread_getspecific() to handle the thread local storage for gct.
+#define gct ((gc_thread *)(pthread_getspecific(gctKey)))
+#define DECLARE_GCT /* nothing */
#elif defined(sparc_HOST_ARCH)
// On SPARC we can't pin gct to a register. Names like %l1 are just offsets