summaryrefslogtreecommitdiff
path: root/rts/sm/GCTDecl.h
diff options
context:
space:
mode:
authorDavid M Peixotto <dmp@rice.edu>2011-06-28 15:31:42 -0500
committerDavid M Peixotto <dmp@rice.edu>2011-10-07 16:48:34 -0500
commitdba7254566b121408e7167200d0223a531b66e8b (patch)
tree0a3bfcb739b35123822cb644db93081b46c54fca /rts/sm/GCTDecl.h
parent29a97fded4010bd01aa0a17945c84258e285d421 (diff)
downloadhaskell-dba7254566b121408e7167200d0223a531b66e8b.tar.gz
Enable pthread_getspecific() tls for LLVM compiler
LLVM does not support the __thread attribute for thread local storage and may generate incorrect code for global register variables. We want to allow building the runtime with LLVM-based compilers such as llvm-gcc and clang, particularly for MacOS. This patch changes the gct variable used by the garbage collector to use pthread_getspecific() for thread local storage when an llvm based compiler is used to build the runtime.
Diffstat (limited to 'rts/sm/GCTDecl.h')
-rw-r--r--rts/sm/GCTDecl.h15
1 files changed, 13 insertions, 2 deletions
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