From 180662f03883a12cfa6091ff494db428cc5e7461 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Fri, 9 May 2025 15:52:48 +0200 Subject: [PATCH] runtime: avoid an allocation in (*time.Timer).Reset --- src/runtime/scheduler.go | 13 +++++-------- src/runtime/scheduler_cooperative.go | 6 +++--- src/runtime/scheduler_none.go | 4 ++-- src/runtime/scheduler_threads.go | 6 +++--- src/runtime/time_go122.go | 6 +++--- src/runtime/time_go123.go | 15 +++++++++------ 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/runtime/scheduler.go b/src/runtime/scheduler.go index 9ca54e1c0..9b2557952 100644 --- a/src/runtime/scheduler.go +++ b/src/runtime/scheduler.go @@ -39,20 +39,17 @@ func timerQueueAdd(tn *timerNode) { *q = tn } -func timerQueueRemove(t *timer) bool { - removedTimer := false +func timerQueueRemove(t *timer) *timerNode { for q := &timerQueue; *q != nil; q = &(*q).next { if (*q).timer == t { scheduleLog("removed timer") + n := *q *q = (*q).next - removedTimer = true - break + return n } } - if !removedTimer { - scheduleLog("did not remove timer") - } - return removedTimer + scheduleLog("did not remove timer") + return nil } // Goexit terminates the currently running goroutine. No other goroutines are affected. diff --git a/src/runtime/scheduler_cooperative.go b/src/runtime/scheduler_cooperative.go index 8df1962e1..d919aa969 100644 --- a/src/runtime/scheduler_cooperative.go +++ b/src/runtime/scheduler_cooperative.go @@ -117,11 +117,11 @@ func addTimer(tim *timerNode) { // removeTimer is the implementation of time.stopTimer. It removes a timer from // the timer queue, returning true if the timer is present in the timer queue. -func removeTimer(tim *timer) bool { +func removeTimer(tim *timer) *timerNode { mask := interrupt.Disable() - removedTimer := timerQueueRemove(tim) + n := timerQueueRemove(tim) interrupt.Restore(mask) - return removedTimer + return n } func schedulerRunQueue() *task.Queue { diff --git a/src/runtime/scheduler_none.go b/src/runtime/scheduler_none.go index 3c03e9438..3f88e03eb 100644 --- a/src/runtime/scheduler_none.go +++ b/src/runtime/scheduler_none.go @@ -56,9 +56,9 @@ func addTimer(tim *timerNode) { runtimePanic("timers not supported without a scheduler") } -func removeTimer(tim *timer) bool { +func removeTimer(tim *timer) *timerNode { runtimePanic("timers not supported without a scheduler") - return false + return nil } func schedulerRunQueue() *task.Queue { diff --git a/src/runtime/scheduler_threads.go b/src/runtime/scheduler_threads.go index 292499354..32b9caaf2 100644 --- a/src/runtime/scheduler_threads.go +++ b/src/runtime/scheduler_threads.go @@ -110,11 +110,11 @@ func addTimer(tim *timerNode) { timerQueueLock.Unlock() } -func removeTimer(tim *timer) bool { +func removeTimer(tim *timer) *timerNode { timerQueueLock.Lock() - removed := timerQueueRemove(tim) + n := timerQueueRemove(tim) timerQueueLock.Unlock() - return removed + return n } func schedulerRunQueue() *task.Queue { diff --git a/src/runtime/time_go122.go b/src/runtime/time_go122.go index 2994c2722..2693555cf 100644 --- a/src/runtime/time_go122.go +++ b/src/runtime/time_go122.go @@ -53,13 +53,13 @@ func startTimer(tim *timer) { //go:linkname stopTimer time.stopTimer func stopTimer(tim *timer) bool { - return removeTimer(tim) + return removeTimer(tim) != nil } //go:linkname resetTimer time.resetTimer func resetTimer(tim *timer, when int64) bool { tim.when = when - removed := removeTimer(tim) + n := removeTimer(tim) startTimer(tim) - return removed + return n != nil } diff --git a/src/runtime/time_go123.go b/src/runtime/time_go123.go index cfef4d393..e39da7448 100644 --- a/src/runtime/time_go123.go +++ b/src/runtime/time_go123.go @@ -52,17 +52,20 @@ func newTimer(when, period int64, f func(arg any, seq uintptr, delta int64), arg //go:linkname stopTimer time.stopTimer func stopTimer(tim *timeTimer) bool { - return removeTimer(&tim.timer) + return removeTimer(&tim.timer) != nil } //go:linkname resetTimer time.resetTimer func resetTimer(t *timeTimer, when, period int64) bool { t.timer.when = when t.timer.period = period - removed := removeTimer(&t.timer) - addTimer(&timerNode{ - timer: &t.timer, - callback: timerCallback, - }) + n := removeTimer(&t.timer) + removed := n != nil + if n == nil { + n = new(timerNode) + } + n.timer = &t.timer + n.callback = timerCallback + addTimer(n) return removed }