Daily bump.
[official-gcc.git] / libgo / go / time / sleep_test.go
blobcb09a84469ee4a771dbe69453ba1d8e571fc0dff
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 "sync"
13 "sync/atomic"
14 "testing"
15 . "time"
18 func TestSleep(t *testing.T) {
19 const delay = 100 * Millisecond
20 go func() {
21 Sleep(delay / 2)
22 Interrupt()
23 }()
24 start := Now()
25 Sleep(delay)
26 duration := Now().Sub(start)
27 if duration < delay {
28 t.Fatalf("Sleep(%s) slept for only %s", delay, duration)
32 // Test the basic function calling behavior. Correct queueing
33 // behavior is tested elsewhere, since After and AfterFunc share
34 // the same code.
35 func TestAfterFunc(t *testing.T) {
36 i := 10
37 c := make(chan bool)
38 var f func()
39 f = func() {
40 i--
41 if i >= 0 {
42 AfterFunc(0, f)
43 Sleep(1 * Second)
44 } else {
45 c <- true
49 AfterFunc(0, f)
50 <-c
53 func TestAfterStress(t *testing.T) {
54 stop := uint32(0)
55 go func() {
56 for atomic.LoadUint32(&stop) == 0 {
57 runtime.GC()
58 // Yield so that the OS can wake up the timer thread,
59 // so that it can generate channel sends for the main goroutine,
60 // which will eventually set stop = 1 for us.
61 Sleep(Nanosecond)
63 }()
64 ticker := NewTicker(1)
65 for i := 0; i < 100; i++ {
66 <-ticker.C
68 ticker.Stop()
69 atomic.StoreUint32(&stop, 1)
72 func benchmark(b *testing.B, bench func(n int)) {
73 garbage := make([]*Timer, 1<<17)
74 for i := 0; i < len(garbage); i++ {
75 garbage[i] = AfterFunc(Hour, nil)
78 const batch = 1000
79 P := runtime.GOMAXPROCS(-1)
80 N := int32(b.N / batch)
82 b.ResetTimer()
84 var wg sync.WaitGroup
85 wg.Add(P)
87 for p := 0; p < P; p++ {
88 go func() {
89 for atomic.AddInt32(&N, -1) >= 0 {
90 bench(batch)
92 wg.Done()
93 }()
96 wg.Wait()
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 if duration := Now().Sub(start); duration < delay {
167 t.Fatalf("After(%s) slept for only %d ns", delay, duration)
169 if min := start.Add(delay); end.Before(min) {
170 t.Fatalf("After(%s) expect >= %s, got %s", delay, min, end)
174 func TestAfterTick(t *testing.T) {
175 const Count = 10
176 Delta := 100 * Millisecond
177 if testing.Short() {
178 Delta = 10 * Millisecond
180 t0 := Now()
181 for i := 0; i < Count; i++ {
182 <-After(Delta)
184 t1 := Now()
185 d := t1.Sub(t0)
186 target := Delta * Count
187 if d < target*9/10 {
188 t.Fatalf("%d ticks of %s too fast: took %s, expected %s", Count, Delta, d, target)
190 if !testing.Short() && d > target*30/10 {
191 t.Fatalf("%d ticks of %s too slow: took %s, expected %s", Count, Delta, d, target)
195 func TestAfterStop(t *testing.T) {
196 AfterFunc(100*Millisecond, func() {})
197 t0 := NewTimer(50 * Millisecond)
198 c1 := make(chan bool, 1)
199 t1 := AfterFunc(150*Millisecond, func() { c1 <- true })
200 c2 := After(200 * Millisecond)
201 if !t0.Stop() {
202 t.Fatalf("failed to stop event 0")
204 if !t1.Stop() {
205 t.Fatalf("failed to stop event 1")
207 <-c2
208 select {
209 case <-t0.C:
210 t.Fatalf("event 0 was not stopped")
211 case <-c1:
212 t.Fatalf("event 1 was not stopped")
213 default:
215 if t1.Stop() {
216 t.Fatalf("Stop returned true twice")
220 func TestAfterQueuing(t *testing.T) {
221 // This test flakes out on some systems,
222 // so we'll try it a few times before declaring it a failure.
223 const attempts = 3
224 err := errors.New("!=nil")
225 for i := 0; i < attempts && err != nil; i++ {
226 if err = testAfterQueuing(t); err != nil {
227 t.Logf("attempt %v failed: %v", i, err)
230 if err != nil {
231 t.Fatal(err)
235 // For gccgo omit 0 for now because it can take too long to start the
236 var slots = []int{5, 3, 6, 6, 6, 1, 1, 2, 7, 9, 4, 8 /*0*/}
238 type afterResult struct {
239 slot int
240 t Time
243 func await(slot int, result chan<- afterResult, ac <-chan Time) {
244 result <- afterResult{slot, <-ac}
247 func testAfterQueuing(t *testing.T) error {
248 Delta := 100 * Millisecond
249 if testing.Short() {
250 Delta = 20 * Millisecond
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))
257 t0 := Now()
258 for _, slot := range slots {
259 go await(slot, result, After(Duration(slot)*Delta))
261 sort.Ints(slots)
262 for _, slot := range slots {
263 r := <-result
264 if r.slot != slot {
265 return fmt.Errorf("after slot %d, expected %d", r.slot, slot)
267 dt := r.t.Sub(t0)
268 target := Duration(slot) * Delta
269 if dt < target-Delta/2 || dt > target+Delta*10 {
270 return fmt.Errorf("After(%s) arrived at %s, expected [%s,%s]", target, dt, target-Delta/2, target+Delta*10)
273 return nil
276 func TestTimerStopStress(t *testing.T) {
277 if testing.Short() {
278 return
280 for i := 0; i < 100; i++ {
281 go func(i int) {
282 timer := AfterFunc(2*Second, func() {
283 t.Fatalf("timer %d was not stopped", i)
285 Sleep(1 * Second)
286 timer.Stop()
287 }(i)
289 Sleep(3 * Second)
292 func TestSleepZeroDeadlock(t *testing.T) {
293 // Sleep(0) used to hang, the sequence of events was as follows.
294 // Sleep(0) sets G's status to Gwaiting, but then immediately returns leaving the status.
295 // Then the goroutine calls e.g. new and falls down into the scheduler due to pending GC.
296 // After the GC nobody wakes up the goroutine from Gwaiting status.
297 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
298 c := make(chan bool)
299 go func() {
300 for i := 0; i < 100; i++ {
301 runtime.GC()
303 c <- true
305 for i := 0; i < 100; i++ {
306 Sleep(0)
307 tmp := make(chan bool, 1)
308 tmp <- true
309 <-tmp
314 func testReset(d Duration) error {
315 t0 := NewTimer(2 * d)
316 Sleep(d)
317 if t0.Reset(3*d) != true {
318 return errors.New("resetting unfired timer returned false")
320 Sleep(2 * d)
321 select {
322 case <-t0.C:
323 return errors.New("timer fired early")
324 default:
326 Sleep(2 * d)
327 select {
328 case <-t0.C:
329 default:
330 return errors.New("reset timer did not fire")
333 if t0.Reset(50*Millisecond) != false {
334 return errors.New("resetting expired timer returned true")
336 return nil
339 func TestReset(t *testing.T) {
340 // We try to run this test with increasingly larger multiples
341 // until one works so slow, loaded hardware isn't as flaky,
342 // but without slowing down fast machines unnecessarily.
343 const unit = 25 * Millisecond
344 tries := []Duration{
345 1 * unit,
346 3 * unit,
347 7 * unit,
348 15 * unit,
350 var err error
351 for _, d := range tries {
352 err = testReset(d)
353 if err == nil {
354 t.Logf("passed using duration %v", d)
355 return
358 t.Error(err)
361 // Test that sleeping for an interval so large it overflows does not
362 // result in a short sleep duration.
363 func TestOverflowSleep(t *testing.T) {
364 const timeout = 25 * Millisecond
365 const big = Duration(int64(1<<63 - 1))
366 select {
367 case <-After(big):
368 t.Fatalf("big timeout fired")
369 case <-After(timeout):
370 // OK
372 const neg = Duration(-1 << 63)
373 select {
374 case <-After(neg):
375 // OK
376 case <-After(timeout):
377 t.Fatalf("negative timeout didn't fire")
381 // Test that a panic while deleting a timer does not leave
382 // the timers mutex held, deadlocking a ticker.Stop in a defer.
383 func TestIssue5745(t *testing.T) {
384 ticker := NewTicker(Hour)
385 defer func() {
386 // would deadlock here before the fix due to
387 // lock taken before the segfault.
388 ticker.Stop()
390 if r := recover(); r == nil {
391 t.Error("Expected panic, but none happened.")
395 // cause a panic due to a segfault
396 var timer *Timer
397 timer.Stop()
398 t.Error("Should be unreachable.")
401 func TestOverflowRuntimeTimer(t *testing.T) {
402 if err := CheckRuntimeTimerOverflow(); err != nil {
403 t.Fatalf(err.Error())