X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fincludes%2FRegs.h;h=b6e29217eb19b2c554cfe2d7d5482f01443ac414;hb=7f24ae51ed36c5c0308a2d0de23e243f32a0043c;hp=7333f2db84d1081196f8380e37f7ee7aa9397b68;hpb=03a9ff01812afc81eb5236fd3063cbec44cf469e;p=ghc-hetmet.git diff --git a/ghc/includes/Regs.h b/ghc/includes/Regs.h index 7333f2d..b6e2921 100644 --- a/ghc/includes/Regs.h +++ b/ghc/includes/Regs.h @@ -24,15 +24,18 @@ #include "gmp.h" // Needs MP_INT definition -/* - * This is the table that holds shadow-locations for all the STG - * registers. The shadow locations are used when: - * - * 1) the particular register isn't mapped to a real machine - * register, probably because there's a shortage of real registers. - * 2) caller-saves registers are saved across a CCall +/* + * Spark pools: used to store pending sparks + * (THREADED_RTS & PARALLEL_HASKELL only) + * This is a circular buffer. Invariants: + * - base <= hd < lim + * - base <= tl < lim + * - if hd==tl, then the pool is empty. + * - if hd == tl+1, then the pool is full. + * Adding to the pool is done by assigning to *tl++ (wrapping round as + * necessary). When adding to a full pool, we have the option of + * throwing away either the oldest (hd++) or the most recent (tl--) entry. */ - typedef struct StgSparkPool_ { StgClosure **base; StgClosure **lim; @@ -40,6 +43,12 @@ typedef struct StgSparkPool_ { StgClosure **tl; } StgSparkPool; +#define ASSERT_SPARK_POOL_INVARIANTS(p) \ + ASSERT((p)->base <= (p)->hd); \ + ASSERT((p)->hd < (p)->lim); \ + ASSERT((p)->base <= (p)->tl); \ + ASSERT((p)->tl < (p)->lim); + typedef struct { StgFunPtr stgGCEnter1; StgFunPtr stgGCFun; @@ -64,6 +73,14 @@ typedef union { StgTSOPtr t; } StgUnion; +/* + * This is the table that holds shadow-locations for all the STG + * registers. The shadow locations are used when: + * + * 1) the particular register isn't mapped to a real machine + * register, probably because there's a shortage of real registers. + * 2) caller-saves registers are saved across a CCall + */ typedef struct StgRegTable_ { StgUnion rR1; StgUnion rR2; @@ -91,18 +108,18 @@ typedef struct StgRegTable_ { struct bdescr_ *rCurrentNursery; /* Hp/HpLim point into this block */ struct bdescr_ *rCurrentAlloc; /* for allocation using allocate() */ StgWord rHpAlloc; /* number of *bytes* being allocated in heap */ - // rmp_tmp1..rmp_result2 are only used in SMP builds to avoid per-thread temps - // in bss, but currently always incldue here so we just run mkDerivedConstants once + // rmp_tmp1..rmp_result2 are only used in THREADED_RTS builds to + // avoid per-thread temps in bss, but currently always incldue here + // so we just run mkDerivedConstants once StgInt rmp_tmp_w; MP_INT rmp_tmp1; MP_INT rmp_tmp2; MP_INT rmp_result1; MP_INT rmp_result2; -#if defined(SMP) || defined(PAR) + StgWord rRet; // holds the return code of the thread +#if defined(THREADED_RTS) || defined(PAR) StgSparkPool rSparks; /* per-task spark pool */ #endif - // If this flag is set, we are running Haskell code. Used to detect - // uses of 'foreign import unsafe' that should be 'safe'. } StgRegTable; #if IN_STG_CODE @@ -315,20 +332,30 @@ struct PartCapability_ { StgRegTable r; }; -/* No such thing as a MainCapability under SMP - each thread must have +/* No such thing as a MainCapability under THREADED_RTS - each thread must have * its own Capability. */ -#if IN_STG_CODE && !defined(SMP) +#if IN_STG_CODE && !defined(THREADED_RTS) extern W_ MainCapability[]; #endif +/* + * Assigning to BaseReg (the ASSIGN_BaseReg macro): this happens on + * return from a "safe" foreign call, when the thread might be running + * on a new Capability. Obviously if BaseReg is not a register, then + * we are restricted to a single Capability (this invariant is enforced + * in Capability.c:initCapabilities), and assigning to BaseReg can be omitted. + */ + #if defined(REG_Base) && !defined(NO_GLOBAL_REG_DECLS) GLOBAL_REG_DECL(StgRegTable *,BaseReg,REG_Base) +#define ASSIGN_BaseReg(e) (BaseReg = (e)) #else -#ifdef SMP -#error BaseReg must be in a register for SMP +#ifdef THREADED_RTS +#error BaseReg must be in a register for THREADED_RTS #endif -#define BaseReg (&((struct Capability_)MainCapability).r) +#define BaseReg (&((struct PartCapability_ *)MainCapability)->r) +#define ASSIGN_BaseReg(e) (e) #endif #if defined(REG_Sp) && !defined(NO_GLOBAL_REG_DECLS) @@ -603,8 +630,8 @@ GLOBAL_REG_DECL(bdescr *,SparkLim,REG_SparkLim) #endif #ifdef CALLER_SAVES_Base -#ifdef SMP -#error "Can't have caller-saved BaseReg with SMP" +#ifdef THREADED_RTS +#error "Can't have caller-saved BaseReg with THREADED_RTS" #endif #define CALLER_SAVE_Base /* nothing */ #define CALLER_RESTORE_Base BaseReg = &MainRegTable;