add comments and an ASSERT_LOCK_HELD()
[ghc-hetmet.git] / rts / RaiseAsync.c
index 9d03d07..10d91a7 100644 (file)
@@ -575,6 +575,12 @@ performBlockedException (Capability *cap, StgTSO *source, StgTSO *target)
 
    This is for use when we raise an exception in another thread, which
    may be blocked.
+
+   Precondition: we have exclusive access to the TSO, which entails
+   holding a lock on the object that owns the queue, if the TSO is
+   blocked.  e.g. if the thread is blocked on an MVar, we must hold a
+   lock on the MVar before calling removeFromQueues().
+
    This has nothing to do with the UnblockThread event in GranSim. -- HWL
    -------------------------------------------------------------------------- */
 
@@ -752,6 +758,9 @@ removeFromQueues(Capability *cap, StgTSO *tso)
       goto done;
 
   case BlockedOnBlackHole:
+      // we have exclusive access to this TSO, which implies that we
+      // must hold sched_mutex:
+      ASSERT_LOCK_HELD(&sched_mutex);
       removeThreadFromQueue(cap, &blackhole_queue, tso);
       goto done;
 
@@ -1010,23 +1019,14 @@ raiseAsync(Capability *cap, StgTSO *tso, StgClosure *exception,
            if (stop_at_atomically) {
                ASSERT(stmGetEnclosingTRec(tso->trec) == NO_TREC);
                stmCondemnTransaction(cap, tso -> trec);
-#ifdef REG_R1
                tso->sp = frame;
-#else
-               // R1 is not a register: the return convention for IO in
-               // this case puts the return value on the stack, so we
-               // need to set up the stack to return to the atomically
-               // frame properly...
-               tso->sp = frame - 2;
-               tso->sp[1] = (StgWord) &stg_NO_FINALIZER_closure; // why not?
-               tso->sp[0] = (StgWord) &stg_ut_1_0_unreg_info;
-#endif
                tso->what_next = ThreadRunGHC;
                return;
            }
            // Not stop_at_atomically... fall through and abort the
            // transaction.
            
+       case CATCH_STM_FRAME:
        case CATCH_RETRY_FRAME:
            // IF we find an ATOMICALLY_FRAME then we abort the
            // current transaction and propagate the exception.  In