summaryrefslogtreecommitdiff
path: root/rts/HeapStackCheck.cmm
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2017-06-03 20:26:13 +0100
committerSimon Marlow <marlowsd@gmail.com>2017-06-08 08:38:09 +0100
commit598472908ebb08f6811b892f285490554c290ae3 (patch)
tree84079aceefe1a7eacda507f104c0f0d4d8c12417 /rts/HeapStackCheck.cmm
parentbca56bd040de64315564cdac4b7e943fc8a75ea0 (diff)
downloadhaskell-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/HeapStackCheck.cmm')
-rw-r--r--rts/HeapStackCheck.cmm24
1 files changed, 0 insertions, 24 deletions
diff --git a/rts/HeapStackCheck.cmm b/rts/HeapStackCheck.cmm
index 001e5f6299..85fb1cbef6 100644
--- a/rts/HeapStackCheck.cmm
+++ b/rts/HeapStackCheck.cmm
@@ -230,30 +230,6 @@ stg_gc_prim_p_ll
}
/* -----------------------------------------------------------------------------
- stg_enter_checkbh is just like stg_enter, except that we also call
- checkBlockingQueues(). The point of this is that the GC can
- replace an stg_marked_upd_frame with an stg_enter_checkbh if it
- finds that the BLACKHOLE has already been updated by another
- thread. It would be unsafe to use stg_enter, because there might
- be an orphaned BLOCKING_QUEUE now.
- -------------------------------------------------------------------------- */
-
-/* The stg_enter_checkbh frame has the same shape as an update frame: */
-
-INFO_TABLE_RET ( stg_enter_checkbh, RET_SMALL,
- UPDATE_FRAME_FIELDS(W_,P_,info_ptr,ccs,p2,updatee))
- return (P_ ret)
-{
- foreign "C" checkBlockingQueues(MyCapability() "ptr",
- CurrentTSO);
-
- // we need to return updatee now. Note that it might be a pointer
- // to an indirection or a tagged value, we don't know which, so we
- // need to ENTER() rather than return().
- ENTER(updatee);
-}
-
-/* -----------------------------------------------------------------------------
Info tables for returning values of various types. These are used
when we want to push a frame on the stack that will return a value
to the frame underneath it.