gcMarkTermination() ensures that all caches are flushed before continuing the GC cycle, thus preempting all goroutines.
However, inlining calls to lock() in bgsweep makes it non-preemptible for most of the time, leading to livelock.
This change adds explicit preemption to avoid this.
Fixes #73499.
Change-Id: I4abf0d658f3d7a03ad588469cd013a0639de0c8a
Reviewed-on: https://go-review.googlesource.com/c/go/+/668795
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
// gosweepone returning ^0 above
// and the lock being acquired.
unlock(&sweep.lock)
+ // This goroutine must preempt when we have no work to do
+ // but isSweepDone returns false because of another existing sweeper.
+ // See issue #73499.
+ goschedIfBusy()
continue
}
sweep.parked = true