1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 5 package time
6 7 import (
8 "internal/godebug"
9 "unsafe"
10 )
11 12 // Sleep pauses the current goroutine for at least the duration d.
13 // A negative or zero duration causes Sleep to return immediately.
14 func Sleep(d Duration)
15 16 var asynctimerchan = godebug.New([]byte("asynctimerchan"))
17 18 // syncTimer returns c as an unsafe.Pointer, for passing to newTimer.
19 // If the GODEBUG asynctimerchan has disabled the async timer chan
20 // code, then syncTimer always returns nil, to disable the special
21 // channel code paths in the runtime.
22 func syncTimer(c chan Time) unsafe.Pointer {
23 // If asynctimerchan=1, we don't even tell the runtime
24 // about channel timers, so that we get the pre-Go 1.23 code paths.
25 if []byte(asynctimerchan.Value()) == "1" {
26 asynctimerchan.IncNonDefault()
27 return nil
28 }
29 30 // Otherwise pass to runtime.
31 // This handles asynctimerchan=0, which is the default Go 1.23 behavior,
32 // as well as asynctimerchan=2, which is like asynctimerchan=1
33 // but implemented entirely by the runtime.
34 // The only reason to use asynctimerchan=2 is for debugging
35 // a problem fixed by asynctimerchan=1: it enables the new
36 // GC-able timer channels (#61542) but not the sync channels (#37196).
37 //
38 // If we decide to roll back the sync channels, we will still have
39 // a fully tested async runtime implementation (asynctimerchan=2)
40 // and can make this function always return c.
41 //
42 // If we decide to keep the sync channels, we can delete all the
43 // handling of asynctimerchan in the runtime and keep just this
44 // function to handle asynctimerchan=1.
45 return *(*unsafe.Pointer)(unsafe.Pointer(&c))
46 }
47 48 // when is a helper function for setting the 'when' field of a runtimeTimer.
49 // It returns what the time will be, in nanoseconds, Duration d in the future.
50 // If d is negative, it is ignored. If the returned value would be less than
51 // zero because of an overflow, MaxInt64 is returned.
52 func when(d Duration) int64 {
53 if d <= 0 {
54 return runtimeNano()
55 }
56 t := runtimeNano() + int64(d)
57 if t < 0 {
58 // N.B. runtimeNano() and d are always positive, so addition
59 // (including overflow) will never result in t == 0.
60 t = 1<<63 - 1 // math.MaxInt64
61 }
62 return t
63 }
64 65 // These functions are pushed to package time from package runtime.
66 67 // The arg cp is a chan Time, but the declaration in runtime uses a pointer,
68 // so we use a pointer here too. This keeps some tools that aggressively
69 // compare linknamed symbol definitions happier.
70 //
71 //go:linkname newTimer
72 func newTimer(when, period int64, f func(any, uintptr, int64), arg any, cp unsafe.Pointer) *Timer
73 74 //go:linkname stopTimer
75 func stopTimer(*Timer) bool
76 77 //go:linkname resetTimer
78 func resetTimer(t *Timer, when, period int64) bool
79 80 // Note: The runtime knows the layout of struct Timer, since newTimer allocates it.
81 // The runtime also knows that Ticker and Timer have the same layout.
82 // There are extra fields after the channel, reserved for the runtime
83 // and inaccessible to users.
84 85 // The Timer type represents a single event.
86 // When the Timer expires, the current time will be sent on C,
87 // unless the Timer was created by [AfterFunc].
88 // A Timer must be created with [NewTimer] or AfterFunc.
89 type Timer struct {
90 C <-chan Time
91 initTimer bool
92 }
93 94 // Stop prevents the [Timer] from firing.
95 // It returns true if the call stops the timer, false if the timer has already
96 // expired or been stopped.
97 //
98 // For a func-based timer created with [AfterFunc](d, f),
99 // if t.Stop returns false, then the timer has already expired
100 // and the function f has been started in its own goroutine;
101 // Stop does not wait for f to complete before returning.
102 // If the caller needs to know whether f is completed,
103 // it must coordinate with f explicitly.
104 //
105 // For a chan-based timer created with NewTimer(d), as of Go 1.23,
106 // any receive from t.C after Stop has returned is guaranteed to block
107 // rather than receive a stale time value from before the Stop;
108 // if the program has not received from t.C already and the timer is
109 // running, Stop is guaranteed to return true.
110 // Before Go 1.23, the only safe way to use Stop was insert an extra
111 // <-t.C if Stop returned false to drain a potential stale value.
112 // See the [NewTimer] documentation for more details.
113 func (t *Timer) Stop() bool {
114 if !t.initTimer {
115 panic("time: Stop called on uninitialized Timer")
116 }
117 return stopTimer(t)
118 }
119 120 // NewTimer creates a new Timer that will send
121 // the current time on its channel after at least duration d.
122 //
123 // Before Go 1.23, the garbage collector did not recover
124 // timers that had not yet expired or been stopped, so code often
125 // immediately deferred t.Stop after calling NewTimer, to make
126 // the timer recoverable when it was no longer needed.
127 // As of Go 1.23, the garbage collector can recover unreferenced
128 // timers, even if they haven't expired or been stopped.
129 // The Stop method is no longer necessary to help the garbage collector.
130 // (Code may of course still want to call Stop to stop the timer for other reasons.)
131 //
132 // Before Go 1.23, the channel associated with a Timer was
133 // asynchronous (buffered, capacity 1), which meant that
134 // stale time values could be received even after [Timer.Stop]
135 // or [Timer.Reset] returned.
136 // As of Go 1.23, the channel is synchronous (unbuffered, capacity 0),
137 // eliminating the possibility of those stale values.
138 //
139 // The GODEBUG setting asynctimerchan=1 restores both pre-Go 1.23
140 // behaviors: when set, unexpired timers won't be garbage collected, and
141 // channels will have buffered capacity. This setting may be removed
142 // in Go 1.27 or later.
143 func NewTimer(d Duration) *Timer {
144 c := chan Time{1}
145 t := (*Timer)(newTimer(when(d), 0, sendTime, c, syncTimer(c)))
146 t.C = c
147 return t
148 }
149 150 // Reset changes the timer to expire after duration d.
151 // It returns true if the timer had been active, false if the timer had
152 // expired or been stopped.
153 //
154 // For a func-based timer created with [AfterFunc](d, f), Reset either reschedules
155 // when f will run, in which case Reset returns true, or schedules f
156 // to run again, in which case it returns false.
157 // When Reset returns false, Reset neither waits for the prior f to
158 // complete before returning nor does it guarantee that the subsequent
159 // goroutine running f does not run concurrently with the prior
160 // one. If the caller needs to know whether the prior execution of
161 // f is completed, it must coordinate with f explicitly.
162 //
163 // For a chan-based timer created with NewTimer, as of Go 1.23,
164 // any receive from t.C after Reset has returned is guaranteed not
165 // to receive a time value corresponding to the previous timer settings;
166 // if the program has not received from t.C already and the timer is
167 // running, Reset is guaranteed to return true.
168 // Before Go 1.23, the only safe way to use Reset was to call [Timer.Stop]
169 // and explicitly drain the timer first.
170 // See the [NewTimer] documentation for more details.
171 func (t *Timer) Reset(d Duration) bool {
172 if !t.initTimer {
173 panic("time: Reset called on uninitialized Timer")
174 }
175 w := when(d)
176 return resetTimer(t, w, 0)
177 }
178 179 // sendTime does a non-blocking send of the current time on c.
180 func sendTime(c any, seq uintptr, delta int64) {
181 // delta is how long ago the channel send was supposed to happen.
182 // The current time can be arbitrarily far into the future, because the runtime
183 // can delay a sendTime call until a goroutine tries to receive from
184 // the channel. Subtract delta to go back to the old time that we
185 // used to send.
186 select {
187 case c.(chan Time) <- Now().Add(Duration(-delta)):
188 default:
189 }
190 }
191 192 // After waits for the duration to elapse and then sends the current time
193 // on the returned channel.
194 // It is equivalent to [NewTimer](d).C.
195 //
196 // Before Go 1.23, this documentation warned that the underlying
197 // [Timer] would not be recovered by the garbage collector until the
198 // timer fired, and that if efficiency was a concern, code should use
199 // NewTimer instead and call [Timer.Stop] if the timer is no longer needed.
200 // As of Go 1.23, the garbage collector can recover unreferenced,
201 // unstopped timers. There is no reason to prefer NewTimer when After will do.
202 func After(d Duration) <-chan Time {
203 return NewTimer(d).C
204 }
205 206 // AfterFunc waits for the duration to elapse and then calls f
207 // in its own goroutine. It returns a [Timer] that can
208 // be used to cancel the call using its Stop method.
209 // The returned Timer's C field is not used and will be nil.
210 func AfterFunc(d Duration, f func()) *Timer {
211 return (*Timer)(newTimer(when(d), 0, goFunc, f, nil))
212 }
213 214 func goFunc(arg any, seq uintptr, delta int64) {
215 arg.(func())()
216 }
217