diff options
author | Ian Lance Taylor <iant@golang.org> | 2019-04-10 21:23:55 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2019-10-22 20:45:48 +0000 |
commit | 9093b1def0b5e6f3ac30d5f9c18b375e8f5964e9 (patch) | |
tree | b78e2f03c8527485b70b837d3a7d3c03bd9dcdca /src/runtime/time.go | |
parent | b12703e052feb46faa3a5e4efd3d68837682717e (diff) | |
download | go-9093b1def0b5e6f3ac30d5f9c18b375e8f5964e9.tar.gz go-9093b1def0b5e6f3ac30d5f9c18b375e8f5964e9.zip |
runtime: add new dodeltimer and dodeltimer0 functions
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>
Diffstat (limited to 'src/runtime/time.go')
-rw-r--r-- | src/runtime/time.go | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/runtime/time.go b/src/runtime/time.go index 4e3511eb11..4269fb9a3a 100644 --- a/src/runtime/time.go +++ b/src/runtime/time.go @@ -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 |