diff options
author | Edward Z. Yang <ezyang@mit.edu> | 2013-07-08 11:03:35 -0700 |
---|---|---|
committer | Edward Z. Yang <ezyang@mit.edu> | 2013-07-09 11:29:11 -0700 |
commit | 70e20631742e516c6a11c3c112fbd5b4a08c15ac (patch) | |
tree | d0097f8b1c8e5c0a67b26bb950c036ea7684c65d /rts/RaiseAsync.c | |
parent | ca9a431401755f119d97dec59a1fc963a8e9f681 (diff) | |
download | haskell-70e20631742e516c6a11c3c112fbd5b4a08c15ac.tar.gz |
Implement atomicReadMVar, fixing #4001.
We add the invariant to the MVar blocked threads queue that
threads blocked on an atomic read are always at the front of
the queue. This invariant is easy to maintain, since takers
are only ever added to the end of the queue.
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
Diffstat (limited to 'rts/RaiseAsync.c')
-rw-r--r-- | rts/RaiseAsync.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/rts/RaiseAsync.c b/rts/RaiseAsync.c index 11f518a87d..edc4a91193 100644 --- a/rts/RaiseAsync.c +++ b/rts/RaiseAsync.c @@ -294,6 +294,7 @@ check_target: } case BlockedOnMVar: + case BlockedOnMVarRead: { /* To establish ownership of this TSO, we need to acquire a @@ -318,7 +319,7 @@ check_target: // we have the MVar, let's check whether the thread // is still blocked on the same MVar. - if (target->why_blocked != BlockedOnMVar + if ((target->why_blocked != BlockedOnMVar && target->why_blocked != BlockedOnMVarRead) || (StgMVar *)target->block_info.closure != mvar) { unlockClosure((StgClosure *)mvar, info); goto retry; @@ -637,6 +638,7 @@ removeFromQueues(Capability *cap, StgTSO *tso) goto done; case BlockedOnMVar: + case BlockedOnMVarRead: removeFromMVarBlockedQueue(tso); goto done; |