Refactoring and tidy up
[ghc-hetmet.git] / rts / sm / GCTDecl.h
1 /* -----------------------------------------------------------------------------
2  *
3  * (c) The GHC Team 1998-2009
4  *
5  * Documentation on the architecture of the Garbage Collector can be
6  * found in the online commentary:
7  * 
8  *   http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/GC
9  *
10  * ---------------------------------------------------------------------------*/
11
12 #ifndef SM_GCTDECL_H
13 #define SM_GCTDECL_H
14
15 #include "BeginPrivate.h"
16
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
22    variable.
23    -------------------------------------------------------------------------- */
24
25 #if defined(THREADED_RTS)
26
27 #define GLOBAL_REG_DECL(type,name,reg) register type name REG(reg);
28
29 #define SET_GCT(to) gct = (to)
30
31
32
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
38 //
39 // We ought to do the same on MacOS X, but __thread is not
40 // supported there yet (gcc 4.0.1).
41
42 extern __thread gc_thread* gct;
43 #define DECLARE_GCT __thread gc_thread* gct;
44
45
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.
49 //      
50 //      There are eight global (non-window) registers, but they're used for other purposes.
51 //      %g0     -- always zero
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
56
57 extern __thread gc_thread* gct;
58 #define DECLARE_GCT __thread gc_thread* gct;
59
60
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
63 // want to steal it
64
65 GLOBAL_REG_DECL(gc_thread*, gct, REG_Base)
66 #define DECLARE_GCT /* nothing */
67
68
69 #elif defined(REG_R1)
70
71 GLOBAL_REG_DECL(gc_thread*, gct, REG_R1)
72 #define DECLARE_GCT /* nothing */
73
74
75 #elif defined(__GNUC__)
76
77 extern __thread gc_thread* gct;
78 #define DECLARE_GCT __thread gc_thread* gct;
79
80 #else
81
82 #error Cannot find a way to declare the thread-local gct
83
84 #endif
85
86 #else  // not the threaded RTS
87
88 extern StgWord8 the_gc_thread[];
89
90 #define gct ((gc_thread*)&the_gc_thread)
91 #define SET_GCT(to) /*nothing*/
92 #define DECLARE_GCT /*nothing*/
93
94 #endif // THREADED_RTS
95
96 #include "EndPrivate.h"
97
98 #endif // SM_GCTDECL_H