summaryrefslogtreecommitdiff
path: root/rts/HeapStackCheck.cmm
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2014-07-31 10:00:16 +0100
committerSimon Marlow <marlowsd@gmail.com>2014-08-01 12:45:41 +0100
commit9d9a55469719908bbd5cd3277e0ac79c0588dc55 (patch)
tree64ac687c7eaae1518d20e180d6d71ae04f4671ef /rts/HeapStackCheck.cmm
parent6483b8ab7c5cb4dc3d06b2069dcd44fabe400858 (diff)
downloadhaskell-9d9a55469719908bbd5cd3277e0ac79c0588dc55.tar.gz
interruptible() was not returning true for BlockedOnSTM (#9379)
Summary: There's an knock-on fix in HeapStackCheck.c which is potentially scary, but I'm pretty confident is OK. See comment for details. Test Plan: I've run all the STM tests I can find, including libraries/stm/tests/stm049 with +RTS -N8 and some of the constants bumped to make it more of a stress test. Reviewers: hvr, rwbarton, austin Subscribers: simonmar, relrod, ezyang, carter Differential Revision: https://phabricator.haskell.org/D104 GHC Trac Issues: #9379
Diffstat (limited to 'rts/HeapStackCheck.cmm')
-rw-r--r--rts/HeapStackCheck.cmm25
1 files changed, 18 insertions, 7 deletions
diff --git a/rts/HeapStackCheck.cmm b/rts/HeapStackCheck.cmm
index 12bcfb26df..f090bff5ad 100644
--- a/rts/HeapStackCheck.cmm
+++ b/rts/HeapStackCheck.cmm
@@ -681,13 +681,24 @@ stg_block_async_void
STM-specific waiting
-------------------------------------------------------------------------- */
-stg_block_stmwait_finally
-{
- ccall stmWaitUnlock(MyCapability() "ptr", R3 "ptr");
- jump StgReturn [R1];
-}
-
stg_block_stmwait
{
- BLOCK_BUT_FIRST(stg_block_stmwait_finally);
+ // When blocking on an MVar we have to be careful to only release
+ // the lock on the MVar at the very last moment (using
+ // BLOCK_BUT_FIRST()), since when we release the lock another
+ // Capability can wake up the thread, which modifies its stack and
+ // other state. This is not a problem for STM, because STM
+ // wakeups are non-destructive; the waker simply calls
+ // tryWakeupThread() which sends a message to the owner
+ // Capability. So the moment we release this lock we might start
+ // getting wakeup messages, but that's perfectly harmless.
+ //
+ // Furthermore, we *must* release these locks, just in case an
+ // exception is raised in this thread by
+ // maybePerformBlockedException() while exiting to the scheduler,
+ // which will abort the transaction, which needs to obtain a lock
+ // on all the TVars to remove the thread from the queues.
+ //
+ ccall stmWaitUnlock(MyCapability() "ptr", R3 "ptr");
+ BLOCK_GENERIC;
}