takeMVar/putMVar were missing some write barriers when modifying a TSO
authorSimon Marlow <simonmar@microsoft.com>
Tue, 28 Feb 2006 16:37:24 +0000 (16:37 +0000)
committerSimon Marlow <simonmar@microsoft.com>
Tue, 28 Feb 2006 16:37:24 +0000 (16:37 +0000)
This relates to the recent introduction of clean/dirty TSOs, and the
consqeuent write barriers required.  We were missing some write
barriers in the takeMVar/putMVar family of primops, when performing
the take/put directly on another TSO.

Fixes #705, and probably some test failures.

ghc/rts/PrimOps.cmm
ghc/rts/Schedule.h

index 6a2b36f..23bc22e 100644 (file)
@@ -1496,6 +1496,7 @@ takeMVarzh_fast
       /* actually perform the putMVar for the thread that we just woke up */
       tso = StgMVar_head(mvar);
       PerformPut(tso,StgMVar_value(mvar));
+      foreign "C" dirtyTSO(tso "ptr") [];
 
 #if defined(GRAN) || defined(PAR)
       /* ToDo: check 2nd arg (mvar) is right */
@@ -1569,6 +1570,7 @@ tryTakeMVarzh_fast
        /* actually perform the putMVar for the thread that we just woke up */
        tso = StgMVar_head(mvar);
        PerformPut(tso,StgMVar_value(mvar));
+        foreign "C" dirtyTSO(tso "ptr") [];
 
 #if defined(GRAN) || defined(PAR)
        /* ToDo: check 2nd arg (mvar) is right */
@@ -1638,6 +1640,7 @@ putMVarzh_fast
        /* actually perform the takeMVar */
        tso = StgMVar_head(mvar);
        PerformTake(tso, R2);
+        foreign "C" dirtyTSO(tso "ptr") [];
       
 #if defined(GRAN) || defined(PAR)
        /* ToDo: check 2nd arg (mvar) is right */
@@ -1703,6 +1706,7 @@ tryPutMVarzh_fast
        /* actually perform the takeMVar */
        tso = StgMVar_head(mvar);
        PerformTake(tso, R2);
+        foreign "C" dirtyTSO(tso "ptr") [];
       
 #if defined(GRAN) || defined(PAR)
        /* ToDo: check 2nd arg (mvar) is right */
index 553c2a2..0e2e496 100644 (file)
@@ -287,12 +287,6 @@ emptyThreadQueues(Capability *cap)
     ;
 }
 
-STATIC_INLINE void
-dirtyTSO (StgTSO *tso)
-{
-    tso->flags |= TSO_DIRTY;
-}
-
 #ifdef DEBUG
 void sched_belch(char *s, ...)
    GNU_ATTRIBUTE(format (printf, 1, 2));
@@ -300,5 +294,11 @@ void sched_belch(char *s, ...)
 
 #endif /* !IN_STG_CODE */
 
+STATIC_INLINE void
+dirtyTSO (StgTSO *tso)
+{
+    tso->flags |= TSO_DIRTY;
+}
+
 #endif /* SCHEDULE_H */