PR tree-optimization/84480 - bogus -Wstringop-truncation despite assignment with...
[official-gcc.git] / libgo / go / sync / rwmutex_test.go
blob9ee8864cebb8eb36c35c389677a06c39d75f4761
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 panic(fmt.Sprintf("wlock(%d)\n", n))
64 for i := 0; i < 100; i++ {
66 atomic.AddInt32(activity, -1)
67 rwm.RUnlock()
69 cdone <- true
72 func writer(rwm *RWMutex, num_iterations int, activity *int32, cdone chan bool) {
73 for i := 0; i < num_iterations; i++ {
74 rwm.Lock()
75 n := atomic.AddInt32(activity, 10000)
76 if n != 10000 {
77 panic(fmt.Sprintf("wlock(%d)\n", n))
79 for i := 0; i < 100; i++ {
81 atomic.AddInt32(activity, -10000)
82 rwm.Unlock()
84 cdone <- true
87 func HammerRWMutex(gomaxprocs, numReaders, num_iterations int) {
88 runtime.GOMAXPROCS(gomaxprocs)
89 // Number of active readers + 10000 * number of active writers.
90 var activity int32
91 var rwm RWMutex
92 cdone := make(chan bool)
93 go writer(&rwm, num_iterations, &activity, cdone)
94 var i int
95 for i = 0; i < numReaders/2; i++ {
96 go reader(&rwm, num_iterations, &activity, cdone)
98 go writer(&rwm, num_iterations, &activity, cdone)
99 for ; i < numReaders; i++ {
100 go reader(&rwm, num_iterations, &activity, cdone)
102 // Wait for the 2 writers and all readers to finish.
103 for i := 0; i < 2+numReaders; i++ {
104 <-cdone
108 func TestRWMutex(t *testing.T) {
109 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(-1))
110 n := 1000
111 if testing.Short() {
112 n = 5
114 HammerRWMutex(1, 1, n)
115 HammerRWMutex(1, 3, n)
116 HammerRWMutex(1, 10, n)
117 HammerRWMutex(4, 1, n)
118 HammerRWMutex(4, 3, n)
119 HammerRWMutex(4, 10, n)
120 HammerRWMutex(10, 1, n)
121 HammerRWMutex(10, 3, n)
122 HammerRWMutex(10, 10, n)
123 HammerRWMutex(10, 5, n)
126 func TestRLocker(t *testing.T) {
127 var wl RWMutex
128 var rl Locker
129 wlocked := make(chan bool, 1)
130 rlocked := make(chan bool, 1)
131 rl = wl.RLocker()
132 n := 10
133 go func() {
134 for i := 0; i < n; i++ {
135 rl.Lock()
136 rl.Lock()
137 rlocked <- true
138 wl.Lock()
139 wlocked <- true
142 for i := 0; i < n; i++ {
143 <-rlocked
144 rl.Unlock()
145 select {
146 case <-wlocked:
147 t.Fatal("RLocker() didn't read-lock it")
148 default:
150 rl.Unlock()
151 <-wlocked
152 select {
153 case <-rlocked:
154 t.Fatal("RLocker() didn't respect the write lock")
155 default:
157 wl.Unlock()
161 func BenchmarkRWMutexUncontended(b *testing.B) {
162 type PaddedRWMutex struct {
163 RWMutex
164 pad [32]uint32
166 b.RunParallel(func(pb *testing.PB) {
167 var rwm PaddedRWMutex
168 for pb.Next() {
169 rwm.RLock()
170 rwm.RLock()
171 rwm.RUnlock()
172 rwm.RUnlock()
173 rwm.Lock()
174 rwm.Unlock()
179 func benchmarkRWMutex(b *testing.B, localWork, writeRatio int) {
180 var rwm RWMutex
181 b.RunParallel(func(pb *testing.PB) {
182 foo := 0
183 for pb.Next() {
184 foo++
185 if foo%writeRatio == 0 {
186 rwm.Lock()
187 rwm.Unlock()
188 } else {
189 rwm.RLock()
190 for i := 0; i != localWork; i += 1 {
191 foo *= 2
192 foo /= 2
194 rwm.RUnlock()
197 _ = foo
201 func BenchmarkRWMutexWrite100(b *testing.B) {
202 benchmarkRWMutex(b, 0, 100)
205 func BenchmarkRWMutexWrite10(b *testing.B) {
206 benchmarkRWMutex(b, 0, 10)
209 func BenchmarkRWMutexWorkWrite100(b *testing.B) {
210 benchmarkRWMutex(b, 100, 100)
213 func BenchmarkRWMutexWorkWrite10(b *testing.B) {
214 benchmarkRWMutex(b, 100, 10)