aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/time.go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2019-04-10 21:38:16 -0700
committerIan Lance Taylor <iant@golang.org>2019-10-22 21:04:09 +0000
commit466547014769bbdf7d5a62ca1019bf52d809dfcd (patch)
treee632d0a9c8216dea3856607b3f0371fe2e1fe130 /src/runtime/time.go
parentdaeb5efb20a561ffc865f94163e836b68eee4193 (diff)
downloadgo-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.go55
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