Fortran: fix ALLOCATE with SOURCE of deferred character length [PR114019]
[official-gcc.git] / libgo / go / sync / rwmutex_test.go
blobdfbdd9bbeef706afd38ef510019187f824f527ab
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 // GOMAXPROCS=10 go test
7 package sync_test
9 import (
10 "fmt"
11 "runtime"
12 . "sync"
13 "sync/atomic"
14 "testing"
17 // There is a modified copy of this file in runtime/rwmutex_test.go.
18 // If you make any changes here, see if you should make them there.
20 func parallelReader(m *RWMutex, clocked, cunlock, cdone chan bool) {
21 m.RLock()
22 clocked <- true
23 <-cunlock
24 m.RUnlock()
25 cdone <- true
28 func doTestParallelReaders(numReaders, gomaxprocs int) {
29 runtime.GOMAXPROCS(gomaxprocs)
30 var m RWMutex
31 clocked := make(chan bool)
32 cunlock := make(chan bool)
33 cdone := make(chan bool)
34 for i := 0; i < numReaders; i++ {
35 go parallelReader(&m, clocked, cunlock, cdone)
37 // Wait for all parallel RLock()s to succeed.
38 for i := 0; i < numReaders; i++ {
39 <-clocked
41 for i := 0; i < numReaders; i++ {
42 cunlock <- true
44 // Wait for the goroutines to finish.
45 for i := 0; i < numReaders; i++ {
46 <-cdone
50 func TestParallelReaders(t *testing.T) {
51 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(-1))
52 doTestParallelReaders(1, 4)
53 doTestParallelReaders(3, 4)
54 doTestParallelReaders(4, 2)
57 func reader(rwm *RWMutex, num_iterations int, activity *int32, cdone chan bool) {
58 for i := 0; i < num_iterations; i++ {
59 rwm.RLock()
60 n := atomic.AddInt32(activity, 1)
61 if n < 1 || n >= 10000 {
62 rwm.RUnlock()
63 panic(fmt.Sprintf("wlock(%d)\n", n))
65 for i := 0; i < 100; i++ {
67 atomic.AddInt32(activity, -1)
68 rwm.RUnlock()
70 cdone <- true
73 func writer(rwm *RWMutex, num_iterations int, activity *int32, cdone chan bool) {
74 for i := 0; i < num_iterations; i++ {
75 rwm.Lock()
76 n := atomic.AddInt32(activity, 10000)
77 if n != 10000 {
78 rwm.Unlock()
79 panic(fmt.Sprintf("wlock(%d)\n", n))
81 for i := 0; i < 100; i++ {
83 atomic.AddInt32(activity, -10000)
84 rwm.Unlock()
86 cdone <- true
89 func HammerRWMutex(gomaxprocs, numReaders, num_iterations int) {
90 runtime.GOMAXPROCS(gomaxprocs)
91 // Number of active readers + 10000 * number of active writers.
92 var activity int32
93 var rwm RWMutex
94 cdone := make(chan bool)
95 go writer(&rwm, num_iterations, &activity, cdone)
96 var i int
97 for i = 0; i < numReaders/2; i++ {
98 go reader(&rwm, num_iterations, &activity, cdone)
100 go writer(&rwm, num_iterations, &activity, cdone)
101 for ; i < numReaders; i++ {
102 go reader(&rwm, num_iterations, &activity, cdone)
104 // Wait for the 2 writers and all readers to finish.
105 for i := 0; i < 2+numReaders; i++ {
106 <-cdone
110 func TestRWMutex(t *testing.T) {
111 var m RWMutex
113 m.Lock()
114 if m.TryLock() {
115 t.Fatalf("TryLock succeeded with mutex locked")
117 if m.TryRLock() {
118 t.Fatalf("TryRLock succeeded with mutex locked")
120 m.Unlock()
122 if !m.TryLock() {
123 t.Fatalf("TryLock failed with mutex unlocked")
125 m.Unlock()
127 if !m.TryRLock() {
128 t.Fatalf("TryRLock failed with mutex unlocked")
130 if !m.TryRLock() {
131 t.Fatalf("TryRLock failed with mutex rlocked")
133 if m.TryLock() {
134 t.Fatalf("TryLock succeeded with mutex rlocked")
136 m.RUnlock()
137 m.RUnlock()
139 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(-1))
140 n := 1000
141 if testing.Short() {
142 n = 5
144 HammerRWMutex(1, 1, n)
145 HammerRWMutex(1, 3, n)
146 HammerRWMutex(1, 10, n)
147 HammerRWMutex(4, 1, n)
148 HammerRWMutex(4, 3, n)
149 HammerRWMutex(4, 10, n)
150 HammerRWMutex(10, 1, n)
151 HammerRWMutex(10, 3, n)
152 HammerRWMutex(10, 10, n)
153 HammerRWMutex(10, 5, n)
156 func TestRLocker(t *testing.T) {
157 var wl RWMutex
158 var rl Locker
159 wlocked := make(chan bool, 1)
160 rlocked := make(chan bool, 1)
161 rl = wl.RLocker()
162 n := 10
163 go func() {
164 for i := 0; i < n; i++ {
165 rl.Lock()
166 rl.Lock()
167 rlocked <- true
168 wl.Lock()
169 wlocked <- true
172 for i := 0; i < n; i++ {
173 <-rlocked
174 rl.Unlock()
175 select {
176 case <-wlocked:
177 t.Fatal("RLocker() didn't read-lock it")
178 default:
180 rl.Unlock()
181 <-wlocked
182 select {
183 case <-rlocked:
184 t.Fatal("RLocker() didn't respect the write lock")
185 default:
187 wl.Unlock()
191 func BenchmarkRWMutexUncontended(b *testing.B) {
192 type PaddedRWMutex struct {
193 RWMutex
194 pad [32]uint32
196 b.RunParallel(func(pb *testing.PB) {
197 var rwm PaddedRWMutex
198 for pb.Next() {
199 rwm.RLock()
200 rwm.RLock()
201 rwm.RUnlock()
202 rwm.RUnlock()
203 rwm.Lock()
204 rwm.Unlock()
209 func benchmarkRWMutex(b *testing.B, localWork, writeRatio int) {
210 var rwm RWMutex
211 b.RunParallel(func(pb *testing.PB) {
212 foo := 0
213 for pb.Next() {
214 foo++
215 if foo%writeRatio == 0 {
216 rwm.Lock()
217 rwm.Unlock()
218 } else {
219 rwm.RLock()
220 for i := 0; i != localWork; i += 1 {
221 foo *= 2
222 foo /= 2
224 rwm.RUnlock()
227 _ = foo
231 func BenchmarkRWMutexWrite100(b *testing.B) {
232 benchmarkRWMutex(b, 0, 100)
235 func BenchmarkRWMutexWrite10(b *testing.B) {
236 benchmarkRWMutex(b, 0, 10)
239 func BenchmarkRWMutexWorkWrite100(b *testing.B) {
240 benchmarkRWMutex(b, 100, 100)
243 func BenchmarkRWMutexWorkWrite10(b *testing.B) {
244 benchmarkRWMutex(b, 100, 10)