mirror of
https://github.com/golang/go
synced 2024-09-15 22:20:06 +00:00
time: add Ticker.Reset
This CL implements Ticker.Reset method in time package. Benchmark: name time/op TickerReset-12 6.41µs ±10% TickerResetNaive-12 95.7µs ±12% Fixes #33184 Change-Id: I12c651f81e452541bcbbc748b45f038aae1f8dae Reviewed-on: https://go-review.googlesource.com/c/go/+/217362 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
ebe49b2c29
commit
6e5652bebe
|
@ -1 +1,2 @@
|
||||||
pkg testing, method (*T) Deadline() (time.Time, bool)
|
pkg testing, method (*T) Deadline() (time.Time, bool)
|
||||||
|
pkg time, method (*Ticker) Reset(Duration)
|
||||||
|
|
|
@ -80,3 +80,13 @@ TODO
|
||||||
<p>
|
<p>
|
||||||
TODO
|
TODO
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<dl id="time"><dt><a href="/pkg/time/">time</a></dt>
|
||||||
|
<dd>
|
||||||
|
<p><!-- golang.org/issue/33184 -->
|
||||||
|
The new method
|
||||||
|
<a href="/pkg/time#Ticker.Reset"><code>Ticker.Reset</code></a>
|
||||||
|
supports changing the duration of a ticker.
|
||||||
|
</p>
|
||||||
|
</dd>
|
||||||
|
</dl><!-- time -->
|
||||||
|
|
|
@ -233,6 +233,12 @@ func resetTimer(t *timer, when int64) {
|
||||||
resettimer(t, when)
|
resettimer(t, when)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
modtimer(t, when, period, f, arg, seq)
|
||||||
|
}
|
||||||
|
|
||||||
// Go runtime.
|
// Go runtime.
|
||||||
|
|
||||||
// Ready the goroutine arg.
|
// Ready the goroutine arg.
|
||||||
|
@ -402,7 +408,7 @@ func dodeltimer0(pp *p) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// modtimer modifies an existing timer.
|
// modtimer modifies an existing timer.
|
||||||
// This is called by the netpoll code.
|
// 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) {
|
func modtimer(t *timer, when, period int64, f func(interface{}, uintptr), arg interface{}, seq uintptr) {
|
||||||
if when < 0 {
|
if when < 0 {
|
||||||
when = maxWhen
|
when = maxWhen
|
||||||
|
|
|
@ -39,6 +39,7 @@ func when(d Duration) int64 {
|
||||||
func startTimer(*runtimeTimer)
|
func startTimer(*runtimeTimer)
|
||||||
func stopTimer(*runtimeTimer) bool
|
func stopTimer(*runtimeTimer) bool
|
||||||
func resetTimer(*runtimeTimer, int64)
|
func resetTimer(*runtimeTimer, int64)
|
||||||
|
func modTimer(t *runtimeTimer, when, period int64, f func(interface{}, uintptr), arg interface{}, seq uintptr)
|
||||||
|
|
||||||
// The Timer type represents a single event.
|
// The Timer type represents a single event.
|
||||||
// When the Timer expires, the current time will be sent on C,
|
// When the Timer expires, the current time will be sent on C,
|
||||||
|
|
|
@ -46,6 +46,15 @@ func (t *Ticker) Stop() {
|
||||||
stopTimer(&t.r)
|
stopTimer(&t.r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset stops a ticker and resets its period to the specified duration.
|
||||||
|
// The next tick will arrive after the new period elapses.
|
||||||
|
func (t *Ticker) Reset(d Duration) {
|
||||||
|
if t.r.f == nil {
|
||||||
|
panic("time: Reset called on uninitialized Ticker")
|
||||||
|
}
|
||||||
|
modTimer(&t.r, when(d), int64(d), t.r.f, t.r.arg, t.r.seq)
|
||||||
|
}
|
||||||
|
|
||||||
// Tick is a convenience wrapper for NewTicker providing access to the ticking
|
// Tick is a convenience wrapper for NewTicker providing access to the ticking
|
||||||
// channel only. While Tick is useful for clients that have no need to shut down
|
// channel only. While Tick is useful for clients that have no need to shut down
|
||||||
// the Ticker, be aware that without a way to shut it down the underlying
|
// the Ticker, be aware that without a way to shut it down the underlying
|
||||||
|
|
|
@ -36,13 +36,17 @@ func TestTicker(t *testing.T) {
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
ticker := NewTicker(delta)
|
ticker := NewTicker(delta)
|
||||||
t0 := Now()
|
t0 := Now()
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count/2; i++ {
|
||||||
|
<-ticker.C
|
||||||
|
}
|
||||||
|
ticker.Reset(delta * 2)
|
||||||
|
for i := count / 2; i < count; i++ {
|
||||||
<-ticker.C
|
<-ticker.C
|
||||||
}
|
}
|
||||||
ticker.Stop()
|
ticker.Stop()
|
||||||
t1 := Now()
|
t1 := Now()
|
||||||
dt := t1.Sub(t0)
|
dt := t1.Sub(t0)
|
||||||
target := delta * Duration(count)
|
target := 3 * delta * Duration(count/2)
|
||||||
slop := target * 2 / 10
|
slop := target * 2 / 10
|
||||||
if dt < target-slop || dt > target+slop {
|
if dt < target-slop || dt > target+slop {
|
||||||
errs = append(errs, fmt.Sprintf("%d %s ticks took %s, expected [%s,%s]", count, delta, dt, target-slop, target+slop))
|
errs = append(errs, fmt.Sprintf("%d %s ticks took %s, expected [%s,%s]", count, delta, dt, target-slop, target+slop))
|
||||||
|
@ -118,3 +122,24 @@ func BenchmarkTicker(b *testing.B) {
|
||||||
ticker.Stop()
|
ticker.Stop()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkTickerReset(b *testing.B) {
|
||||||
|
benchmark(b, func(n int) {
|
||||||
|
ticker := NewTicker(Nanosecond)
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
ticker.Reset(Nanosecond * 2)
|
||||||
|
}
|
||||||
|
ticker.Stop()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkTickerResetNaive(b *testing.B) {
|
||||||
|
benchmark(b, func(n int) {
|
||||||
|
ticker := NewTicker(Nanosecond)
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
ticker.Stop()
|
||||||
|
ticker = NewTicker(Nanosecond * 2)
|
||||||
|
}
|
||||||
|
ticker.Stop()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue