diff options
author | Ian Lance Taylor <iant@golang.org> | 2020-03-11 22:03:50 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2020-03-12 23:17:02 +0000 |
commit | 5d70cb066756369f99be6ffa69b639626d95e647 (patch) | |
tree | e1938cdd31a48165d9eb9a788aa2ac6427439e3b /src/runtime/time.go | |
parent | 29b36a88ab0b179c140612e7c907042b2a388587 (diff) | |
download | go-5d70cb066756369f99be6ffa69b639626d95e647.tar.gz go-5d70cb066756369f99be6ffa69b639626d95e647.zip |
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 <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/runtime/time.go')
-rw-r--r-- | src/runtime/time.go | 10 |
1 files changed, 10 insertions, 0 deletions
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") |