Commit 64b68bed authored by Austin Clements's avatar Austin Clements

runtime/debug: make SetGCPercent(-1) wait for concurrent GC

Currently, SetGCPercent(-1) disables GC, but doesn't wait for any
currently running concurrent GC to finish, so GC can still be running
when it returns. This is a change in behavior from Go 1.8, probably
defies user expectations, and can break various runtime tests that
depend on SetGCPercent(-1) to disable garbage collection in order to
prevent preemption deadlocks.

Fix this by making SetGCPercent(-1) block until any concurrently
running GC cycle finishes.

Fixes #22443.

Change-Id: I904133a34acf97a7942ef4531ace0647b13930ef
Reviewed-on: https://go-review.googlesource.com/79195
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
parent 48e207d5
......@@ -230,6 +230,24 @@ func setGCPercent(in int32) (out int32) {
// Update pacing in response to gcpercent change.
gcSetTriggerRatio(memstats.triggerRatio)
unlock(&mheap_.lock)
// If we just disabled GC, wait for any concurrent GC to
// finish so we always return with no GC running.
if in < 0 {
// Disable phase transitions.
lock(&work.sweepWaiters.lock)
if gcphase == _GCmark {
// GC is active. Wait until we reach sweeping.
gp := getg()
gp.schedlink = work.sweepWaiters.head
work.sweepWaiters.head.set(gp)
goparkunlock(&work.sweepWaiters.lock, "wait for GC cycle", traceEvGoBlock, 1)
} else {
// GC isn't active.
unlock(&work.sweepWaiters.lock)
}
}
return out
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment