aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2020-04-03 12:52:17 -0700
committerIan Lance Taylor <iant@golang.org>2020-04-06 03:35:33 +0000
commit5f3354d1bf2e6a61e4b9e1e31ee04b99dfe7de35 (patch)
tree5f6516429d7639976bed14bdbc4b68ab0586cdc5
parent763bd58b19a3aea9760cb8c8326dabf78653db68 (diff)
downloadgo-5f3354d1bf2e6a61e4b9e1e31ee04b99dfe7de35.tar.gz
go-5f3354d1bf2e6a61e4b9e1e31ee04b99dfe7de35.zip
time, runtime: only call resetTimer from (*Timer).Reset
Previously we stopped the timer and then reset it. With the current timer implementation that is no longer required. Change-Id: Ie7aba61ad53ce835f6fcd0b6bce7fe0a15b10e24 Reviewed-on: https://go-review.googlesource.com/c/go/+/227180 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com>
-rw-r--r--src/runtime/time.go19
-rw-r--r--src/time/sleep.go6
2 files changed, 16 insertions, 9 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
diff --git a/src/time/sleep.go b/src/time/sleep.go
index bd0ed9aaba..22ffd68282 100644
--- a/src/time/sleep.go
+++ b/src/time/sleep.go
@@ -38,7 +38,7 @@ func when(d Duration) int64 {
func startTimer(*runtimeTimer)
func stopTimer(*runtimeTimer) bool
-func resetTimer(*runtimeTimer, int64)
+func resetTimer(*runtimeTimer, int64) bool
func modTimer(t *runtimeTimer, when, period int64, f func(interface{}, uintptr), arg interface{}, seq uintptr)
// The Timer type represents a single event.
@@ -123,9 +123,7 @@ func (t *Timer) Reset(d Duration) bool {
panic("time: Reset called on uninitialized Timer")
}
w := when(d)
- active := stopTimer(&t.r)
- resetTimer(&t.r, w)
- return active
+ return resetTimer(&t.r, w)
}
func sendTime(c interface{}, seq uintptr) {