Source file
test/ken/chan.go
1
2
3
4
5
6
7
8
9 package main
10
11 import "os"
12 import "runtime"
13 import "sync"
14
15 var randx int
16
17 func nrand(n int) int {
18 randx += 10007
19 if randx >= 1000000 {
20 randx -= 1000000
21 }
22 return randx % n
23 }
24
25 type Chan struct {
26 sc, rc chan int
27 sv, rv int
28 }
29
30 var (
31 nproc int
32 nprocLock sync.Mutex
33 cval int
34 end int = 10000
35 totr, tots int
36 totLock sync.Mutex
37 nc *Chan
38 )
39
40 func init() {
41 nc = new(Chan)
42 }
43
44 func changeNproc(adjust int) int {
45 nprocLock.Lock()
46 nproc += adjust
47 ret := nproc
48 nprocLock.Unlock()
49 return ret
50 }
51
52 func mkchan(c, n int) []*Chan {
53 ca := make([]*Chan, n)
54 for i := 0; i < n; i++ {
55 cval = cval + 100
56 ch := new(Chan)
57 ch.sc = make(chan int, c)
58 ch.rc = ch.sc
59 ch.sv = cval
60 ch.rv = cval
61 ca[i] = ch
62 }
63 return ca
64 }
65
66 func expect(v, v0 int) (newv int) {
67 if v == v0 {
68 if v%100 == 75 {
69 return end
70 }
71 return v + 1
72 }
73 print("got ", v, " expected ", v0+1, "\n")
74 panic("fail")
75 }
76
77 func (c *Chan) send() bool {
78
79 totLock.Lock()
80 tots++
81 totLock.Unlock()
82 c.sv = expect(c.sv, c.sv)
83 if c.sv == end {
84 c.sc = nil
85 return true
86 }
87 return false
88 }
89
90 func send(c *Chan) {
91 for {
92 for r := nrand(10); r >= 0; r-- {
93 runtime.Gosched()
94 }
95 c.sc <- c.sv
96 if c.send() {
97 break
98 }
99 }
100 changeNproc(-1)
101 }
102
103 func (c *Chan) recv(v int) bool {
104
105 totLock.Lock()
106 totr++
107 totLock.Unlock()
108 c.rv = expect(c.rv, v)
109 if c.rv == end {
110 c.rc = nil
111 return true
112 }
113 return false
114 }
115
116 func recv(c *Chan) {
117 var v int
118
119 for {
120 for r := nrand(10); r >= 0; r-- {
121 runtime.Gosched()
122 }
123 v = <-c.rc
124 if c.recv(v) {
125 break
126 }
127 }
128 changeNproc(-1)
129 }
130
131 func sel(r0, r1, r2, r3, s0, s1, s2, s3 *Chan) {
132 var v int
133
134 a := 0
135
136 if r0.rc != nil {
137 a++
138 }
139 if r1.rc != nil {
140 a++
141 }
142 if r2.rc != nil {
143 a++
144 }
145 if r3.rc != nil {
146 a++
147 }
148 if s0.sc != nil {
149 a++
150 }
151 if s1.sc != nil {
152 a++
153 }
154 if s2.sc != nil {
155 a++
156 }
157 if s3.sc != nil {
158 a++
159 }
160
161 for {
162 for r := nrand(5); r >= 0; r-- {
163 runtime.Gosched()
164 }
165
166 select {
167 case v = <-r0.rc:
168 if r0.recv(v) {
169 a--
170 }
171 case v = <-r1.rc:
172 if r1.recv(v) {
173 a--
174 }
175 case v = <-r2.rc:
176 if r2.recv(v) {
177 a--
178 }
179 case v = <-r3.rc:
180 if r3.recv(v) {
181 a--
182 }
183 case s0.sc <- s0.sv:
184 if s0.send() {
185 a--
186 }
187 case s1.sc <- s1.sv:
188 if s1.send() {
189 a--
190 }
191 case s2.sc <- s2.sv:
192 if s2.send() {
193 a--
194 }
195 case s3.sc <- s3.sv:
196 if s3.send() {
197 a--
198 }
199 }
200 if a == 0 {
201 break
202 }
203 }
204 changeNproc(-1)
205 }
206
207
208 func test1(c *Chan) {
209 changeNproc(2)
210 go send(c)
211 go recv(c)
212 }
213
214
215 func test2(c int) {
216 ca := mkchan(c, 4)
217
218 changeNproc(4)
219 go send(ca[0])
220 go send(ca[1])
221 go send(ca[2])
222 go send(ca[3])
223
224 changeNproc(1)
225 go sel(ca[0], ca[1], ca[2], ca[3], nc, nc, nc, nc)
226 }
227
228
229 func test3(c int) {
230 ca := mkchan(c, 4)
231
232 changeNproc(4)
233 go recv(ca[0])
234 go recv(ca[1])
235 go recv(ca[2])
236 go recv(ca[3])
237
238 changeNproc(1)
239 go sel(nc, nc, nc, nc, ca[0], ca[1], ca[2], ca[3])
240 }
241
242
243 func test4(c int) {
244 ca := mkchan(c, 4)
245
246 changeNproc(2)
247 go sel(nc, nc, nc, nc, ca[0], ca[1], ca[2], ca[3])
248 go sel(ca[0], ca[1], ca[2], ca[3], nc, nc, nc, nc)
249 }
250
251 func test5(c int) {
252 ca := mkchan(c, 8)
253
254 changeNproc(2)
255 go sel(ca[4], ca[5], ca[6], ca[7], ca[0], ca[1], ca[2], ca[3])
256 go sel(ca[0], ca[1], ca[2], ca[3], ca[4], ca[5], ca[6], ca[7])
257 }
258
259 func test6(c int) {
260 ca := mkchan(c, 12)
261
262 changeNproc(4)
263 go send(ca[4])
264 go send(ca[5])
265 go send(ca[6])
266 go send(ca[7])
267
268 changeNproc(4)
269 go recv(ca[8])
270 go recv(ca[9])
271 go recv(ca[10])
272 go recv(ca[11])
273
274 changeNproc(2)
275 go sel(ca[4], ca[5], ca[6], ca[7], ca[0], ca[1], ca[2], ca[3])
276 go sel(ca[0], ca[1], ca[2], ca[3], ca[8], ca[9], ca[10], ca[11])
277 }
278
279
280 func wait() {
281 runtime.Gosched()
282 for changeNproc(0) != 0 {
283 runtime.Gosched()
284 }
285 }
286
287
288 func tests(c int) {
289 ca := mkchan(c, 4)
290 test1(ca[0])
291 test1(ca[1])
292 test1(ca[2])
293 test1(ca[3])
294 wait()
295
296 test2(c)
297 wait()
298
299 test3(c)
300 wait()
301
302 test4(c)
303 wait()
304
305 test5(c)
306 wait()
307
308 test6(c)
309 wait()
310 }
311
312
313 func main() {
314
315 tests(0)
316 tests(1)
317 tests(10)
318 tests(100)
319
320 t := 4 *
321 (4*4 +
322 8 +
323 12) *
324 76
325
326 if tots != t || totr != t {
327 print("tots=", tots, " totr=", totr, " sb=", t, "\n")
328 os.Exit(1)
329 }
330 os.Exit(0)
331 }
332
View as plain text