From 5d70cb066756369f99be6ffa69b639626d95e647 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 11 Mar 2020 22:03:50 -0700 Subject: [PATCH] runtime: leave cleantimers early if G is being preempted The cleantimers can run for a while in some unlikely cases. If the GC is trying to preempt the G, it is forced to wait as the G is holding timersLock. To avoid introducing a GC delay, return from cleantimers if the G has a preemption request. Fixes #37779 Change-Id: Id9a567f991e26668e2292eefc39e2edc56efa4e0 Reviewed-on: https://go-review.googlesource.com/c/go/+/223122 Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot Reviewed-by: Michael Knyszek Reviewed-by: Cherry Zhang --- src/runtime/time.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/runtime/time.go b/src/runtime/time.go index 155e0501fe..c62207d7f7 100644 --- a/src/runtime/time.go +++ b/src/runtime/time.go @@ -499,10 +499,20 @@ func resettimer(t *timer, when int64) { // slows down addtimer. Reports whether no timer problems were found. // The caller must have locked the timers for pp. func cleantimers(pp *p) { + gp := getg() for { if len(pp.timers) == 0 { return } + + // This loop can theoretically run for a while, and because + // it is holding timersLock it cannot be preempted. + // If someone is trying to preempt us, just return. + // We can clean the timers later. + if gp.preemptStop { + return + } + t := pp.timers[0] if t.pp.ptr() != pp { throw("cleantimers: bad p") -- 2.50.0