]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: add new cleantimers function
authorIan Lance Taylor <iant@golang.org>
Thu, 11 Apr 2019 04:38:16 +0000 (21:38 -0700)
committerIan Lance Taylor <iant@golang.org>
Tue, 22 Oct 2019 21:04:09 +0000 (21:04 +0000)
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>
src/runtime/time.go

index 4269fb9a3a0c6f5ce2937539fb839ed50b00e3ef..ffb56f1805538b64cd1d8699bba3c3909948c942 100644 (file)
@@ -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