[project @ 2005-11-08 15:07:08 by simonmar]
authorsimonmar <unknown>
Tue, 8 Nov 2005 15:07:08 +0000 (15:07 +0000)
committersimonmar <unknown>
Tue, 8 Nov 2005 15:07:08 +0000 (15:07 +0000)
SMP bugfix: if the thread we were just running blocked, then we are in
a delicate state - we don't necessarily have access to the TSO we were
just running, because we relinquished it when we put it on whatever
blocking queue it is on.  It might even be running already.

Previously I made the scheduler quickly loop again in this case.
However, I made it loop too quickly: we should be sure to set the
blackholes_need_checking flag if necessary, otherwise we can miss some
wakeups.

ghc/rts/Schedule.c

index 35e87e0..299e132 100644 (file)
@@ -615,6 +615,18 @@ run_thread:
     // happened.  So find the new location:
     t = cap->r.rCurrentTSO;
 
+    // We have run some Haskell code: there might be blackhole-blocked
+    // threads to wake up now.
+    // Lock-free test here should be ok, we're just setting a flag.
+    if ( blackhole_queue != END_TSO_QUEUE ) {
+       blackholes_need_checking = rtsTrue;
+    }
+    
+    // And save the current errno in this thread.
+    // XXX: possibly bogus for SMP because this thread might already
+    // be running again, see code below.
+    t->saved_errno = errno;
+
 #ifdef SMP
     // If ret is ThreadBlocked, and this Task is bound to the TSO that
     // blocked, we are in limbo - the TSO is now owned by whatever it
@@ -632,9 +644,6 @@ run_thread:
 
     ASSERT_CAPABILITY_INVARIANTS(cap,task);
 
-    // And save the current errno in this thread.
-    t->saved_errno = errno;
-
     // ----------------------------------------------------------------------
     
     // Costs for the scheduler are assigned to CCS_SYSTEM
@@ -643,13 +652,6 @@ run_thread:
     CCCS = CCS_SYSTEM;
 #endif
     
-    // We have run some Haskell code: there might be blackhole-blocked
-    // threads to wake up now.
-    // Lock-free test here should be ok, we're just setting a flag.
-    if ( blackhole_queue != END_TSO_QUEUE ) {
-       blackholes_need_checking = rtsTrue;
-    }
-    
 #if defined(THREADED_RTS)
     IF_DEBUG(scheduler,debugBelch("sched (task %p): ", (void *)(unsigned long)(unsigned int)osThreadId()););
 #elif !defined(GRAN) && !defined(PARALLEL_HASKELL)