]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: add new dodeltimer and dodeltimer0 functions
authorIan Lance Taylor <iant@golang.org>
Thu, 11 Apr 2019 04:23:55 +0000 (21:23 -0700)
committerIan Lance Taylor <iant@golang.org>
Tue, 22 Oct 2019 20:45:48 +0000 (20:45 +0000)
The dodeltimer function removes a timer from a heap. The dodeltimer0
function removes the first timer from a heap; in the old timer code
this common special case was inlined in the timerproc function.

Updates #27707

Change-Id: I1b7c0af46866abb4bffa8aa4d8e7143f9ae8f402
Reviewed-on: https://go-review.googlesource.com/c/go/+/171834
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>
src/runtime/time.go

index 4e3511eb118170e48c4224cac088e6a8e2433ea9..4269fb9a3a0c6f5ce2937539fb839ed50b00e3ef 100644 (file)
@@ -417,6 +417,59 @@ func deltimer(t *timer) bool {
        }
 }
 
+// dodeltimer removes timer i from the current P's heap.
+// We are locked on the P when this is called.
+// It reports whether it saw no problems due to races.
+// The caller must have locked the timers for pp.
+func dodeltimer(pp *p, i int) bool {
+       if t := pp.timers[i]; t.pp.ptr() != pp {
+               throw("dodeltimer: wrong P")
+       } else {
+               t.pp = 0
+       }
+       last := len(pp.timers) - 1
+       if i != last {
+               pp.timers[i] = pp.timers[last]
+       }
+       pp.timers[last] = nil
+       pp.timers = pp.timers[:last]
+       ok := true
+       if i != last {
+               // Moving to i may have moved the last timer to a new parent,
+               // so sift up to preserve the heap guarantee.
+               if !siftupTimer(pp.timers, i) {
+                       ok = false
+               }
+               if !siftdownTimer(pp.timers, i) {
+                       ok = false
+               }
+       }
+       return ok
+}
+
+// dodeltimer0 removes timer 0 from the current P's heap.
+// We are locked on the P when this is called.
+// It reports whether it saw no problems due to races.
+// The caller must have locked the timers for pp.
+func dodeltimer0(pp *p) bool {
+       if t := pp.timers[0]; t.pp.ptr() != pp {
+               throw("dodeltimer0: wrong P")
+       } else {
+               t.pp = 0
+       }
+       last := len(pp.timers) - 1
+       if last > 0 {
+               pp.timers[0] = pp.timers[last]
+       }
+       pp.timers[last] = nil
+       pp.timers = pp.timers[:last]
+       ok := true
+       if last > 0 {
+               ok = siftdownTimer(pp.timers, 0)
+       }
+       return ok
+}
+
 func deltimerOld(t *timer) bool {
        if t.tb == nil {
                // t.tb can be nil if the user created a timer