diff options
author | Ian Lance Taylor <iant@golang.org> | 2019-04-11 08:53:42 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2019-10-23 05:20:12 +0000 |
commit | 5f92939c9040c33ed19893a6b369b3dbbd3c5837 (patch) | |
tree | 7df63d3834b7c0ce451c18e731101fb39bb9fd97 /src/runtime/time.go | |
parent | 0195a29399946210700bc5dca2d55c75d80ef9ff (diff) | |
download | go-5f92939c9040c33ed19893a6b369b3dbbd3c5837.tar.gz go-5f92939c9040c33ed19893a6b369b3dbbd3c5837.zip |
runtime: update timejump function for new timers
Since timers are now on a P, rather than having a G running timerproc,
timejump changes to return a P rather than a G.
Updates #27707
Change-Id: I3d05af2d664409a0fd906e709fdecbbcbe00b9a7
Reviewed-on: https://go-review.googlesource.com/c/go/+/171880
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Diffstat (limited to 'src/runtime/time.go')
-rw-r--r-- | src/runtime/time.go | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/src/runtime/time.go b/src/runtime/time.go index 3eba66bf07..c0f2d0287d 100644 --- a/src/runtime/time.go +++ b/src/runtime/time.go @@ -1125,7 +1125,66 @@ func runOneTimer(pp *p, t *timer, now int64) { f(arg, seq) } -func timejump() *g { +func timejump() *p { + if faketime == 0 { + return nil + } + + // Nothing is running, so we can look at all the P's. + // Determine a timer bucket with minimum when. + var ( + minT *timer + minWhen int64 + minP *p + ) + for _, pp := range allp { + if pp.status != _Pidle && pp.status != _Pdead { + throw("non-idle P in timejump") + } + if len(pp.timers) == 0 { + continue + } + c := pp.adjustTimers + for _, t := range pp.timers { + switch s := atomic.Load(&t.status); s { + case timerWaiting: + if minT == nil || t.when < minWhen { + minT = t + minWhen = t.when + minP = pp + } + case timerModifiedEarlier, timerModifiedLater: + if minT == nil || t.nextwhen < minWhen { + minT = t + minWhen = t.nextwhen + minP = pp + } + if s == timerModifiedEarlier { + c-- + } + case timerRunning, timerModifying, timerMoving: + badTimer() + } + // The timers are sorted, so we only have to check + // the first timer for each P, unless there are + // some timerModifiedEarlier timers. The number + // of timerModifiedEarlier timers is in the adjustTimers + // field, used to initialize c, above. + if c == 0 { + break + } + } + } + + if minT == nil || minWhen <= faketime { + return nil + } + + faketime = minWhen + return minP +} + +func timejumpOld() *g { if faketime == 0 { return nil } |