[commit: ghc] master: Fix deadlock (#10545) (111ba4b)
git at git.haskell.org
git at git.haskell.org
Fri Jun 26 08:32:01 UTC 2015
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/111ba4beda4ffc48381723da12e5b237d7f9ac59/ghc
>---------------------------------------------------------------
commit 111ba4beda4ffc48381723da12e5b237d7f9ac59
Author: Simon Marlow <marlowsd at gmail.com>
Date: Fri Jun 19 15:12:24 2015 +0100
Fix deadlock (#10545)
yieldCapability() was not prepared to be called by a Task that is not
either a worker or a bound Task. This could happen if we ended up in
yieldCapability via this call stack:
performGC()
scheduleDoGC()
requestSync()
yieldCapability()
and there were a few other ways this could happen via requestSync.
The fix is to handle this case in yieldCapability(): when the Task is
not a worker or a bound Task, we put it on the returning_workers
queue, where it will be woken up again.
Summary of changes:
* `yieldCapability`: factored out subroutine waitForWorkerCapability`
* `waitForReturnCapability` renamed to `waitForCapability`, and
factored out subroutine `waitForReturnCapability`
* `releaseCapabilityAndQueue` worker renamed to `enqueueWorker`, does
not take a lock and no longer tests if `!isBoundTask()`
* `yieldCapability` adjusted for refactorings, only change in behavior
is when it is not a worker or bound task.
Test Plan:
* new test concurrent/should_run/performGC
* validate
Reviewers: niteria, austin, ezyang, bgamari
Subscribers: thomie, bgamari
Differential Revision: https://phabricator.haskell.org/D997
GHC Trac Issues: #10545
>---------------------------------------------------------------
111ba4beda4ffc48381723da12e5b237d7f9ac59
rts/Capability.c | 301 +++++++----
rts/Capability.h | 8 +-
rts/RtsAPI.c | 2 +-
rts/Schedule.c | 14 +-
rts/Task.h | 11 +
testsuite/tests/concurrent/should_run/RandomPGC.hs | 597 +++++++++++++++++++++
testsuite/tests/concurrent/should_run/all.T | 4 +
testsuite/tests/concurrent/should_run/performGC.hs | 24 +
.../tests/concurrent/should_run/performGC.stdout | 400 ++++++++++++++
9 files changed, 1231 insertions(+), 130 deletions(-)
Diff suppressed because of size. To see it, use:
git diff-tree --root --patch-with-stat --no-color --find-copies-harder --ignore-space-at-eol --cc 111ba4beda4ffc48381723da12e5b237d7f9ac59
More information about the ghc-commits
mailing list