aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/runtime/time.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/runtime/time.go')
-rw-r--r--libgo/go/runtime/time.go40
1 files changed, 25 insertions, 15 deletions
diff --git a/libgo/go/runtime/time.go b/libgo/go/runtime/time.go
index 7cc9156..8e5a36e 100644
--- a/libgo/go/runtime/time.go
+++ b/libgo/go/runtime/time.go
@@ -26,8 +26,8 @@ type timer struct {
// when must be positive on an active timer.
when int64
period int64
- f func(interface{}, uintptr)
- arg interface{}
+ f func(any, uintptr)
+ arg any
seq uintptr
// What to set the when field to in timerModifiedXX status.
@@ -230,14 +230,14 @@ func resetTimer(t *timer, when int64) bool {
// modTimer modifies an existing timer.
//go:linkname modTimer time.modTimer
-func modTimer(t *timer, when, period int64, f func(interface{}, uintptr), arg interface{}, seq uintptr) {
+func modTimer(t *timer, when, period int64, f func(any, uintptr), arg any, seq uintptr) {
modtimer(t, when, period, f, arg, seq)
}
// Go runtime.
// Ready the goroutine arg.
-func goroutineReady(arg interface{}, seq uintptr) {
+func goroutineReady(arg any, seq uintptr) {
goready(arg.(*g), 0)
}
@@ -365,9 +365,9 @@ 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.
+// It returns the smallest changed index in pp.timers.
// The caller must have locked the timers for pp.
-func dodeltimer(pp *p, i int) {
+func dodeltimer(pp *p, i int) int {
if t := pp.timers[i]; t.pp.ptr() != pp {
throw("dodeltimer: wrong P")
} else {
@@ -379,16 +379,18 @@ func dodeltimer(pp *p, i int) {
}
pp.timers[last] = nil
pp.timers = pp.timers[:last]
+ smallestChanged := i
if i != last {
// Moving to i may have moved the last timer to a new parent,
// so sift up to preserve the heap guarantee.
- siftupTimer(pp.timers, i)
+ smallestChanged = siftupTimer(pp.timers, i)
siftdownTimer(pp.timers, i)
}
if i == 0 {
updateTimer0When(pp)
}
atomic.Xadd(&pp.numTimers, -1)
+ return smallestChanged
}
// dodeltimer0 removes timer 0 from the current P's heap.
@@ -417,7 +419,7 @@ func dodeltimer0(pp *p) {
// modtimer modifies an existing timer.
// This is called by the netpoll code or time.Ticker.Reset or time.Timer.Reset.
// Reports whether the timer was modified before it was run.
-func modtimer(t *timer, when, period int64, f func(interface{}, uintptr), arg interface{}, seq uintptr) bool {
+func modtimer(t *timer, when, period int64, f func(any, uintptr), arg any, seq uintptr) bool {
if when <= 0 {
throw("timer when must be positive")
}
@@ -673,13 +675,14 @@ func adjusttimers(pp *p, now int64) {
switch s := atomic.Load(&t.status); s {
case timerDeleted:
if atomic.Cas(&t.status, s, timerRemoving) {
- dodeltimer(pp, i)
+ changed := dodeltimer(pp, i)
if !atomic.Cas(&t.status, timerRemoving, timerRemoved) {
badTimer()
}
atomic.Xadd(&pp.deletedTimers, -1)
- // Look at this heap position again.
- i--
+ // Go back to the earliest changed heap entry.
+ // "- 1" because the loop will add 1.
+ i = changed - 1
}
case timerModifiedEarlier, timerModifiedLater:
if atomic.Cas(&t.status, s, timerMoving) {
@@ -689,10 +692,11 @@ func adjusttimers(pp *p, now int64) {
// We don't add it back yet because the
// heap manipulation could cause our
// loop to skip some other timer.
- dodeltimer(pp, i)
+ changed := dodeltimer(pp, i)
moved = append(moved, t)
- // Look at this heap position again.
- i--
+ // Go back to the earliest changed heap entry.
+ // "- 1" because the loop will add 1.
+ i = changed - 1
}
case timerNoStatus, timerRunning, timerRemoving, timerRemoved, timerMoving:
badTimer()
@@ -1020,7 +1024,10 @@ func timeSleepUntil() (int64, *p) {
// "panic holding locks" message. Instead, we panic while not
// holding a lock.
-func siftupTimer(t []*timer, i int) {
+// siftupTimer puts the timer at position i in the right place
+// in the heap by moving it up toward the top of the heap.
+// It returns the smallest changed index.
+func siftupTimer(t []*timer, i int) int {
if i >= len(t) {
badTimer()
}
@@ -1040,8 +1047,11 @@ func siftupTimer(t []*timer, i int) {
if tmp != t[i] {
t[i] = tmp
}
+ return i
}
+// siftdownTimer puts the timer at position i in the right place
+// in the heap by moving it down toward the bottom of the heap.
func siftdownTimer(t []*timer, i int) {
n := len(t)
if i >= n {