remove accidental extra in previous patch
[ghc-hetmet.git] / ghc / includes / Regs.h
index b65d242..b6e2921 100644 (file)
 
 #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 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;