diff options
author | Simon Marlow <marlowsd@gmail.com> | 2017-06-03 20:26:13 +0100 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2017-06-08 08:38:09 +0100 |
commit | 598472908ebb08f6811b892f285490554c290ae3 (patch) | |
tree | 84079aceefe1a7eacda507f104c0f0d4d8c12417 /rts/StgStartup.cmm | |
parent | bca56bd040de64315564cdac4b7e943fc8a75ea0 (diff) | |
download | haskell-598472908ebb08f6811b892f285490554c290ae3.tar.gz |
Fix a lost-wakeup bug in BLACKHOLE handling (#13751)
Summary:
The problem occurred when
* Threads A & B evaluate the same thunk
* Thread A context-switches, so the thunk gets blackholed
* Thread C enters the blackhole, creates a BLOCKING_QUEUE attached to
the blackhole and thread A's `tso->bq` queue
* Thread B updates the blackhole with a value, overwriting the BLOCKING_QUEUE
* We GC, replacing A's update frame with stg_enter_checkbh
* Throw an exception in A, which ignores the stg_enter_checkbh frame
Now we have C blocked on A's tso->bq queue, but we forgot to check the
queue because the stg_enter_checkbh frame has been thrown away by the
exception.
The solution and alternative designs are discussed in Note [upd-black-hole].
This also exposed a bug in the interpreter, whereby we were sometimes
context-switching without calling `threadPaused()`. I've fixed this
and added some Notes.
Test Plan:
* `cd testsuite/tests/concurrent && make slow`
* validate
Reviewers: niteria, bgamari, austin, erikd
Reviewed By: erikd
Subscribers: rwbarton, thomie
GHC Trac Issues: #13751
Differential Revision: https://phabricator.haskell.org/D3630
Diffstat (limited to 'rts/StgStartup.cmm')
-rw-r--r-- | rts/StgStartup.cmm | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/rts/StgStartup.cmm b/rts/StgStartup.cmm index a650e5c367..0cd18628e2 100644 --- a/rts/StgStartup.cmm +++ b/rts/StgStartup.cmm @@ -127,6 +127,9 @@ stg_returnToSched /* no args: explicit stack layout */ // current thread. This is used for switching from compiled execution to the // interpreter, where calling threadPaused() on every switch would be too // expensive. +// +// See Note [avoiding threadPaused] in Interpreter.c +// stg_returnToSchedNotPaused /* no args: explicit stack layout */ { SAVE_THREAD_STATE(); |