OSDN Git Service

405079270dcc7254c657ac5c241b516d0a1c4962
[pf3gnuchains/gcc-fork.git] / libgo / go / sync / rwmutex_test.go
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.
4
5 // GOMAXPROCS=10 gotest
6
7 package sync_test
8
9 import (
10         "fmt"
11         "runtime"
12         . "sync"
13         "sync/atomic"
14         "testing"
15 )
16
17 func parallelReader(m *RWMutex, clocked, cunlock, cdone chan bool) {
18         m.RLock()
19         clocked <- true
20         <-cunlock
21         m.RUnlock()
22         cdone <- true
23 }
24
25 func doTestParallelReaders(numReaders, gomaxprocs int) {
26         runtime.GOMAXPROCS(gomaxprocs)
27         var m RWMutex
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)
33         }
34         // Wait for all parallel RLock()s to succeed.
35         for i := 0; i < numReaders; i++ {
36                 <-clocked
37         }
38         for i := 0; i < numReaders; i++ {
39                 cunlock <- true
40         }
41         // Wait for the goroutines to finish.
42         for i := 0; i < numReaders; i++ {
43                 <-cdone
44         }
45 }
46
47 func TestParallelReaders(t *testing.T) {
48         doTestParallelReaders(1, 4)
49         doTestParallelReaders(3, 4)
50         doTestParallelReaders(4, 2)
51 }
52
53 func reader(rwm *RWMutex, num_iterations int, activity *int32, cdone chan bool) {
54         for i := 0; i < num_iterations; i++ {
55                 rwm.RLock()
56                 n := atomic.AddInt32(activity, 1)
57                 if n < 1 || n >= 10000 {
58                         panic(fmt.Sprintf("wlock(%d)\n", n))
59                 }
60                 for i := 0; i < 100; i++ {
61                 }
62                 atomic.AddInt32(activity, -1)
63                 rwm.RUnlock()
64         }
65         cdone <- true
66 }
67
68 func writer(rwm *RWMutex, num_iterations int, activity *int32, cdone chan bool) {
69         for i := 0; i < num_iterations; i++ {
70                 rwm.Lock()
71                 n := atomic.AddInt32(activity, 10000)
72                 if n != 10000 {
73                         panic(fmt.Sprintf("wlock(%d)\n", n))
74                 }
75                 for i := 0; i < 100; i++ {
76                 }
77                 atomic.AddInt32(activity, -10000)
78                 rwm.Unlock()
79         }
80         cdone <- true
81 }
82
83 func HammerRWMutex(gomaxprocs, numReaders, num_iterations int) {
84         runtime.GOMAXPROCS(gomaxprocs)
85         // Number of active readers + 10000 * number of active writers.
86         var activity int32
87         var rwm RWMutex
88         cdone := make(chan bool)
89         go writer(&rwm, num_iterations, &activity, cdone)
90         var i int
91         for i = 0; i < numReaders/2; i++ {
92                 go reader(&rwm, num_iterations, &activity, cdone)
93         }
94         go writer(&rwm, num_iterations, &activity, cdone)
95         for ; i < numReaders; i++ {
96                 go reader(&rwm, num_iterations, &activity, cdone)
97         }
98         // Wait for the 2 writers and all readers to finish.
99         for i := 0; i < 2+numReaders; i++ {
100                 <-cdone
101         }
102 }
103
104 func TestRWMutex(t *testing.T) {
105         HammerRWMutex(1, 1, 1000)
106         HammerRWMutex(1, 3, 1000)
107         HammerRWMutex(1, 10, 1000)
108         HammerRWMutex(4, 1, 1000)
109         HammerRWMutex(4, 3, 1000)
110         HammerRWMutex(4, 10, 1000)
111         HammerRWMutex(10, 1, 1000)
112         HammerRWMutex(10, 3, 1000)
113         HammerRWMutex(10, 10, 1000)
114         HammerRWMutex(10, 5, 10000)
115 }
116
117 func TestRLocker(t *testing.T) {
118         var wl RWMutex
119         var rl Locker
120         wlocked := make(chan bool, 1)
121         rlocked := make(chan bool, 1)
122         rl = wl.RLocker()
123         n := 10
124         go func() {
125                 for i := 0; i < n; i++ {
126                         rl.Lock()
127                         rl.Lock()
128                         rlocked <- true
129                         wl.Lock()
130                         wlocked <- true
131                 }
132         }()
133         for i := 0; i < n; i++ {
134                 <-rlocked
135                 rl.Unlock()
136                 select {
137                 case <-wlocked:
138                         t.Fatal("RLocker() didn't read-lock it")
139                 default:
140                 }
141                 rl.Unlock()
142                 <-wlocked
143                 select {
144                 case <-rlocked:
145                         t.Fatal("RLocker() didn't respect the write lock")
146                 default:
147                 }
148                 wl.Unlock()
149         }
150 }