X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=rts%2FSTM.c;h=01155b1107acf49191f15cd6df3926271bee127f;hp=5c3b4341e2136b4e527cb3a03363a654c2cc18f1;hb=9c4abbc0c2d4373eb7c63b1110821dfcb0077661;hpb=5a2769f0273dd389977e8283375e7920d183bdd4 diff --git a/rts/STM.c b/rts/STM.c index 5c3b434..01155b1 100644 --- a/rts/STM.c +++ b/rts/STM.c @@ -328,15 +328,21 @@ static void park_tso(StgTSO *tso) { } static void unpark_tso(Capability *cap, StgTSO *tso) { - // We will continue unparking threads while they remain on one of the wait - // queues: it's up to the thread itself to remove it from the wait queues - // if it decides to do so when it is scheduled. - if (tso -> why_blocked == BlockedOnSTM) { - TRACE("unpark_tso on tso=%p\n", tso); - unblockOne(cap,tso); - } else { - TRACE("spurious unpark_tso on tso=%p\n", tso); - } + // We will continue unparking threads while they remain on one of the wait + // queues: it's up to the thread itself to remove it from the wait queues + // if it decides to do so when it is scheduled. + + // Unblocking a TSO from BlockedOnSTM is done under the TSO lock, + // to avoid multiple CPUs unblocking the same TSO, and also to + // synchronise with throwTo(). + lockTSO(tso); + if (tso -> why_blocked == BlockedOnSTM) { + TRACE("unpark_tso on tso=%p\n", tso); + unblockOne(cap,tso); + } else { + TRACE("spurious unpark_tso on tso=%p\n", tso); + } + unlockTSO(tso); } static void unpark_waiters_on(Capability *cap, StgTVar *s) {