2015-03-13 Robert Dewar <dewar@adacore.com>
[official-gcc.git] / libgo / go / time / sleep_test.go
blobc21eb997dc4bac8d3d3f1d8945ff389bf0e9689f
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.
5 package time_test
7 import (
8 "errors"
9 "fmt"
10 "runtime"
11 "sort"
12 "strings"
13 "sync"
14 "sync/atomic"
15 "testing"
16 . "time"
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
29 go func() {
30 Sleep(delay / 2)
31 Interrupt()
32 }()
33 start := Now()
34 Sleep(delay)
35 delayadj := delay
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
47 // the same code.
48 func TestAfterFunc(t *testing.T) {
49 i := 10
50 c := make(chan bool)
51 var f func()
52 f = func() {
53 i--
54 if i >= 0 {
55 AfterFunc(0, f)
56 Sleep(1 * Second)
57 } else {
58 c <- true
62 AfterFunc(0, f)
63 <-c
66 func TestAfterStress(t *testing.T) {
67 stop := uint32(0)
68 go func() {
69 for atomic.LoadUint32(&stop) == 0 {
70 runtime.GC()
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.
74 Sleep(Nanosecond)
76 }()
77 ticker := NewTicker(1)
78 for i := 0; i < 100; i++ {
79 <-ticker.C
81 ticker.Stop()
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)
90 b.ResetTimer()
92 b.RunParallel(func(pb *testing.PB) {
93 for pb.Next() {
94 bench(1000)
98 b.StopTimer()
99 for i := 0; i < len(garbage); i++ {
100 garbage[i].Stop()
104 func BenchmarkAfterFunc(b *testing.B) {
105 benchmark(b, func(n int) {
106 c := make(chan bool)
107 var f func()
108 f = func() {
110 if n >= 0 {
111 AfterFunc(0, f)
112 } else {
113 c <- true
117 AfterFunc(0, f)
122 func BenchmarkAfter(b *testing.B) {
123 benchmark(b, func(n int) {
124 for i := 0; i < n; i++ {
125 <-After(1)
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
141 wg.Add(n)
142 for i := 0; i < n; i++ {
143 AfterFunc(0, wg.Done)
145 wg.Wait()
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++ {
157 timers[i].Stop()
162 func TestAfter(t *testing.T) {
163 const delay = 100 * Millisecond
164 start := Now()
165 end := <-After(delay)
166 delayadj := 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) {
179 const Count = 10
180 Delta := 100 * Millisecond
181 if testing.Short() {
182 Delta = 10 * Millisecond
184 t0 := Now()
185 for i := 0; i < Count; i++ {
186 <-After(Delta)
188 t1 := Now()
189 d := t1.Sub(t0)
190 target := Delta * Count
191 if d < target*9/10 {
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)
205 if !t0.Stop() {
206 t.Fatalf("failed to stop event 0")
208 if !t1.Stop() {
209 t.Fatalf("failed to stop event 1")
211 <-c2
212 select {
213 case <-t0.C:
214 t.Fatalf("event 0 was not stopped")
215 case <-c1:
216 t.Fatalf("event 1 was not stopped")
217 default:
219 if t1.Stop() {
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.
227 const attempts = 3
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)
234 if err != nil {
235 t.Fatal(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 {
243 slot int
244 t Time
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
253 if testing.Short() {
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))
261 t0 := Now()
262 for _, slot := range slots {
263 go await(slot, result, After(Duration(slot)*Delta))
265 sort.Ints(slots)
266 for _, slot := range slots {
267 r := <-result
268 if r.slot != slot {
269 return fmt.Errorf("after slot %d, expected %d", r.slot, slot)
271 dt := r.t.Sub(t0)
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)
277 return nil
280 func TestTimerStopStress(t *testing.T) {
281 if testing.Short() {
282 return
284 for i := 0; i < 100; i++ {
285 go func(i int) {
286 timer := AfterFunc(2*Second, func() {
287 t.Fatalf("timer %d was not stopped", i)
289 Sleep(1 * Second)
290 timer.Stop()
291 }(i)
293 Sleep(3 * Second)
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))
302 c := make(chan bool)
303 go func() {
304 for i := 0; i < 100; i++ {
305 runtime.GC()
307 c <- true
309 for i := 0; i < 100; i++ {
310 Sleep(0)
311 tmp := make(chan bool, 1)
312 tmp <- true
313 <-tmp
318 func testReset(d Duration) error {
319 t0 := NewTimer(2 * d)
320 Sleep(d)
321 if t0.Reset(3*d) != true {
322 return errors.New("resetting unfired timer returned false")
324 Sleep(2 * d)
325 select {
326 case <-t0.C:
327 return errors.New("timer fired early")
328 default:
330 Sleep(2 * d)
331 select {
332 case <-t0.C:
333 default:
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")
340 return nil
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
348 tries := []Duration{
349 1 * unit,
350 3 * unit,
351 7 * unit,
352 15 * unit,
354 var err error
355 for _, d := range tries {
356 err = testReset(d)
357 if err == nil {
358 t.Logf("passed using duration %v", d)
359 return
362 t.Error(err)
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))
369 select {
370 case <-After(big):
371 t.Fatalf("big timeout fired")
372 case <-After(25 * Millisecond):
373 // OK
375 const neg = Duration(-1 << 63)
376 select {
377 case <-After(neg):
378 // OK
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)
388 defer func() {
389 // would deadlock here before the fix due to
390 // lock taken before the segfault.
391 ticker.Stop()
393 if r := recover(); r == nil {
394 t.Error("Expected panic, but none happened.")
398 // cause a panic due to a segfault
399 var timer *Timer
400 timer.Stop()
401 t.Error("Should be unreachable.")
404 func TestOverflowRuntimeTimer(t *testing.T) {
405 if testing.Short() {
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) {
414 e := recover()
415 s, _ := e.(string)
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)
423 var tr Timer
424 tr.Reset(1)
427 func TestZeroTimerStopPanics(t *testing.T) {
428 defer checkZeroPanicString(t)
429 var tr Timer
430 tr.Stop()