From: Ian Lance Taylor Date: Thu, 12 Mar 2020 05:03:50 +0000 (-0700) Subject: runtime: leave cleantimers early if G is being preempted X-Git-Tag: go1.15beta1~877 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=5d70cb066756369f99be6ffa69b639626d95e647;p=gostls13.git 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 --- 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")