Fix a lost-wakeup bug in BLACKHOLE handling (#13751)
authorSimon Marlow <marlowsd@gmail.com>
Sat, 3 Jun 2017 19:26:13 +0000 (20:26 +0100)
committerSimon Marlow <marlowsd@gmail.com>
Thu, 8 Jun 2017 07:38:09 +0000 (08:38 +0100)
commit598472908ebb08f6811b892f285490554c290ae3
tree84079aceefe1a7eacda507f104c0f0d4d8c12417
parentbca56bd040de64315564cdac4b7e943fc8a75ea0
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
includes/stg/MiscClosures.h
rts/HeapStackCheck.cmm
rts/Interpreter.c
rts/Messages.c
rts/Schedule.c
rts/StgStartup.cmm
rts/sm/Evac.c
rts/sm/Evac.h
rts/sm/Scav.c
testsuite/tests/concurrent/should_run/all.T