From cbc83989fe39607eec0dcb6a84f6086a9e0bb442 Mon Sep 17 00:00:00 2001 From: simonmar Date: Tue, 8 Nov 2005 15:07:08 +0000 Subject: [PATCH 1/1] [project @ 2005-11-08 15:07:08 by simonmar] 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 | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/ghc/rts/Schedule.c b/ghc/rts/Schedule.c index 35e87e0..299e132 100644 --- a/ghc/rts/Schedule.c +++ b/ghc/rts/Schedule.c @@ -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) -- 1.7.10.4