Daily bump.
[official-gcc.git] / libgo / go / runtime / chan_test.go
blobeb2c7c60d0cdc0bdeeee8924fa2296b27268d0eb
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 package runtime_test
7 import (
8 "runtime"
9 "sync"
10 "sync/atomic"
11 "testing"
14 func TestChanSendInterface(t *testing.T) {
15 type mt struct{}
16 m := &mt{}
17 c := make(chan interface{}, 1)
18 c <- m
19 select {
20 case c <- m:
21 default:
23 select {
24 case c <- m:
25 case c <- &mt{}:
26 default:
30 func TestPseudoRandomSend(t *testing.T) {
31 n := 100
32 c := make(chan int)
33 l := make([]int, n)
34 var m sync.Mutex
35 m.Lock()
36 go func() {
37 for i := 0; i < n; i++ {
38 runtime.Gosched()
39 l[i] = <-c
41 m.Unlock()
42 }()
43 for i := 0; i < n; i++ {
44 select {
45 case c <- 0:
46 case c <- 1:
49 m.Lock() // wait
50 n0 := 0
51 n1 := 0
52 for _, i := range l {
53 n0 += (i + 1) % 2
54 n1 += i
55 if n0 > n/10 && n1 > n/10 {
56 return
59 t.Errorf("Want pseudo random, got %d zeros and %d ones", n0, n1)
62 func TestMultiConsumer(t *testing.T) {
63 const nwork = 23
64 const niter = 271828
66 pn := []int{2, 3, 7, 11, 13, 17, 19, 23, 27, 31}
68 q := make(chan int, nwork*3)
69 r := make(chan int, nwork*3)
71 // workers
72 var wg sync.WaitGroup
73 for i := 0; i < nwork; i++ {
74 wg.Add(1)
75 go func(w int) {
76 for v := range q {
77 // mess with the fifo-ish nature of range
78 if pn[w%len(pn)] == v {
79 runtime.Gosched()
81 r <- v
83 wg.Done()
84 }(i)
87 // feeder & closer
88 expect := 0
89 go func() {
90 for i := 0; i < niter; i++ {
91 v := pn[i%len(pn)]
92 expect += v
93 q <- v
95 close(q) // no more work
96 wg.Wait() // workers done
97 close(r) // ... so there can be no more results
98 }()
100 // consume & check
101 n := 0
102 s := 0
103 for v := range r {
105 s += v
107 if n != niter || s != expect {
108 t.Errorf("Expected sum %d (got %d) from %d iter (saw %d)",
109 expect, s, niter, n)
113 func BenchmarkSelectUncontended(b *testing.B) {
114 const CallsPerSched = 1000
115 procs := runtime.GOMAXPROCS(-1)
116 N := int32(b.N / CallsPerSched)
117 c := make(chan bool, procs)
118 for p := 0; p < procs; p++ {
119 go func() {
120 myc1 := make(chan int, 1)
121 myc2 := make(chan int, 1)
122 myc1 <- 0
123 for atomic.AddInt32(&N, -1) >= 0 {
124 for g := 0; g < CallsPerSched; g++ {
125 select {
126 case <-myc1:
127 myc2 <- 0
128 case <-myc2:
129 myc1 <- 0
133 c <- true
136 for p := 0; p < procs; p++ {
141 func BenchmarkSelectContended(b *testing.B) {
142 const CallsPerSched = 1000
143 procs := runtime.GOMAXPROCS(-1)
144 N := int32(b.N / CallsPerSched)
145 c := make(chan bool, procs)
146 myc1 := make(chan int, procs)
147 myc2 := make(chan int, procs)
148 for p := 0; p < procs; p++ {
149 myc1 <- 0
150 go func() {
151 for atomic.AddInt32(&N, -1) >= 0 {
152 for g := 0; g < CallsPerSched; g++ {
153 select {
154 case <-myc1:
155 myc2 <- 0
156 case <-myc2:
157 myc1 <- 0
161 c <- true
164 for p := 0; p < procs; p++ {
169 func BenchmarkSelectNonblock(b *testing.B) {
170 const CallsPerSched = 1000
171 procs := runtime.GOMAXPROCS(-1)
172 N := int32(b.N / CallsPerSched)
173 c := make(chan bool, procs)
174 for p := 0; p < procs; p++ {
175 go func() {
176 myc1 := make(chan int)
177 myc2 := make(chan int)
178 myc3 := make(chan int, 1)
179 myc4 := make(chan int, 1)
180 for atomic.AddInt32(&N, -1) >= 0 {
181 for g := 0; g < CallsPerSched; g++ {
182 select {
183 case <-myc1:
184 default:
186 select {
187 case myc2 <- 0:
188 default:
190 select {
191 case <-myc3:
192 default:
194 select {
195 case myc4 <- 0:
196 default:
200 c <- true
203 for p := 0; p < procs; p++ {
208 func BenchmarkChanUncontended(b *testing.B) {
209 const CallsPerSched = 1000
210 procs := runtime.GOMAXPROCS(-1)
211 N := int32(b.N / CallsPerSched)
212 c := make(chan bool, procs)
213 for p := 0; p < procs; p++ {
214 go func() {
215 myc := make(chan int, CallsPerSched)
216 for atomic.AddInt32(&N, -1) >= 0 {
217 for g := 0; g < CallsPerSched; g++ {
218 myc <- 0
220 for g := 0; g < CallsPerSched; g++ {
221 <-myc
224 c <- true
227 for p := 0; p < procs; p++ {
232 func BenchmarkChanContended(b *testing.B) {
233 const CallsPerSched = 1000
234 procs := runtime.GOMAXPROCS(-1)
235 N := int32(b.N / CallsPerSched)
236 c := make(chan bool, procs)
237 myc := make(chan int, procs*CallsPerSched)
238 for p := 0; p < procs; p++ {
239 go func() {
240 for atomic.AddInt32(&N, -1) >= 0 {
241 for g := 0; g < CallsPerSched; g++ {
242 myc <- 0
244 for g := 0; g < CallsPerSched; g++ {
245 <-myc
248 c <- true
251 for p := 0; p < procs; p++ {
256 func BenchmarkChanSync(b *testing.B) {
257 const CallsPerSched = 1000
258 procs := 2
259 N := int32(b.N / CallsPerSched / procs * procs)
260 c := make(chan bool, procs)
261 myc := make(chan int)
262 for p := 0; p < procs; p++ {
263 go func() {
264 for {
265 i := atomic.AddInt32(&N, -1)
266 if i < 0 {
267 break
269 for g := 0; g < CallsPerSched; g++ {
270 if i%2 == 0 {
271 <-myc
272 myc <- 0
273 } else {
274 myc <- 0
275 <-myc
279 c <- true
282 for p := 0; p < procs; p++ {
287 func benchmarkChanProdCons(b *testing.B, chanSize, localWork int) {
288 const CallsPerSched = 1000
289 procs := runtime.GOMAXPROCS(-1)
290 N := int32(b.N / CallsPerSched)
291 c := make(chan bool, 2*procs)
292 myc := make(chan int, chanSize)
293 for p := 0; p < procs; p++ {
294 go func() {
295 foo := 0
296 for atomic.AddInt32(&N, -1) >= 0 {
297 for g := 0; g < CallsPerSched; g++ {
298 for i := 0; i < localWork; i++ {
299 foo *= 2
300 foo /= 2
302 myc <- 1
305 myc <- 0
306 c <- foo == 42
308 go func() {
309 foo := 0
310 for {
311 v := <-myc
312 if v == 0 {
313 break
315 for i := 0; i < localWork; i++ {
316 foo *= 2
317 foo /= 2
320 c <- foo == 42
323 for p := 0; p < procs; p++ {
329 func BenchmarkChanProdCons0(b *testing.B) {
330 benchmarkChanProdCons(b, 0, 0)
333 func BenchmarkChanProdCons10(b *testing.B) {
334 benchmarkChanProdCons(b, 10, 0)
337 func BenchmarkChanProdCons100(b *testing.B) {
338 benchmarkChanProdCons(b, 100, 0)
341 func BenchmarkChanProdConsWork0(b *testing.B) {
342 benchmarkChanProdCons(b, 0, 100)
345 func BenchmarkChanProdConsWork10(b *testing.B) {
346 benchmarkChanProdCons(b, 10, 100)
349 func BenchmarkChanProdConsWork100(b *testing.B) {
350 benchmarkChanProdCons(b, 100, 100)
353 func BenchmarkChanCreation(b *testing.B) {
354 const CallsPerSched = 1000
355 procs := runtime.GOMAXPROCS(-1)
356 N := int32(b.N / CallsPerSched)
357 c := make(chan bool, procs)
358 for p := 0; p < procs; p++ {
359 go func() {
360 for atomic.AddInt32(&N, -1) >= 0 {
361 for g := 0; g < CallsPerSched; g++ {
362 myc := make(chan int, 1)
363 myc <- 0
364 <-myc
367 c <- true
370 for p := 0; p < procs; p++ {
375 func BenchmarkChanSem(b *testing.B) {
376 type Empty struct{}
377 c := make(chan Empty, 1)
378 for i := 0; i < b.N; i++ {
379 c <- Empty{}