diff options
author | Ian Lance Taylor <iant@golang.org> | 2019-04-11 09:02:37 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2019-10-23 07:02:10 +0000 |
commit | c824420d4744bd3e11128c000d88c24859602d46 (patch) | |
tree | b7a6d9e6ce3018f2ede0c1d017b88c7955481323 /src/runtime/time.go | |
parent | 5f92939c9040c33ed19893a6b369b3dbbd3c5837 (diff) | |
download | go-c824420d4744bd3e11128c000d88c24859602d46.tar.gz go-c824420d4744bd3e11128c000d88c24859602d46.zip |
runtime: implement timeSleepUntil for new timers
Updates #27707
Change-Id: Id4b37594511895f404ee3c09a85263b2b35f835d
Reviewed-on: https://go-review.googlesource.com/c/go/+/171881
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Diffstat (limited to 'src/runtime/time.go')
-rw-r--r-- | src/runtime/time.go | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/runtime/time.go b/src/runtime/time.go index c0f2d0287d..4bc819f023 100644 --- a/src/runtime/time.go +++ b/src/runtime/time.go @@ -1227,6 +1227,52 @@ func timejumpLocked() *g { } func timeSleepUntil() int64 { + if oldTimers { + return timeSleepUntilOld() + } + + next := int64(maxWhen) + + for _, pp := range allp { + lock(&pp.timersLock) + c := atomic.Load(&pp.adjustTimers) + for _, t := range pp.timers { + switch s := atomic.Load(&t.status); s { + case timerWaiting: + if t.when < next { + next = t.when + } + case timerModifiedEarlier, timerModifiedLater: + if t.nextwhen < next { + next = t.nextwhen + } + if s == timerModifiedEarlier { + c-- + } + } + // 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. + // + // We don't worry about cases like timerModifying. + // New timers can show up at any time, + // so this function is necessarily imprecise. + // Do a signed check here since we aren't + // synchronizing the read of pp.adjustTimers + // with the check of a timer status. + if int32(c) <= 0 { + break + } + } + unlock(&pp.timersLock) + } + + return next +} + +func timeSleepUntilOld() int64 { next := int64(1<<63 - 1) // Determine minimum sleepUntil across all the timer buckets. |