1 /* -----------------------------------------------------------------------------
3 * (c) The GHC Team 1998-2009
5 * Documentation on the architecture of the Garbage Collector can be
6 * found in the online commentary:
8 * http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/GC
10 * ---------------------------------------------------------------------------*/
15 #include "BeginPrivate.h"
17 /* -----------------------------------------------------------------------------
18 The gct variable is thread-local and points to the current thread's
19 gc_thread structure. It is heavily accessed, so we try to put gct
20 into a global register variable if possible; if we don't have a
21 register then use gcc's __thread extension to create a thread-local
23 -------------------------------------------------------------------------- */
25 #if defined(THREADED_RTS)
27 #define GLOBAL_REG_DECL(type,name,reg) register type name REG(reg);
29 #define SET_GCT(to) gct = (to)
33 #if (defined(i386_HOST_ARCH) && defined(linux_HOST_OS))
34 // Using __thread is better than stealing a register on x86/Linux, because
35 // we have too few registers available. In my tests it was worth
36 // about 5% in GC performance, but of course that might change as gcc
37 // improves. -- SDM 2009/04/03
39 // We ought to do the same on MacOS X, but __thread is not
40 // supported there yet (gcc 4.0.1).
42 extern __thread gc_thread* gct;
43 #define DECLARE_GCT __thread gc_thread* gct;
46 #elif defined(sparc_HOST_ARCH)
47 // On SPARC we can't pin gct to a register. Names like %l1 are just offsets
48 // into the register window, which change on each function call.
50 // There are eight global (non-window) registers, but they're used for other purposes.
52 // %g1 -- volatile over function calls, used by the linker
53 // %g2-%g3 -- used as scratch regs by the C compiler (caller saves)
54 // %g4 -- volatile over function calls, used by the linker
55 // %g5-%g7 -- reserved by the OS
57 extern __thread gc_thread* gct;
58 #define DECLARE_GCT __thread gc_thread* gct;
61 #elif defined(REG_Base) && !defined(i386_HOST_ARCH)
62 // on i386, REG_Base is %ebx which is also used for PIC, so we don't
65 GLOBAL_REG_DECL(gc_thread*, gct, REG_Base)
66 #define DECLARE_GCT /* nothing */
71 GLOBAL_REG_DECL(gc_thread*, gct, REG_R1)
72 #define DECLARE_GCT /* nothing */
75 #elif defined(__GNUC__)
77 extern __thread gc_thread* gct;
78 #define DECLARE_GCT __thread gc_thread* gct;
82 #error Cannot find a way to declare the thread-local gct
86 #else // not the threaded RTS
88 extern StgWord8 the_gc_thread[];
90 #define gct ((gc_thread*)&the_gc_thread)
91 #define SET_GCT(to) /*nothing*/
92 #define DECLARE_GCT /*nothing*/
94 #endif // THREADED_RTS
96 #include "EndPrivate.h"
98 #endif // SM_GCTDECL_H