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.
19 // Go runtime uses different Windows timers for time.Now and sleeping.
20 // These can tick at different frequencies and can arrive out of sync.
21 // The effect can be seen, for example, as time.Sleep(100ms) is actually
22 // shorter then 100ms when measured as difference between time.Now before and
23 // after time.Sleep call. This was observed on Windows XP SP3 (windows/386).
24 // windowsInaccuracy is to ignore such errors.
25 const windowsInaccuracy
= 17 * Millisecond
27 func TestSleep(t
*testing
.T
) {
28 const delay
= 100 * Millisecond
36 if runtime
.GOOS
== "windows" {
37 delayadj
-= windowsInaccuracy
39 duration
:= Now().Sub(start
)
40 if duration
< delayadj
{
41 t
.Fatalf("Sleep(%s) slept for only %s", delay
, duration
)
45 // Test the basic function calling behavior. Correct queueing
46 // behavior is tested elsewhere, since After and AfterFunc share
48 func TestAfterFunc(t
*testing
.T
) {
66 func TestAfterStress(t
*testing
.T
) {
69 for atomic
.LoadUint32(&stop
) == 0 {
71 // Yield so that the OS can wake up the timer thread,
72 // so that it can generate channel sends for the main goroutine,
73 // which will eventually set stop = 1 for us.
77 ticker
:= NewTicker(1)
78 for i
:= 0; i
< 100; i
++ {
82 atomic
.StoreUint32(&stop
, 1)
85 func benchmark(b
*testing
.B
, bench
func(n
int)) {
86 garbage
:= make([]*Timer
, 1<<17)
87 for i
:= 0; i
< len(garbage
); i
++ {
88 garbage
[i
] = AfterFunc(Hour
, nil)
92 b
.RunParallel(func(pb
*testing
.PB
) {
99 for i
:= 0; i
< len(garbage
); i
++ {
104 func BenchmarkAfterFunc(b
*testing
.B
) {
105 benchmark(b
, func(n
int) {
122 func BenchmarkAfter(b
*testing
.B
) {
123 benchmark(b
, func(n
int) {
124 for i
:= 0; i
< n
; i
++ {
130 func BenchmarkStop(b
*testing
.B
) {
131 benchmark(b
, func(n
int) {
132 for i
:= 0; i
< n
; i
++ {
133 NewTimer(1 * Second
).Stop()
138 func BenchmarkSimultaneousAfterFunc(b
*testing
.B
) {
139 benchmark(b
, func(n
int) {
140 var wg sync
.WaitGroup
142 for i
:= 0; i
< n
; i
++ {
143 AfterFunc(0, wg
.Done
)
149 func BenchmarkStartStop(b
*testing
.B
) {
150 benchmark(b
, func(n
int) {
151 timers
:= make([]*Timer
, n
)
152 for i
:= 0; i
< n
; i
++ {
153 timers
[i
] = AfterFunc(Hour
, nil)
156 for i
:= 0; i
< n
; i
++ {
162 func TestAfter(t
*testing
.T
) {
163 const delay
= 100 * Millisecond
165 end
:= <-After(delay
)
167 if runtime
.GOOS
== "windows" {
168 delayadj
-= windowsInaccuracy
170 if duration
:= Now().Sub(start
); duration
< delayadj
{
171 t
.Fatalf("After(%s) slept for only %d ns", delay
, duration
)
173 if min
:= start
.Add(delayadj
); end
.Before(min
) {
174 t
.Fatalf("After(%s) expect >= %s, got %s", delay
, min
, end
)
178 func TestAfterTick(t
*testing
.T
) {
180 Delta
:= 100 * Millisecond
182 Delta
= 10 * Millisecond
185 for i
:= 0; i
< Count
; i
++ {
190 target
:= Delta
* Count
192 t
.Fatalf("%d ticks of %s too fast: took %s, expected %s", Count
, Delta
, d
, target
)
194 if !testing
.Short() && d
> target
*30/10 {
195 t
.Fatalf("%d ticks of %s too slow: took %s, expected %s", Count
, Delta
, d
, target
)
199 func TestAfterStop(t
*testing
.T
) {
200 AfterFunc(100*Millisecond
, func() {})
201 t0
:= NewTimer(50 * Millisecond
)
202 c1
:= make(chan bool, 1)
203 t1
:= AfterFunc(150*Millisecond
, func() { c1
<- true })
204 c2
:= After(200 * Millisecond
)
206 t
.Fatalf("failed to stop event 0")
209 t
.Fatalf("failed to stop event 1")
214 t
.Fatalf("event 0 was not stopped")
216 t
.Fatalf("event 1 was not stopped")
220 t
.Fatalf("Stop returned true twice")
224 func TestAfterQueuing(t
*testing
.T
) {
225 // This test flakes out on some systems,
226 // so we'll try it a few times before declaring it a failure.
228 err
:= errors
.New("!=nil")
229 for i
:= 0; i
< attempts
&& err
!= nil; i
++ {
230 if err
= testAfterQueuing(t
); err
!= nil {
231 t
.Logf("attempt %v failed: %v", i
, err
)
239 // For gccgo omit 0 for now because it can take too long to start the
240 var slots
= []int{5, 3, 6, 6, 6, 1, 1, 2, 7, 9, 4, 8 /*0*/}
242 type afterResult
struct {
247 func await(slot
int, result
chan<- afterResult
, ac
<-chan Time
) {
248 result
<- afterResult
{slot
, <-ac
}
251 func testAfterQueuing(t
*testing
.T
) error
{
252 Delta
:= 100 * Millisecond
254 Delta
= 20 * Millisecond
256 // make the result channel buffered because we don't want
257 // to depend on channel queueing semantics that might
258 // possibly change in the future.
259 result
:= make(chan afterResult
, len(slots
))
262 for _
, slot
:= range slots
{
263 go await(slot
, result
, After(Duration(slot
)*Delta
))
266 for _
, slot
:= range slots
{
269 return fmt
.Errorf("after slot %d, expected %d", r
.slot
, slot
)
272 target
:= Duration(slot
) * Delta
273 if dt
< target
-Delta
/2 || dt
> target
+Delta
*10 {
274 return fmt
.Errorf("After(%s) arrived at %s, expected [%s,%s]", target
, dt
, target
-Delta
/2, target
+Delta
*10)
280 func TestTimerStopStress(t
*testing
.T
) {
284 for i
:= 0; i
< 100; i
++ {
286 timer
:= AfterFunc(2*Second
, func() {
287 t
.Fatalf("timer %d was not stopped", i
)
296 func TestSleepZeroDeadlock(t
*testing
.T
) {
297 // Sleep(0) used to hang, the sequence of events was as follows.
298 // Sleep(0) sets G's status to Gwaiting, but then immediately returns leaving the status.
299 // Then the goroutine calls e.g. new and falls down into the scheduler due to pending GC.
300 // After the GC nobody wakes up the goroutine from Gwaiting status.
301 defer runtime
.GOMAXPROCS(runtime
.GOMAXPROCS(4))
304 for i
:= 0; i
< 100; i
++ {
309 for i
:= 0; i
< 100; i
++ {
311 tmp
:= make(chan bool, 1)
318 func testReset(d Duration
) error
{
319 t0
:= NewTimer(2 * d
)
321 if t0
.Reset(3*d
) != true {
322 return errors
.New("resetting unfired timer returned false")
327 return errors
.New("timer fired early")
334 return errors
.New("reset timer did not fire")
337 if t0
.Reset(50*Millisecond
) != false {
338 return errors
.New("resetting expired timer returned true")
343 func TestReset(t
*testing
.T
) {
344 // We try to run this test with increasingly larger multiples
345 // until one works so slow, loaded hardware isn't as flaky,
346 // but without slowing down fast machines unnecessarily.
347 const unit
= 25 * Millisecond
355 for _
, d
:= range tries
{
358 t
.Logf("passed using duration %v", d
)
365 // Test that sleeping for an interval so large it overflows does not
366 // result in a short sleep duration.
367 func TestOverflowSleep(t
*testing
.T
) {
368 const big
= Duration(int64(1<<63 - 1))
371 t
.Fatalf("big timeout fired")
372 case <-After(25 * Millisecond
):
375 const neg
= Duration(-1 << 63)
379 case <-After(1 * Second
):
380 t
.Fatalf("negative timeout didn't fire")
384 // Test that a panic while deleting a timer does not leave
385 // the timers mutex held, deadlocking a ticker.Stop in a defer.
386 func TestIssue5745(t
*testing
.T
) {
387 ticker
:= NewTicker(Hour
)
389 // would deadlock here before the fix due to
390 // lock taken before the segfault.
393 if r
:= recover(); r
== nil {
394 t
.Error("Expected panic, but none happened.")
398 // cause a panic due to a segfault
401 t
.Error("Should be unreachable.")
404 func TestOverflowRuntimeTimer(t
*testing
.T
) {
406 t
.Skip("skipping in short mode, see issue 6874")
408 // This may hang forever if timers are broken. See comment near
409 // the end of CheckRuntimeTimerOverflow in internal_test.go.
410 CheckRuntimeTimerOverflow()
413 func checkZeroPanicString(t
*testing
.T
) {
416 if want
:= "called on uninitialized Timer"; !strings
.Contains(s
, want
) {
417 t
.Errorf("panic = %v; want substring %q", e
, want
)
421 func TestZeroTimerResetPanics(t
*testing
.T
) {
422 defer checkZeroPanicString(t
)
427 func TestZeroTimerStopPanics(t
*testing
.T
) {
428 defer checkZeroPanicString(t
)