diff options
author | Simon Marlow <marlowsd@gmail.com> | 2011-11-22 11:26:28 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2011-11-22 11:26:28 +0000 |
commit | d681f8700ad2c034d5b9dacf4e681b8e7279f6ee (patch) | |
tree | c808d7d5e623679e13b67d8e82d46ebbb0130005 /rts/sm | |
parent | a5762b71d1aaf9037d14fc706bb04976a231bf22 (diff) | |
parent | 6247b59e5d31de58ee51273916bc44ac2118240a (diff) | |
download | haskell-d681f8700ad2c034d5b9dacf4e681b8e7279f6ee.tar.gz |
merge
Diffstat (limited to 'rts/sm')
-rw-r--r-- | rts/sm/GC.c | 2 | ||||
-rw-r--r-- | rts/sm/GCTDecl.h | 15 |
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 |