aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/time.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/time.go')
-rw-r--r--src/runtime/time.go19
1 files changed, 14 insertions, 5 deletions
diff --git a/src/runtime/time.go b/src/runtime/time.go
index 208fbf64c7..fdb5066b24 100644
--- a/src/runtime/time.go
+++ b/src/runtime/time.go
@@ -216,11 +216,12 @@ func stopTimer(t *timer) bool {
// resetTimer resets an inactive timer, adding it to the heap.
//go:linkname resetTimer time.resetTimer
-func resetTimer(t *timer, when int64) {
+// Reports whether the timer was modified before it was run.
+func resetTimer(t *timer, when int64) bool {
if raceenabled {
racerelease(unsafe.Pointer(t))
}
- resettimer(t, when)
+ return resettimer(t, when)
}
// modTimer modifies an existing timer.
@@ -403,13 +404,15 @@ func dodeltimer0(pp *p) {
// modtimer modifies an existing timer.
// This is called by the netpoll code or time.Ticker.Reset.
-func modtimer(t *timer, when, period int64, f func(interface{}, uintptr), arg interface{}, seq uintptr) {
+// 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 {
if when < 0 {
when = maxWhen
}
status := uint32(timerNoStatus)
wasRemoved := false
+ var pending bool
var mp *m
loop:
for {
@@ -419,6 +422,7 @@ loop:
// This could lead to a self-deadlock. See #38070.
mp = acquirem()
if atomic.Cas(&t.status, status, timerModifying) {
+ pending = true // timer not yet run
break loop
}
releasem(mp)
@@ -431,6 +435,7 @@ loop:
// Act like addtimer.
if atomic.Cas(&t.status, status, timerModifying) {
wasRemoved = true
+ pending = false // timer already run or stopped
break loop
}
releasem(mp)
@@ -440,6 +445,7 @@ loop:
mp = acquirem()
if atomic.Cas(&t.status, status, timerModifying) {
atomic.Xadd(&t.pp.ptr().deletedTimers, -1)
+ pending = false // timer already stopped
break loop
}
releasem(mp)
@@ -510,14 +516,17 @@ loop:
wakeNetPoller(when)
}
}
+
+ return pending
}
// resettimer resets the time when a timer should fire.
// If used for an inactive timer, the timer will become active.
// This should be called instead of addtimer if the timer value has been,
// or may have been, used previously.
-func resettimer(t *timer, when int64) {
- modtimer(t, when, t.period, t.f, t.arg, t.seq)
+// Reports whether the timer was modified before it was run.
+func resettimer(t *timer, when int64) bool {
+ return modtimer(t, when, t.period, t.f, t.arg, t.seq)
}
// cleantimers cleans up the head of the timer queue. This speeds up