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