diff options
author | Ian Lance Taylor <iant@golang.org> | 2019-04-10 21:38:16 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2019-10-22 21:04:09 +0000 |
commit | 466547014769bbdf7d5a62ca1019bf52d809dfcd (patch) | |
tree | e632d0a9c8216dea3856607b3f0371fe2e1fe130 /src/runtime/time.go | |
parent | daeb5efb20a561ffc865f94163e836b68eee4193 (diff) | |
download | go-466547014769bbdf7d5a62ca1019bf52d809dfcd.tar.gz go-466547014769bbdf7d5a62ca1019bf52d809dfcd.zip |
runtime: add new cleantimers function
Also add a skeleton of the runOneTimer function.
Updates #27707
Change-Id: Ic6a0279354a57295f823093704b7e152ce5d769d
Reviewed-on: https://go-review.googlesource.com/c/go/+/171835
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 | 55 |
1 files changed, 52 insertions, 3 deletions
diff --git a/src/runtime/time.go b/src/runtime/time.go index 4269fb9a3a..ffb56f1805 100644 --- a/src/runtime/time.go +++ b/src/runtime/time.go @@ -151,6 +151,9 @@ type timersBucket struct { // timerMoving -> panic: resettimer called on active timer // timerModifiedXX -> panic: resettimer called on active timer // timerModifying -> panic: resettimer called on active timer +// cleantimers (looks in P's timer heap): +// timerDeleted -> timerRemoving -> timerRemoved +// timerModifiedXX -> timerMoving -> timerWaiting // Values for the timer status field. const ( @@ -763,9 +766,49 @@ func timerproc(tb *timersBucket) { // slows down addtimer. Reports whether no timer problems were found. // The caller must have locked the timers for pp. func cleantimers(pp *p) bool { - // TODO: write this. - throw("cleantimers") - return true + for { + if len(pp.timers) == 0 { + return true + } + t := pp.timers[0] + if t.pp.ptr() != pp { + throw("cleantimers: bad p") + } + switch s := atomic.Load(&t.status); s { + case timerDeleted: + if !atomic.Cas(&t.status, s, timerRemoving) { + continue + } + if !dodeltimer0(pp) { + return false + } + if !atomic.Cas(&t.status, timerRemoving, timerRemoved) { + return false + } + case timerModifiedEarlier, timerModifiedLater: + if !atomic.Cas(&t.status, s, timerMoving) { + continue + } + // Now we can change the when field. + t.when = t.nextwhen + // Move t to the right position. + if !dodeltimer0(pp) { + return false + } + if !doaddtimer(pp, t) { + return false + } + if s == timerModifiedEarlier { + atomic.Xadd(&pp.adjustTimers, -1) + } + if !atomic.Cas(&t.status, timerMoving, timerWaiting) { + return false + } + default: + // Head of timers does not need adjustment. + return true + } + } } // moveTimers moves a slice of timers to pp. The slice has been taken @@ -797,6 +840,12 @@ func runtimer(pp *p, now int64) int64 { return -1 } +// runOneTimer runs a single timer. +// The caller must have locked the timers for pp. +func runOneTimer(pp *p, t *timer, now int64) { + throw("runOneTimer: not yet implemented") +} + func timejump() *g { if faketime == 0 { return nil |