mirror of
https://github.com/golang/go
synced 2024-11-26 05:07:59 -07: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 time, method (*Ticker) Reset(Duration)
|
||||
|
@ -80,3 +80,13 @@ TODO
|
||||
<p>
|
||||
TODO
|
||||
</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)
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
||||
// Ready the goroutine arg.
|
||||
@ -402,7 +408,7 @@ func dodeltimer0(pp *p) bool {
|
||||
}
|
||||
|
||||
// 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) {
|
||||
if when < 0 {
|
||||
when = maxWhen
|
||||
|
@ -39,6 +39,7 @@ func when(d Duration) int64 {
|
||||
func startTimer(*runtimeTimer)
|
||||
func stopTimer(*runtimeTimer) bool
|
||||
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.
|
||||
// When the Timer expires, the current time will be sent on C,
|
||||
|
@ -46,6 +46,15 @@ func (t *Ticker) Stop() {
|
||||
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
|
||||
// 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
|
||||
|
@ -36,13 +36,17 @@ func TestTicker(t *testing.T) {
|
||||
for i := 0; i < 5; i++ {
|
||||
ticker := NewTicker(delta)
|
||||
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.Stop()
|
||||
t1 := Now()
|
||||
dt := t1.Sub(t0)
|
||||
target := delta * Duration(count)
|
||||
target := 3 * delta * Duration(count/2)
|
||||
slop := target * 2 / 10
|
||||
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))
|
||||
@ -118,3 +122,24 @@ func BenchmarkTicker(b *testing.B) {
|
||||
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 New Issue
Block a user