X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2Fsm%2FGCThread.h;h=ab5aca72b775b8ab6e55aa0277542b4bbc2ca671;hb=91a804680cfc5cb3894d996b9c7fb28b50180cdb;hp=aacef82cbcd404f044ebbfaf62507fbc7c683402;hpb=4e3542263207ae49963811aeb84927027e7bb61d;p=ghc-hetmet.git diff --git a/rts/sm/GCThread.h b/rts/sm/GCThread.h index aacef82..ab5aca7 100644 --- a/rts/sm/GCThread.h +++ b/rts/sm/GCThread.h @@ -11,12 +11,13 @@ * * ---------------------------------------------------------------------------*/ -#ifndef GCTHREAD_H -#define GCTHREAD_H +#ifndef SM_GCTHREAD_H +#define SM_GCTHREAD_H -#include "OSThreads.h" #include "WSDeque.h" +BEGIN_RTS_PRIVATE + /* ----------------------------------------------------------------------------- General scheme @@ -75,7 +76,7 @@ typedef struct step_workspace_ { step * step; // the step for this workspace - struct gc_thread_ * gct; // the gc_thread that contains this workspace + struct gc_thread_ * my_gct; // the gc_thread that contains this workspace // where objects to be scavenged go bdescr * todo_bd; @@ -189,8 +190,6 @@ typedef struct gc_thread_ { extern nat n_gc_threads; -extern gc_thread **gc_threads; - /* ----------------------------------------------------------------------------- The gct variable is thread-local and points to the current thread's gc_thread structure. It is heavily accessed, so we try to put gct @@ -203,15 +202,44 @@ extern gc_thread **gc_threads; __thread version. -------------------------------------------------------------------------- */ +extern gc_thread **gc_threads; + +#if defined(THREADED_RTS) + #define GLOBAL_REG_DECL(type,name,reg) register type name REG(reg); -#if defined(sparc_HOST_ARCH) -// Don't use REG_base or R1 for gct on SPARC because they're getting clobbered -// by something else. Not sure what yet. -- BL 2009/01/03 +#define SET_GCT(to) gct = (to) + + + +#if (defined(i386_HOST_ARCH) && defined(linux_HOST_OS)) +// Using __thread is better than stealing a register on x86/Linux, because +// we have too few registers available. In my tests it was worth +// 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). extern __thread gc_thread* gct; #define DECLARE_GCT __thread gc_thread* gct; + +#elif defined(sparc_TARGET_ARCH) +// On SPARC we can't pin gct to a register. Names like %l1 are just offsets +// into the register window, which change on each function call. +// +// There are eight global (non-window) registers, but they're used for other purposes. +// %g0 -- always zero +// %g1 -- volatile over function calls, used by the linker +// %g2-%g3 -- used as scratch regs by the C compiler (caller saves) +// %g4 -- volatile over function calls, used by the linker +// %g5-%g7 -- reserved by the OS + +extern __thread gc_thread* gct; +#define DECLARE_GCT __thread gc_thread* gct; + + #elif defined(REG_Base) && !defined(i386_HOST_ARCH) // on i386, REG_Base is %ebx which is also used for PIC, so we don't // want to steal it @@ -219,11 +247,13 @@ extern __thread gc_thread* gct; GLOBAL_REG_DECL(gc_thread*, gct, REG_Base) #define DECLARE_GCT /* nothing */ + #elif defined(REG_R1) GLOBAL_REG_DECL(gc_thread*, gct, REG_R1) #define DECLARE_GCT /* nothing */ + #elif defined(__GNUC__) extern __thread gc_thread* gct; @@ -235,5 +265,17 @@ extern __thread gc_thread* gct; #endif -#endif // GCTHREAD_H +#else // not the threaded RTS + +extern StgWord8 the_gc_thread[]; + +#define gct ((gc_thread*)&the_gc_thread) +#define SET_GCT(to) /*nothing*/ +#define DECLARE_GCT /*nothing*/ + +#endif + +END_RTS_PRIVATE + +#endif // SM_GCTHREAD_H