diff options
| author | Ian Lance Taylor <iant@golang.org> | 2019-11-12 17:22:28 -0800 |
|---|---|---|
| committer | Ian Lance Taylor <iant@golang.org> | 2019-11-13 18:03:37 +0000 |
| commit | e762378c42b786233ea13affa1cc2ee132ceefaf (patch) | |
| tree | 5f68f5d1e61cb315e630840a7f513bbe4750aa6a /src/runtime/proc.go | |
| parent | bf4990522263503a1219372cd8f1ee9422b51324 (diff) | |
| download | go-e762378c42b786233ea13affa1cc2ee132ceefaf.tar.xz | |
runtime: acquire timersLocks around moveTimers
In the discussion of CL 171828 we decided that it was not necessary to
acquire timersLock around the call to moveTimers, because the world is
stopped. However, that is not correct, as sysmon runs even when the world
is stopped, and it calls timeSleepUntil which looks through the timers.
timeSleepUntil acquires timersLock, but that doesn't help if moveTimers
is running at the same time.
Updates #6239
Updates #27707
Updates #35462
Change-Id: I346c5bde594c4aff9955ae430b37c2b6fc71567f
Reviewed-on: https://go-review.googlesource.com/c/go/+/206938
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Diffstat (limited to 'src/runtime/proc.go')
| -rw-r--r-- | src/runtime/proc.go | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/src/runtime/proc.go b/src/runtime/proc.go index 3252173c0a..34d5928aa3 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -4073,10 +4073,17 @@ func (pp *p) destroy() { } if len(pp.timers) > 0 { plocal := getg().m.p.ptr() - // The world is stopped so we don't need to hold timersLock. + // The world is stopped, but we acquire timersLock to + // protect against sysmon calling timeSleepUntil. + // This is the only case where we hold the timersLock of + // more than one P, so there are no deadlock concerns. + lock(&plocal.timersLock) + lock(&pp.timersLock) moveTimers(plocal, pp.timers) pp.timers = nil pp.adjustTimers = 0 + unlock(&pp.timersLock) + unlock(&plocal.timersLock) } // If there's a background worker, make it runnable and put // it on the global queue so it can clean itself up. |
