[project @ 2005-05-19 13:46:24 by simonmar]
authorsimonmar <unknown>
Thu, 19 May 2005 13:46:24 +0000 (13:46 +0000)
committersimonmar <unknown>
Thu, 19 May 2005 13:46:24 +0000 (13:46 +0000)
Fix locking when unblocking a thread in take/putMVar.  Due to CPP
nonsense the previous locking wasn't actually working, which lead to
deadlock problems.  It now turns out that I can call unblockOne
directly rather than needing unblockOneLocked (the lock on the MVar
means I have exclusive access to the threads on its queue).

ghc/rts/PrimOps.cmm

index f704570..bf3aa6f 100644 (file)
@@ -1424,18 +1424,6 @@ newMVarzh_fast
     StgTSO_sp(tso) = StgTSO_sp(tso) + WDS(3);  \
     lval = W_[StgTSO_sp(tso) - WDS(1)];
 
-/*
- * Only in threaded mode: we have to be careful when manipulating another thread's TSO,
- * because the scheduler might also be manipulating it.
- */
-#if defined(RTS_SUPPORTS_THREADS)
-#define ACQUIRE_SCHED_LOCK   foreign "C" ACQUIRE_LOCK(sched_mutex "ptr");
-#define RELEASE_SCHED_LOCK   foreign "C" RELEASE_LOCK(sched_mutex "ptr");
-#else
-#define ACQUIRE_SCHED_LOCK
-#define RELEASE_SCHED_LOCK
-#endif
-
 takeMVarzh_fast
 {
     W_ mvar, val, info, tso;
@@ -1471,8 +1459,6 @@ takeMVarzh_fast
 
   if (StgMVar_head(mvar) != stg_END_TSO_QUEUE_closure)
   {
-      ACQUIRE_SCHED_LOCK;
-
       /* There are putMVar(s) waiting... 
        * wake up the first thread on the queue
        */
@@ -1484,15 +1470,13 @@ takeMVarzh_fast
 
 #if defined(GRAN) || defined(PAR)
       /* ToDo: check 2nd arg (mvar) is right */
-      "ptr" tso = foreign "C" unblockOneLocked(StgMVar_head(mvar),mvar);
+      "ptr" tso = foreign "C" unblockOne(StgMVar_head(mvar),mvar);
       StgMVar_head(mvar) = tso;
 #else
-      "ptr" tso = foreign "C" unblockOneLocked(StgMVar_head(mvar) "ptr");
+      "ptr" tso = foreign "C" unblockOne(StgMVar_head(mvar) "ptr");
       StgMVar_head(mvar) = tso;
 #endif
 
-      RELEASE_SCHED_LOCK;
-
       if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) {
          StgMVar_tail(mvar) = stg_END_TSO_QUEUE_closure;
       }
@@ -1547,8 +1531,6 @@ tryTakeMVarzh_fast
 
     if (StgMVar_head(mvar) != stg_END_TSO_QUEUE_closure) {
 
-        ACQUIRE_SCHED_LOCK;
-
        /* There are putMVar(s) waiting... 
         * wake up the first thread on the queue
         */
@@ -1560,15 +1542,13 @@ tryTakeMVarzh_fast
 
 #if defined(GRAN) || defined(PAR)
        /* ToDo: check 2nd arg (mvar) is right */
-       "ptr" tso = foreign "C" unblockOneLocked(StgMVar_head(mvar) "ptr", mvar "ptr");
+       "ptr" tso = foreign "C" unblockOne(StgMVar_head(mvar) "ptr", mvar "ptr");
        StgMVar_head(mvar) = tso;
 #else
-       "ptr" tso = foreign "C" unblockOneLocked(StgMVar_head(mvar) "ptr");
+       "ptr" tso = foreign "C" unblockOne(StgMVar_head(mvar) "ptr");
        StgMVar_head(mvar) = tso;
 #endif
 
-        RELEASE_SCHED_LOCK;
-
        if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) {
            StgMVar_tail(mvar) = stg_END_TSO_QUEUE_closure;
        }
@@ -1620,8 +1600,6 @@ putMVarzh_fast
   
     if (StgMVar_head(mvar) != stg_END_TSO_QUEUE_closure) {
 
-        ACQUIRE_SCHED_LOCK;
-
        /* There are takeMVar(s) waiting: wake up the first one
         */
        ASSERT(StgTSO_why_blocked(StgMVar_head(mvar)) == BlockedOnMVar::I16);
@@ -1632,15 +1610,13 @@ putMVarzh_fast
       
 #if defined(GRAN) || defined(PAR)
        /* ToDo: check 2nd arg (mvar) is right */
-       "ptr" tso = foreign "C" unblockOneLocked(StgMVar_head(mvar) "ptr",mvar "ptr");
+       "ptr" tso = foreign "C" unblockOne(StgMVar_head(mvar) "ptr",mvar "ptr");
        StgMVar_head(mvar) = tso;
 #else
-       "ptr" tso = foreign "C" unblockOneLocked(StgMVar_head(mvar) "ptr");
+       "ptr" tso = foreign "C" unblockOne(StgMVar_head(mvar) "ptr");
        StgMVar_head(mvar) = tso;
 #endif
 
-        RELEASE_SCHED_LOCK;
-
        if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) {
            StgMVar_tail(mvar) = stg_END_TSO_QUEUE_closure;
        }
@@ -1689,8 +1665,6 @@ tryPutMVarzh_fast
   
     if (StgMVar_head(mvar) != stg_END_TSO_QUEUE_closure) {
 
-        ACQUIRE_SCHED_LOCK;
-
        /* There are takeMVar(s) waiting: wake up the first one
         */
        ASSERT(StgTSO_why_blocked(StgMVar_head(mvar)) == BlockedOnMVar::I16);
@@ -1701,15 +1675,13 @@ tryPutMVarzh_fast
       
 #if defined(GRAN) || defined(PAR)
        /* ToDo: check 2nd arg (mvar) is right */
-       "ptr" tso = foreign "C" unblockOneLocked(StgMVar_head(mvar) "ptr",mvar "ptr");
+       "ptr" tso = foreign "C" unblockOne(StgMVar_head(mvar) "ptr",mvar "ptr");
        StgMVar_head(mvar) = tso;
 #else
-       "ptr" tso = foreign "C" unblockOneLocked(StgMVar_head(mvar) "ptr");
+       "ptr" tso = foreign "C" unblockOne(StgMVar_head(mvar) "ptr");
        StgMVar_head(mvar) = tso;
 #endif
 
-        RELEASE_SCHED_LOCK;
-
        if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) {
            StgMVar_tail(mvar) = stg_END_TSO_QUEUE_closure;
        }