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.
18 // Go runtime uses different Windows timers for time.Now and sleeping.
19 // These can tick at different frequencies and can arrive out of sync.
20 // The effect can be seen, for example, as time.Sleep(100ms) is actually
21 // shorter then 100ms when measured as difference between time.Now before and
22 // after time.Sleep call. This was observed on Windows XP SP3 (windows/386).
23 // windowsInaccuracy is to ignore such errors.
24 const windowsInaccuracy
= 17 * Millisecond
26 func TestSleep(t
*testing
.T
) {
27 const delay
= 100 * Millisecond
35 if runtime
.GOOS
== "windows" {
36 delayadj
-= windowsInaccuracy
38 duration
:= Now().Sub(start
)
39 if duration
< delayadj
{
40 t
.Fatalf("Sleep(%s) slept for only %s", delay
, duration
)
44 // Test the basic function calling behavior. Correct queueing
45 // behavior is tested elsewhere, since After and AfterFunc share
47 func TestAfterFunc(t
*testing
.T
) {
65 func TestAfterStress(t
*testing
.T
) {
68 for atomic
.LoadUint32(&stop
) == 0 {
70 // Yield so that the OS can wake up the timer thread,
71 // so that it can generate channel sends for the main goroutine,
72 // which will eventually set stop = 1 for us.
76 ticker
:= NewTicker(1)
77 for i
:= 0; i
< 100; i
++ {
81 atomic
.StoreUint32(&stop
, 1)
84 func benchmark(b
*testing
.B
, bench
func(n
int)) {
85 garbage
:= make([]*Timer
, 1<<17)
86 for i
:= 0; i
< len(garbage
); i
++ {
87 garbage
[i
] = AfterFunc(Hour
, nil)
91 b
.RunParallel(func(pb
*testing
.PB
) {
98 for i
:= 0; i
< len(garbage
); i
++ {
103 func BenchmarkAfterFunc(b
*testing
.B
) {
104 benchmark(b
, func(n
int) {
121 func BenchmarkAfter(b
*testing
.B
) {
122 benchmark(b
, func(n
int) {
123 for i
:= 0; i
< n
; i
++ {
129 func BenchmarkStop(b
*testing
.B
) {
130 benchmark(b
, func(n
int) {
131 for i
:= 0; i
< n
; i
++ {
132 NewTimer(1 * Second
).Stop()
137 func BenchmarkSimultaneousAfterFunc(b
*testing
.B
) {
138 benchmark(b
, func(n
int) {
139 var wg sync
.WaitGroup
141 for i
:= 0; i
< n
; i
++ {
142 AfterFunc(0, wg
.Done
)
148 func BenchmarkStartStop(b
*testing
.B
) {
149 benchmark(b
, func(n
int) {
150 timers
:= make([]*Timer
, n
)
151 for i
:= 0; i
< n
; i
++ {
152 timers
[i
] = AfterFunc(Hour
, nil)
155 for i
:= 0; i
< n
; i
++ {
161 func TestAfter(t
*testing
.T
) {
162 const delay
= 100 * Millisecond
164 end
:= <-After(delay
)
166 if runtime
.GOOS
== "windows" {
167 delayadj
-= windowsInaccuracy
169 if duration
:= Now().Sub(start
); duration
< delayadj
{
170 t
.Fatalf("After(%s) slept for only %d ns", delay
, duration
)
172 if min
:= start
.Add(delayadj
); end
.Before(min
) {
173 t
.Fatalf("After(%s) expect >= %s, got %s", delay
, min
, end
)
177 func TestAfterTick(t
*testing
.T
) {
179 Delta
:= 100 * Millisecond
181 Delta
= 10 * Millisecond
184 for i
:= 0; i
< Count
; i
++ {
189 target
:= Delta
* Count
191 t
.Fatalf("%d ticks of %s too fast: took %s, expected %s", Count
, Delta
, d
, target
)
193 if !testing
.Short() && d
> target
*30/10 {
194 t
.Fatalf("%d ticks of %s too slow: took %s, expected %s", Count
, Delta
, d
, target
)
198 func TestAfterStop(t
*testing
.T
) {
199 AfterFunc(100*Millisecond
, func() {})
200 t0
:= NewTimer(50 * Millisecond
)
201 c1
:= make(chan bool, 1)
202 t1
:= AfterFunc(150*Millisecond
, func() { c1
<- true })
203 c2
:= After(200 * Millisecond
)
205 t
.Fatalf("failed to stop event 0")
208 t
.Fatalf("failed to stop event 1")
213 t
.Fatalf("event 0 was not stopped")
215 t
.Fatalf("event 1 was not stopped")
219 t
.Fatalf("Stop returned true twice")
223 func TestAfterQueuing(t
*testing
.T
) {
224 // This test flakes out on some systems,
225 // so we'll try it a few times before declaring it a failure.
227 err
:= errors
.New("!=nil")
228 for i
:= 0; i
< attempts
&& err
!= nil; i
++ {
229 delta
:= Duration(20+i
*50) * Millisecond
230 if err
= testAfterQueuing(t
, delta
); 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
, delta Duration
) error
{
252 // make the result channel buffered because we don't want
253 // to depend on channel queueing semantics that might
254 // possibly change in the future.
255 result
:= make(chan afterResult
, len(slots
))
258 for _
, slot
:= range slots
{
259 go await(slot
, result
, After(Duration(slot
)*delta
))
265 order
= append(order
, r
.slot
)
266 times
= append(times
, r
.t
)
268 for i
:= range order
{
269 if i
> 0 && order
[i
] < order
[i
-1] {
270 return fmt
.Errorf("After calls returned out of order: %v", order
)
273 for i
, t
:= range times
{
275 target
:= Duration(order
[i
]) * delta
276 if dt
< target
-delta
/2 || dt
> target
+delta
*10 {
277 return fmt
.Errorf("After(%s) arrived at %s, expected [%s,%s]", target
, dt
, target
-delta
/2, target
+delta
*10)
283 func TestTimerStopStress(t
*testing
.T
) {
287 for i
:= 0; i
< 100; i
++ {
289 timer
:= AfterFunc(2*Second
, func() {
290 t
.Fatalf("timer %d was not stopped", i
)
299 func TestSleepZeroDeadlock(t
*testing
.T
) {
300 // Sleep(0) used to hang, the sequence of events was as follows.
301 // Sleep(0) sets G's status to Gwaiting, but then immediately returns leaving the status.
302 // Then the goroutine calls e.g. new and falls down into the scheduler due to pending GC.
303 // After the GC nobody wakes up the goroutine from Gwaiting status.
304 defer runtime
.GOMAXPROCS(runtime
.GOMAXPROCS(4))
307 for i
:= 0; i
< 100; i
++ {
312 for i
:= 0; i
< 100; i
++ {
314 tmp
:= make(chan bool, 1)
321 func testReset(d Duration
) error
{
322 t0
:= NewTimer(2 * d
)
324 if t0
.Reset(3*d
) != true {
325 return errors
.New("resetting unfired timer returned false")
330 return errors
.New("timer fired early")
337 return errors
.New("reset timer did not fire")
340 if t0
.Reset(50*Millisecond
) != false {
341 return errors
.New("resetting expired timer returned true")
346 func TestReset(t
*testing
.T
) {
347 // We try to run this test with increasingly larger multiples
348 // until one works so slow, loaded hardware isn't as flaky,
349 // but without slowing down fast machines unnecessarily.
350 const unit
= 25 * Millisecond
358 for _
, d
:= range tries
{
361 t
.Logf("passed using duration %v", d
)
368 // Test that sleeping for an interval so large it overflows does not
369 // result in a short sleep duration.
370 func TestOverflowSleep(t
*testing
.T
) {
371 const big
= Duration(int64(1<<63 - 1))
374 t
.Fatalf("big timeout fired")
375 case <-After(25 * Millisecond
):
378 const neg
= Duration(-1 << 63)
382 case <-After(1 * Second
):
383 t
.Fatalf("negative timeout didn't fire")
387 // Test that a panic while deleting a timer does not leave
388 // the timers mutex held, deadlocking a ticker.Stop in a defer.
389 func TestIssue5745(t
*testing
.T
) {
390 if runtime
.GOOS
== "darwin" && runtime
.GOARCH
== "arm" {
391 t
.Skipf("skipping on %s/%s, see issue 10043", runtime
.GOOS
, runtime
.GOARCH
)
394 ticker
:= NewTicker(Hour
)
396 // would deadlock here before the fix due to
397 // lock taken before the segfault.
400 if r
:= recover(); r
== nil {
401 t
.Error("Expected panic, but none happened.")
405 // cause a panic due to a segfault
408 t
.Error("Should be unreachable.")
411 func TestOverflowRuntimeTimer(t
*testing
.T
) {
413 t
.Skip("skipping in short mode, see issue 6874")
415 // This may hang forever if timers are broken. See comment near
416 // the end of CheckRuntimeTimerOverflow in internal_test.go.
417 CheckRuntimeTimerOverflow()
420 func checkZeroPanicString(t
*testing
.T
) {
423 if want
:= "called on uninitialized Timer"; !strings
.Contains(s
, want
) {
424 t
.Errorf("panic = %v; want substring %q", e
, want
)
428 func TestZeroTimerResetPanics(t
*testing
.T
) {
429 defer checkZeroPanicString(t
)
434 func TestZeroTimerStopPanics(t
*testing
.T
) {
435 defer checkZeroPanicString(t
)