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
17 func parallelReader(m
*RWMutex
, clocked
, cunlock
, cdone
chan bool) {
25 func doTestParallelReaders(numReaders
, gomaxprocs
int) {
26 runtime
.GOMAXPROCS(gomaxprocs
)
28 clocked
:= make(chan bool)
29 cunlock
:= make(chan bool)
30 cdone
:= make(chan bool)
31 for i
:= 0; i
< numReaders
; i
++ {
32 go parallelReader(&m
, clocked
, cunlock
, cdone
)
34 // Wait for all parallel RLock()s to succeed.
35 for i
:= 0; i
< numReaders
; i
++ {
38 for i
:= 0; i
< numReaders
; i
++ {
41 // Wait for the goroutines to finish.
42 for i
:= 0; i
< numReaders
; i
++ {
47 func TestParallelReaders(t
*testing
.T
) {
48 defer runtime
.GOMAXPROCS(runtime
.GOMAXPROCS(-1))
49 doTestParallelReaders(1, 4)
50 doTestParallelReaders(3, 4)
51 doTestParallelReaders(4, 2)
54 func reader(rwm
*RWMutex
, num_iterations
int, activity
*int32, cdone
chan bool) {
55 for i
:= 0; i
< num_iterations
; i
++ {
57 n
:= atomic
.AddInt32(activity
, 1)
58 if n
< 1 || n
>= 10000 {
59 panic(fmt
.Sprintf("wlock(%d)\n", n
))
61 for i
:= 0; i
< 100; i
++ {
63 atomic
.AddInt32(activity
, -1)
69 func writer(rwm
*RWMutex
, num_iterations
int, activity
*int32, cdone
chan bool) {
70 for i
:= 0; i
< num_iterations
; i
++ {
72 n
:= atomic
.AddInt32(activity
, 10000)
74 panic(fmt
.Sprintf("wlock(%d)\n", n
))
76 for i
:= 0; i
< 100; i
++ {
78 atomic
.AddInt32(activity
, -10000)
84 func HammerRWMutex(gomaxprocs
, numReaders
, num_iterations
int) {
85 runtime
.GOMAXPROCS(gomaxprocs
)
86 // Number of active readers + 10000 * number of active writers.
89 cdone
:= make(chan bool)
90 go writer(&rwm
, num_iterations
, &activity
, cdone
)
92 for i
= 0; i
< numReaders
/2; i
++ {
93 go reader(&rwm
, num_iterations
, &activity
, cdone
)
95 go writer(&rwm
, num_iterations
, &activity
, cdone
)
96 for ; i
< numReaders
; i
++ {
97 go reader(&rwm
, num_iterations
, &activity
, cdone
)
99 // Wait for the 2 writers and all readers to finish.
100 for i
:= 0; i
< 2+numReaders
; i
++ {
105 func TestRWMutex(t
*testing
.T
) {
106 defer runtime
.GOMAXPROCS(runtime
.GOMAXPROCS(-1))
111 HammerRWMutex(1, 1, n
)
112 HammerRWMutex(1, 3, n
)
113 HammerRWMutex(1, 10, n
)
114 HammerRWMutex(4, 1, n
)
115 HammerRWMutex(4, 3, n
)
116 HammerRWMutex(4, 10, n
)
117 HammerRWMutex(10, 1, n
)
118 HammerRWMutex(10, 3, n
)
119 HammerRWMutex(10, 10, n
)
120 HammerRWMutex(10, 5, n
)
123 func TestRLocker(t
*testing
.T
) {
126 wlocked
:= make(chan bool, 1)
127 rlocked
:= make(chan bool, 1)
131 for i
:= 0; i
< n
; i
++ {
139 for i
:= 0; i
< n
; i
++ {
144 t
.Fatal("RLocker() didn't read-lock it")
151 t
.Fatal("RLocker() didn't respect the write lock")
158 func BenchmarkRWMutexUncontended(b
*testing
.B
) {
159 type PaddedRWMutex
struct {
163 b
.RunParallel(func(pb
*testing
.PB
) {
164 var rwm PaddedRWMutex
176 func benchmarkRWMutex(b
*testing
.B
, localWork
, writeRatio
int) {
178 b
.RunParallel(func(pb
*testing
.PB
) {
182 if foo%writeRatio
== 0 {
187 for i
:= 0; i
!= localWork
; i
+= 1 {
198 func BenchmarkRWMutexWrite100(b
*testing
.B
) {
199 benchmarkRWMutex(b
, 0, 100)
202 func BenchmarkRWMutexWrite10(b
*testing
.B
) {
203 benchmarkRWMutex(b
, 0, 10)
206 func BenchmarkRWMutexWorkWrite100(b
*testing
.B
) {
207 benchmarkRWMutex(b
, 100, 100)
210 func BenchmarkRWMutexWorkWrite10(b
*testing
.B
) {
211 benchmarkRWMutex(b
, 100, 10)