Skip to content

Commit

Permalink
runtime: implement timeSleepUntil for new timers
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
ianlancetaylor committed Oct 23, 2019
1 parent 5f92939 commit c824420
Showing 1 changed file with 46 additions and 0 deletions.
46 changes: 46 additions & 0 deletions src/runtime/time.go
Expand Up @@ -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.
Expand Down

0 comments on commit c824420

Please sign in to comment.