syscall: RawSockaddr fix for ppc64, ppc64le
[official-gcc.git] / libgo / go / sync / waitgroup_test.go
blob4c0a043c01ee7d6ce058c59032e4ade62075e6b0
1 // Copyright 2011 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 sync_test
7 import (
8 . "sync"
9 "sync/atomic"
10 "testing"
13 func testWaitGroup(t *testing.T, wg1 *WaitGroup, wg2 *WaitGroup) {
14 n := 16
15 wg1.Add(n)
16 wg2.Add(n)
17 exited := make(chan bool, n)
18 for i := 0; i != n; i++ {
19 go func(i int) {
20 wg1.Done()
21 wg2.Wait()
22 exited <- true
23 }(i)
25 wg1.Wait()
26 for i := 0; i != n; i++ {
27 select {
28 case <-exited:
29 t.Fatal("WaitGroup released group too soon")
30 default:
32 wg2.Done()
34 for i := 0; i != n; i++ {
35 <-exited // Will block if barrier fails to unlock someone.
39 func TestWaitGroup(t *testing.T) {
40 wg1 := &WaitGroup{}
41 wg2 := &WaitGroup{}
43 // Run the same test a few times to ensure barrier is in a proper state.
44 for i := 0; i != 8; i++ {
45 testWaitGroup(t, wg1, wg2)
49 func TestWaitGroupMisuse(t *testing.T) {
50 defer func() {
51 err := recover()
52 if err != "sync: negative WaitGroup counter" {
53 t.Fatalf("Unexpected panic: %#v", err)
55 }()
56 wg := &WaitGroup{}
57 wg.Add(1)
58 wg.Done()
59 wg.Done()
60 t.Fatal("Should panic")
63 func TestWaitGroupRace(t *testing.T) {
64 // Run this test for about 1ms.
65 for i := 0; i < 1000; i++ {
66 wg := &WaitGroup{}
67 n := new(int32)
68 // spawn goroutine 1
69 wg.Add(1)
70 go func() {
71 atomic.AddInt32(n, 1)
72 wg.Done()
73 }()
74 // spawn goroutine 2
75 wg.Add(1)
76 go func() {
77 atomic.AddInt32(n, 1)
78 wg.Done()
79 }()
80 // Wait for goroutine 1 and 2
81 wg.Wait()
82 if atomic.LoadInt32(n) != 2 {
83 t.Fatal("Spurious wakeup from Wait")
88 func BenchmarkWaitGroupUncontended(b *testing.B) {
89 type PaddedWaitGroup struct {
90 WaitGroup
91 pad [128]uint8
93 b.RunParallel(func(pb *testing.PB) {
94 var wg PaddedWaitGroup
95 for pb.Next() {
96 wg.Add(1)
97 wg.Done()
98 wg.Wait()
103 func benchmarkWaitGroupAddDone(b *testing.B, localWork int) {
104 var wg WaitGroup
105 b.RunParallel(func(pb *testing.PB) {
106 foo := 0
107 for pb.Next() {
108 wg.Add(1)
109 for i := 0; i < localWork; i++ {
110 foo *= 2
111 foo /= 2
113 wg.Done()
115 _ = foo
119 func BenchmarkWaitGroupAddDone(b *testing.B) {
120 benchmarkWaitGroupAddDone(b, 0)
123 func BenchmarkWaitGroupAddDoneWork(b *testing.B) {
124 benchmarkWaitGroupAddDone(b, 100)
127 func benchmarkWaitGroupWait(b *testing.B, localWork int) {
128 var wg WaitGroup
129 b.RunParallel(func(pb *testing.PB) {
130 foo := 0
131 for pb.Next() {
132 wg.Wait()
133 for i := 0; i < localWork; i++ {
134 foo *= 2
135 foo /= 2
138 _ = foo
142 func BenchmarkWaitGroupWait(b *testing.B) {
143 benchmarkWaitGroupWait(b, 0)
146 func BenchmarkWaitGroupWaitWork(b *testing.B) {
147 benchmarkWaitGroupWait(b, 100)