[project @ 2005-06-06 08:49:07 by tharris]
authortharris <unknown>
Mon, 6 Jun 2005 08:49:07 +0000 (08:49 +0000)
committertharris <unknown>
Mon, 6 Jun 2005 08:49:07 +0000 (08:49 +0000)
Remove SMP-only fields from STM data structures from non-SMP builds

ghc/includes/Closures.h
ghc/includes/STM.h
ghc/includes/mkDerivedConstants.c
ghc/rts/GC.c
ghc/rts/GCCompact.c
ghc/rts/PrimOps.cmm
ghc/rts/STM.c

index c8071fd..506592f 100644 (file)
@@ -357,7 +357,9 @@ typedef struct {
   StgHeader                  header;
   StgClosure                *volatile current_value;
   StgTVarWaitQueue          *volatile first_wait_queue_entry;
+#if defined(SMP)
   struct StgTRecHeader_     *volatile last_update_by;
+#endif
 } StgTVar;
 
 /* new_value == expected_value for read-only accesses */
@@ -366,7 +368,9 @@ typedef struct {
   StgTVar                   *tvar;
   StgClosure                *expected_value;
   StgClosure                *new_value; 
+#if defined(SMP)
   struct StgTRecHeader_     *saw_update_by;
+#endif
 } TRecEntry;
 
 #define TREC_CHUNK_NUM_ENTRIES 256
index cf821dc..0db5185 100644 (file)
@@ -184,6 +184,15 @@ extern StgBool stmReWait(StgTSO *tso);
 
 /*----------------------------------------------------------------------
 
+   TVar management operations
+   --------------------------
+*/
+
+extern StgTVar *stmNewTVar(StgRegTable *reg,
+                           StgClosure *new_value);
+
+/*----------------------------------------------------------------------
+
    Data access operations
    ----------------------
 */
index 4602869..754189c 100644 (file)
@@ -374,11 +374,6 @@ main(int argc, char *argv[])
     closure_field(StgMVar,tail);
     closure_field(StgMVar,value);
 
-    closure_size(StgTVar);
-    closure_field(StgTVar,current_value);
-    closure_field(StgTVar,first_wait_queue_entry);
-    closure_field(StgTVar,last_update_by);
-
     closure_size(StgBCO);
     closure_field(StgBCO, instrs);
     closure_field(StgBCO, literals);
index db00d81..f75468f 100644 (file)
@@ -2871,7 +2871,9 @@ scavenge(step *stp)
        evac_gen = 0;
        tvar->current_value = evacuate((StgClosure*)tvar->current_value);
        tvar->first_wait_queue_entry = (StgTVarWaitQueue *)evacuate((StgClosure*)tvar->first_wait_queue_entry);
+#if defined(SMP)
        tvar->last_update_by = (StgTRecHeader *)evacuate((StgClosure*)tvar->last_update_by);
+#endif
        evac_gen = saved_evac_gen;
        failed_to_evac = rtsTrue; // mutable
        p += sizeofW(StgTVar);
@@ -3217,7 +3219,9 @@ linear_scan:
            evac_gen = 0;
            tvar->current_value = evacuate((StgClosure*)tvar->current_value);
            tvar->first_wait_queue_entry = (StgTVarWaitQueue *)evacuate((StgClosure*)tvar->first_wait_queue_entry);
+#if defined(SMP)
             tvar->last_update_by = (StgTRecHeader *)evacuate((StgClosure*)tvar->last_update_by);
+#endif
            evac_gen = saved_evac_gen;
            failed_to_evac = rtsTrue; // mutable
            break;
@@ -3530,7 +3534,9 @@ scavenge_one(StgPtr p)
        evac_gen = 0;
        tvar->current_value = evacuate((StgClosure*)tvar->current_value);
        tvar->first_wait_queue_entry = (StgTVarWaitQueue *)evacuate((StgClosure*)tvar->first_wait_queue_entry);
+#if defined(SMP)
        tvar->last_update_by = (StgTRecHeader *)evacuate((StgClosure*)tvar->last_update_by);
+#endif
        evac_gen = saved_evac_gen;
        failed_to_evac = rtsTrue; // mutable
        break;
index 012235e..f4e66b6 100644 (file)
@@ -675,7 +675,9 @@ thread_obj (StgInfoTable *info, StgPtr p)
         StgTVar *tvar = (StgTVar *)p;
        thread((StgPtr)&tvar->current_value);
        thread((StgPtr)&tvar->first_wait_queue_entry);
+#if defined(SMP)
        thread((StgPtr)&tvar->last_update_by);
+#endif
        return p + sizeofW(StgTVar);
     }
     
index 082cb01..7b1c8aa 100644 (file)
@@ -1330,22 +1330,13 @@ retry_pop_stack:
 newTVarzh_fast
 {
   W_ tv;
-  W_ trec;
+  W_ new_value;
 
   /* Args: R1 = initialisation value */
 
-  ALLOC_PRIM( SIZEOF_StgTVar, R1_PTR, newTVarzh_fast);
-  tv = Hp - SIZEOF_StgTVar + WDS(1);
-  SET_HDR(tv,stg_TVAR_info,W_[CCCS]);
-  StgTVar_current_value(tv) = R1;
-  StgTVar_first_wait_queue_entry(tv) = stg_END_STM_WAIT_QUEUE_closure;
-#if defined(SMP)
-  trec = StgTSO_trec(CurrentTSO);
-  StgTVar_last_update_by(tv) = trec;
-#else
-  StgTVar_last_update_by(tv) = NO_TREC;
-#endif
-    
+  MAYBE_GC (R1_PTR, newTVarzh_fast); 
+  new_value = R1;
+  tv = foreign "C" stmNewTVar(BaseReg "ptr", new_value "ptr");
   RET_P(tv);
 }
 
index 2be5c69..74894ec 100644 (file)
@@ -169,7 +169,13 @@ static int shake(void) {
      
 /*......................................................................*/
 
+#define IF_STM_UNIPROC(__X)  do { } while (0)
+#define IF_STM_CG_LOCK(__X)  do { } while (0)
+#define IF_STM_FG_LOCKS(__X) do { } while (0)
+
 #if defined(STM_UNIPROC)
+#undef IF_STM_UNIPROC
+#define IF_STM_UNIPROC(__X)  do { __X } while (0)
 static const StgBool use_read_phase = FALSE;
 
 static void lock_stm(StgTRecHeader *trec STG_UNUSED) {
@@ -204,13 +210,15 @@ static StgBool cond_lock_tvar(StgTRecHeader *trec STG_UNUSED,
   StgClosure *result;
   TRACE("%p : cond_lock_tvar(%p, %p)\n", trec, s, expected);
   result = s -> current_value;
-  TRACE("%p : %d\n", (result == expected) ? "success" : "failure");
+  TRACE("%p : %s\n", trec, (result == expected) ? "success" : "failure");
   return (result == expected);
 }
 #endif
 
 #if defined(STM_CG_LOCK) /*........................................*/
 
+#undef IF_STM_CG_LOCK
+#define IF_STM_CG_LOCK(__X)  do { __X } while (0)
 static const StgBool use_read_phase = FALSE;
 static volatile StgTRecHeader *smp_locked = NULL;
 
@@ -259,6 +267,8 @@ static StgBool cond_lock_tvar(StgTRecHeader *trec STG_UNUSED,
 
 #if defined(STM_FG_LOCKS) /*...................................*/
 
+#undef IF_STM_FG_LOCKS
+#define IF_STM_FG_LOCKS(__X) do { __X } while (0)
 static const StgBool use_read_phase = TRUE;
 
 static void lock_stm(StgTRecHeader *trec STG_UNUSED) {
@@ -381,6 +391,19 @@ static StgTRecHeader *new_stg_trec_header(StgRegTable *reg,
   return result;  
 }
 
+static StgTVar *new_tvar(StgRegTable *reg,
+                         StgClosure *new_value) {
+  StgTVar *result;
+  result = (StgTVar *)allocateLocal(reg, sizeofW(StgTVar));
+  SET_HDR (result, &stg_TVAR_info, CCS_SYSTEM);
+  result -> current_value = new_value;
+  result -> first_wait_queue_entry = END_STM_WAIT_QUEUE;
+#if defined(SMP)
+  result -> last_update_by = NO_TREC;
+#endif
+  return result;
+}
+
 /*......................................................................*/
 
 // Helper functions for managing waiting lists
@@ -597,20 +620,23 @@ static StgBool validate_and_acquire_ownership (StgTRecHeader *trec,
           BREAK_FOR_EACH;
         }
       } else {
-        TRACE("%p : will need to check %p\n", trec, s);
-        if (s -> current_value != e -> expected_value) {
-          TRACE("%p : doesn't match\n", trec);
-          result = FALSE;
-          BREAK_FOR_EACH;
-        }
-        e -> saw_update_by = s -> last_update_by;
-        if (s -> current_value != e -> expected_value) {
-          TRACE("%p : doesn't match (race)\n", trec);
-          result = FALSE;
-          BREAK_FOR_EACH;
-        } else {
-          TRACE("%p : need to check update by %p\n", trec, e -> saw_update_by);
-        }
+        ASSERT(use_read_phase);
+        IF_STM_FG_LOCKS({
+          TRACE("%p : will need to check %p\n", trec, s);
+          if (s -> current_value != e -> expected_value) {
+            TRACE("%p : doesn't match\n", trec);
+            result = FALSE;
+            BREAK_FOR_EACH;
+          }
+          e -> saw_update_by = s -> last_update_by;
+          if (s -> current_value != e -> expected_value) {
+            TRACE("%p : doesn't match (race)\n", trec);
+            result = FALSE;
+            BREAK_FOR_EACH;
+          } else {
+            TRACE("%p : need to check update by %p\n", trec, e -> saw_update_by);
+          }
+        });
       }
     });
   }
@@ -633,21 +659,24 @@ static StgBool validate_and_acquire_ownership (StgTRecHeader *trec,
 // Keir Fraser's PhD dissertation "Practical lock-free programming" discuss
 // this kind of algorithm.
 
-static StgBool check_read_only(StgTRecHeader *trec) {
+static StgBool check_read_only(StgTRecHeader *trec STG_UNUSED) {
   StgBool result = TRUE;
 
-  FOR_EACH_ENTRY(trec, e, {
-    StgTVar *s;
-    s = e -> tvar;
-    if (entry_is_read_only(e)) {
-      TRACE("%p : check_read_only for TVar %p, saw %p\n", trec, s, e -> saw_update_by);
-      if (s -> last_update_by != e -> saw_update_by) {
-        // ||s -> current_value != e -> expected_value) {
-        TRACE("%p : mismatch\n", trec);
-        result = FALSE;
-        BREAK_FOR_EACH;
+  ASSERT (use_read_phase);
+  IF_STM_FG_LOCKS({
+    FOR_EACH_ENTRY(trec, e, {
+      StgTVar *s;
+      s = e -> tvar;
+      if (entry_is_read_only(e)) {
+        TRACE("%p : check_read_only for TVar %p, saw %p\n", trec, s, e -> saw_update_by);
+        if (s -> last_update_by != e -> saw_update_by) {
+          // ||s -> current_value != e -> expected_value) {
+          TRACE("%p : mismatch\n", trec);
+          result = FALSE;
+          BREAK_FOR_EACH;
+        }
       }
-    }
+    });
   });
 
   return result;
@@ -781,6 +810,7 @@ StgBool stmCommitTransaction(StgRegTable *reg STG_UNUSED, StgTRecHeader *trec) {
     if (use_read_phase) {
       TRACE("%p : doing read check\n", trec);
       result = check_read_only(trec);
+      TRACE("%p : read-check %s\n", trec, result ? "succeeded" : "failed");
     }
     
     if (result) {
@@ -788,7 +818,6 @@ StgBool stmCommitTransaction(StgRegTable *reg STG_UNUSED, StgTRecHeader *trec) {
       // at the end of the call to validate_and_acquire_ownership.  This forms the
       // linearization point of the commit.
       
-      TRACE("%p : read-check succeeded\n", trec);
       FOR_EACH_ENTRY(trec, e, {
         StgTVar *s;
         s = e -> tvar;
@@ -799,7 +828,9 @@ StgBool stmCommitTransaction(StgRegTable *reg STG_UNUSED, StgTRecHeader *trec) {
           ACQ_ASSERT(tvar_is_locked(s, trec));
           TRACE("%p : writing %p to %p, waking waiters\n", trec, e -> new_value, s);
           unpark_waiters_on(s);
-          s -> last_update_by = trec;
+          IF_STM_FG_LOCKS({
+            s -> last_update_by = trec;
+          });
           unlock_tvar(trec, s, e -> new_value, TRUE);
         } 
         ACQ_ASSERT(!tvar_is_locked(s, trec));
@@ -1060,3 +1091,12 @@ void stmWriteTVar(StgRegTable *reg,
 
 /*......................................................................*/
 
+StgTVar *stmNewTVar(StgRegTable *reg,
+                    StgClosure *new_value) {
+  StgTVar *result;
+  result = new_tvar(reg, new_value);
+  return result;
+}
+
+/*......................................................................*/
+