#ifndef REGS_H
#define REGS_H
-#include "gmp.h" // Needs MP_INT definition
-
-/*
- * 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;
- StgClosure **hd;
- 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 {
+ StgWord stgEagerBlackholeInfo;
StgFunPtr stgGCEnter1;
StgFunPtr stgGCFun;
} StgFunTable;
StgTSOPtr t;
} StgUnion;
+// Urgh.. we don't know the size of an MP_INT here because we haven't
+// #included gmp.h. We should really autoconf this, but GMP may not
+// be available at ./configure time if we're building it (GMP) locally.
+#define MP_INT_WORDS 3
+
/*
* This is the table that holds shadow-locations for all the STG
* registers. The shadow locations are used when:
// 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
- StgWord rmp_tmp_w;
- MP_INT rmp_tmp1;
- MP_INT rmp_tmp2;
- MP_INT rmp_result1;
- MP_INT rmp_result2;
+ StgWord rmp_tmp_w[MP_INT_WORDS];
+ StgWord rmp_tmp1[MP_INT_WORDS];
+ StgWord rmp_tmp2[MP_INT_WORDS];
+ StgWord rmp_result1[MP_INT_WORDS];
+ StgWord rmp_result2[MP_INT_WORDS];
StgWord rRet; // holds the return code of the thread
- StgSparkPool rSparks; /* per-task spark pool */
} StgRegTable;
#if IN_STG_CODE
#define SAVE_CurrentTSO (BaseReg->rCurrentTSO)
#define SAVE_CurrentNursery (BaseReg->rCurrentNursery)
#define SAVE_HpAlloc (BaseReg->rHpAlloc)
-#define SAVE_SparkHd (BaseReg->rSparks.hd)
-#define SAVE_SparkTl (BaseReg->rSparks.tl)
-#define SAVE_SparkBase (BaseReg->rSparks.base)
-#define SAVE_SparkLim (BaseReg->rSparks.lim)
/* We sometimes need to save registers across a C-call, eg. if they
* are clobbered in the standard calling convention. We define the
/* No such thing as a MainCapability under THREADED_RTS - each thread must have
* its own Capability.
*/
-#if IN_STG_CODE && !defined(THREADED_RTS)
+#if IN_STG_CODE && !(defined(THREADED_RTS) && !defined(NOSMP))
extern W_ MainCapability[];
#endif
GLOBAL_REG_DECL(StgRegTable *,BaseReg,REG_Base)
#define ASSIGN_BaseReg(e) (BaseReg = (e))
#else
-#ifdef THREADED_RTS
+#if defined(THREADED_RTS) && !defined(NOSMP)
#error BaseReg must be in a register for THREADED_RTS
#endif
#define BaseReg (&((struct PartCapability_ *)MainCapability)->r)
#define HpAlloc (BaseReg->rHpAlloc)
#endif
-#if defined(REG_SparkHd) && !defined(NO_GLOBAL_REG_DECLS)
-GLOBAL_REG_DECL(bdescr *,SparkHd,REG_SparkHd)
-#else
-#define SparkHd (BaseReg->rSparks.hd)
-#endif
-
-#if defined(REG_SparkTl) && !defined(NO_GLOBAL_REG_DECLS)
-GLOBAL_REG_DECL(bdescr *,SparkTl,REG_SparkTl)
-#else
-#define SparkTl (BaseReg->rSparks.tl)
-#endif
-
-#if defined(REG_SparkBase) && !defined(NO_GLOBAL_REG_DECLS)
-GLOBAL_REG_DECL(bdescr *,SparkBase,REG_SparkBase)
-#else
-#define SparkBase (BaseReg->rSparks.base)
-#endif
-
-#if defined(REG_SparkLim) && !defined(NO_GLOBAL_REG_DECLS)
-GLOBAL_REG_DECL(bdescr *,SparkLim,REG_SparkLim)
-#else
-#define SparkLim (BaseReg->rSparks.lim)
-#endif
-
/* -----------------------------------------------------------------------------
Get absolute function pointers from the register table, to save
code space. On x86,
-------------------------------------------------------------------------- */
-#define FunReg ((StgFunTable *)((void *)BaseReg - sizeof(StgFunTable)))
+#define FunReg ((StgFunTable *)((void *)BaseReg - FIELD_OFFSET(struct PartCapability_, r)))
-#define stg_gc_enter_1 (FunReg->stgGCEnter1)
-#define stg_gc_fun (FunReg->stgGCFun)
+#define stg_EAGER_BLACKHOLE_info (FunReg->stgEagerBlackholeInfo)
+#define stg_gc_enter_1 (FunReg->stgGCEnter1)
+#define stg_gc_fun (FunReg->stgGCFun)
/* -----------------------------------------------------------------------------
For any registers which are denoted "caller-saves" by the C calling
#define CALLER_RESTORE_HpAlloc /* nothing */
#endif
-#ifdef CALLER_SAVES_SparkHd
-#define CALLER_SAVE_SparkHd SAVE_SparkHd = SparkHd;
-#define CALLER_RESTORE_SparkHd SparkHd = SAVE_SparkHd;
-#else
-#define CALLER_SAVE_SparkHd /* nothing */
-#define CALLER_RESTORE_SparkHd /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_SparkTl
-#define CALLER_SAVE_SparkTl SAVE_SparkTl = SparkTl;
-#define CALLER_RESTORE_SparkTl SparkTl = SAVE_SparkTl;
-#else
-#define CALLER_SAVE_SparkTl /* nothing */
-#define CALLER_RESTORE_SparkTl /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_SparkBase
-#define CALLER_SAVE_SparkBase SAVE_SparkBase = SparkBase;
-#define CALLER_RESTORE_SparkBase SparkBase = SAVE_SparkBase;
-#else
-#define CALLER_SAVE_SparkBase /* nothing */
-#define CALLER_RESTORE_SparkBase /* nothing */
-#endif
-
-#ifdef CALLER_SAVES_SparkLim
-#define CALLER_SAVE_SparkLim SAVE_SparkLim = SparkLim;
-#define CALLER_RESTORE_SparkLim SparkLim = SAVE_SparkLim;
-#else
-#define CALLER_SAVE_SparkLim /* nothing */
-#define CALLER_RESTORE_SparkLim /* nothing */
-#endif
-
#endif /* IN_STG_CODE */
/* ----------------------------------------------------------------------------
CALLER_SAVE_HpLim \
CALLER_SAVE_CurrentTSO \
CALLER_SAVE_CurrentNursery \
- CALLER_SAVE_SparkHd \
- CALLER_SAVE_SparkTl \
- CALLER_SAVE_SparkBase \
- CALLER_SAVE_SparkLim \
CALLER_SAVE_Base
#define CALLER_RESTORE_USER \
CALLER_RESTORE_Hp \
CALLER_RESTORE_HpLim \
CALLER_RESTORE_CurrentTSO \
- CALLER_RESTORE_CurrentNursery \
- CALLER_RESTORE_SparkHd \
- CALLER_RESTORE_SparkTl \
- CALLER_RESTORE_SparkBase \
- CALLER_RESTORE_SparkLim
+ CALLER_RESTORE_CurrentNursery
#else /* not IN_STG_CODE */