Fix deadlock between STM and throwTo
authorSimon Marlow <marlowsd@gmail.com>
Thu, 12 Jul 2018 14:13:47 +0000 (10:13 -0400)
committerBen Gamari <ben@smart-cactus.org>
Thu, 12 Jul 2018 19:04:20 +0000 (15:04 -0400)
commit7fc418df856d9b58034eeec48915646e67a7a562
tree656a7a8ae131122c4253bb6c490fb9e7db671346
parent1a79270c72cfcd98d683cfe7b2c777d8dd353b78
Fix deadlock between STM and throwTo

There was a lock-order reversal between lockTSO() and the TVar lock,
see #15136 for the details.

It turns out we can fix this pretty easily by just deleting all the
locking code(!).  The principle for unblocking a `BlockedOnSTM` thread
then becomes the same as for other kinds of blocking: if the TSO
belongs to this capability then we do it directly, otherwise we send a
message to the capability that owns the TSO. That is, a thread blocked
on STM is owned by its capability, as it should be.

The possible downside of this is that we might send multiple messages
to wake up a thread when the thread is on another capability. This is
safe, it's just not very efficient.  I'll try to do some experiments
to see if this is a problem.

Test Plan: Test case from #15136 doesn't deadlock any more.

Reviewers: bgamari, osa1, erikd

Reviewed By: osa1

Subscribers: rwbarton, thomie, carter

GHC Trac Issues: #15136

Differential Revision: https://phabricator.haskell.org/D4956
rts/RaiseAsync.c
rts/SMPClosureOps.h
rts/STM.c
rts/Threads.c
rts/sm/Sanity.c