]> Cypherpunks repositories - gostls13.git/commitdiff
time, runtime: only call resetTimer from (*Timer).Reset
authorIan Lance Taylor <iant@golang.org>
Fri, 3 Apr 2020 19:52:17 +0000 (12:52 -0700)
committerIan Lance Taylor <iant@golang.org>
Mon, 6 Apr 2020 03:35:33 +0000 (03:35 +0000)
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>
src/runtime/time.go
src/time/sleep.go

index 208fbf64c7cb618016d2233018e06b4e87c04b83..fdb5066b24f31718d7db566c4ac5821efbf911b6 100644 (file)
@@ -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
index bd0ed9aaba88acbc948cce31d908f89e8f7dba4c..22ffd68282be721e082fd7ae1d242af67a1647fe 100644 (file)
@@ -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) {