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.
15 func TestChan(t
*testing
.T
) {
16 defer runtime
.GOMAXPROCS(runtime
.GOMAXPROCS(4))
21 for chanCap
:= 0; chanCap
< N
; chanCap
++ {
23 // Ensure that receive from empty chan blocks.
24 c
:= make(chan int, chanCap
)
35 time
.Sleep(time
.Millisecond
)
37 t
.Fatalf("chan[%d]: receive from empty chan", chanCap
)
39 // Ensure that non-blocking receive does not block.
42 t
.Fatalf("chan[%d]: receive from empty chan", chanCap
)
47 t
.Fatalf("chan[%d]: receive from empty chan", chanCap
)
55 // Ensure that send to full chan blocks.
56 c
:= make(chan int, chanCap
)
57 for i
:= 0; i
< chanCap
; i
++ {
63 atomic
.StoreUint32(&sent
, 1)
65 time
.Sleep(time
.Millisecond
)
66 if atomic
.LoadUint32(&sent
) != 0 {
67 t
.Fatalf("chan[%d]: send to full chan", chanCap
)
69 // Ensure that non-blocking send does not block.
72 t
.Fatalf("chan[%d]: send to full chan", chanCap
)
79 // Ensure that we receive 0 from closed chan.
80 c
:= make(chan int, chanCap
)
81 for i
:= 0; i
< chanCap
; i
++ {
85 for i
:= 0; i
< chanCap
; i
++ {
88 t
.Fatalf("chan[%d]: received %v, expected %v", chanCap
, v
, i
)
92 t
.Fatalf("chan[%d]: received %v, expected %v", chanCap
, v
, 0)
94 if v
, ok
:= <-c
; v
!= 0 || ok
{
95 t
.Fatalf("chan[%d]: received %v/%v, expected %v/%v", chanCap
, v
, ok
, 0, false)
100 // Ensure that close unblocks receive.
101 c
:= make(chan int, chanCap
)
102 done
:= make(chan bool)
105 done
<- v
== 0 && ok
== false
107 time
.Sleep(time
.Millisecond
)
110 t
.Fatalf("chan[%d]: received non zero from closed chan", chanCap
)
115 // Send 100 integers,
116 // ensure that we receive them non-corrupted in FIFO order.
117 c
:= make(chan int, chanCap
)
119 for i
:= 0; i
< 100; i
++ {
123 for i
:= 0; i
< 100; i
++ {
126 t
.Fatalf("chan[%d]: received %v, expected %v", chanCap
, v
, i
)
130 // Same, but using recv2.
132 for i
:= 0; i
< 100; i
++ {
136 for i
:= 0; i
< 100; i
++ {
139 t
.Fatalf("chan[%d]: receive failed, expected %v", chanCap
, i
)
142 t
.Fatalf("chan[%d]: received %v, expected %v", chanCap
, v
, i
)
146 // Send 1000 integers in 4 goroutines,
147 // ensure that we receive what we send.
150 for p
:= 0; p
< P
; p
++ {
152 for i
:= 0; i
< L
; i
++ {
157 done
:= make(chan map[int]int)
158 for p
:= 0; p
< P
; p
++ {
160 recv
:= make(map[int]int)
161 for i
:= 0; i
< L
; i
++ {
163 recv
[v
] = recv
[v
] + 1
168 recv
:= make(map[int]int)
169 for p
:= 0; p
< P
; p
++ {
170 for k
, v
:= range <-done
{
171 recv
[k
] = recv
[k
] + v
175 t
.Fatalf("chan[%d]: received %v values, expected %v", chanCap
, len(recv
), L
)
177 for _
, v
:= range recv
{
179 t
.Fatalf("chan[%d]: received %v values, expected %v", chanCap
, v
, P
)
186 c
:= make(chan int, chanCap
)
187 if len(c
) != 0 ||
cap(c
) != chanCap
{
188 t
.Fatalf("chan[%d]: bad len/cap, expect %v/%v, got %v/%v", chanCap
, 0, chanCap
, len(c
), cap(c
))
190 for i
:= 0; i
< chanCap
; i
++ {
193 if len(c
) != chanCap ||
cap(c
) != chanCap
{
194 t
.Fatalf("chan[%d]: bad len/cap, expect %v/%v, got %v/%v", chanCap
, chanCap
, chanCap
, len(c
), cap(c
))
201 func TestNonblockRecvRace(t
*testing
.T
) {
206 if runtime
.GOARCH
== "s390" {
207 // Test uses too much address space on 31-bit S390.
208 t
.Skip("skipping long test on s390")
211 for i
:= 0; i
< n
; i
++ {
212 c
:= make(chan int, 1)
218 t
.Error("chan is not ready")
229 // This test checks that select acts on the state of the channels at one
230 // moment in the execution, not over a smeared time window.
231 // In the test, one goroutine does:
233 // make c1 ready for receiving
234 // create second goroutine
235 // make c2 ready for receiving
236 // make c1 no longer ready for receiving (if possible)
237 // The second goroutine does a non-blocking select receiving from c1 and c2.
238 // From the time the second goroutine is created, at least one of c1 and c2
239 // is always ready for receiving, so the select in the second goroutine must
240 // always receive from one or the other. It must never execute the default case.
241 func TestNonblockSelectRace(t
*testing
.T
) {
246 done
:= make(chan bool, 1)
247 for i
:= 0; i
< n
; i
++ {
248 c1
:= make(chan int, 1)
249 c2
:= make(chan int, 1)
267 t
.Fatal("no chan is ready")
272 // Same as TestNonblockSelectRace, but close(c2) replaces c2 <- 1.
273 func TestNonblockSelectRace2(t
*testing
.T
) {
278 done
:= make(chan bool, 1)
279 for i
:= 0; i
< n
; i
++ {
280 c1
:= make(chan int, 1)
299 t
.Fatal("no chan is ready")
304 func TestSelfSelect(t
*testing
.T
) {
305 // Ensure that send/recv on the same chan in select
306 // does not crash nor deadlock.
307 defer runtime
.GOMAXPROCS(runtime
.GOMAXPROCS(2))
308 for _
, chanCap
:= range []int{0, 10} {
309 var wg sync
.WaitGroup
311 c
:= make(chan int, chanCap
)
312 for p
:= 0; p
< 2; p
++ {
316 for i
:= 0; i
< 1000; i
++ {
317 if p
== 0 || i%2
== 0 {
321 if chanCap
== 0 && v
== p
{
322 t
.Errorf("self receive")
329 if chanCap
== 0 && v
== p
{
330 t
.Errorf("self receive")
343 func TestSelectStress(t
*testing
.T
) {
344 defer runtime
.GOMAXPROCS(runtime
.GOMAXPROCS(10))
346 c
[0] = make(chan int)
347 c
[1] = make(chan int)
348 c
[2] = make(chan int, 2)
349 c
[3] = make(chan int, 3)
354 // There are 4 goroutines that send N values on each of the chans,
355 // + 4 goroutines that receive N values on each of the chans,
356 // + 1 goroutine that sends N values on each of the chans in a single select,
357 // + 1 goroutine that receives N values on each of the chans in a single select.
358 // All these sends, receives and selects interact chaotically at runtime,
359 // but we are careful that this whole construct does not deadlock.
360 var wg sync
.WaitGroup
362 for k
:= 0; k
< 4; k
++ {
365 for i
:= 0; i
< N
; i
++ {
371 for i
:= 0; i
< N
; i
++ {
380 for i
:= 0; i
< 4*N
; i
++ {
409 for i
:= 0; i
< 4*N
; i
++ {
438 func TestChanSendInterface(t
*testing
.T
) {
441 c
:= make(chan interface{}, 1)
454 func TestPseudoRandomSend(t
*testing
.T
) {
456 for _
, chanCap
:= range []int{0, n
} {
457 c
:= make(chan int, chanCap
)
462 for i
:= 0; i
< n
; i
++ {
468 for i
:= 0; i
< n
; i
++ {
477 for _
, i
:= range l
{
481 if n0
<= n
/10 || n1
<= n
/10 {
482 t
.Errorf("Want pseudorandom, got %d zeros and %d ones (chan cap %d)", n0
, n1
, chanCap
)
487 func TestMultiConsumer(t
*testing
.T
) {
491 pn
:= []int{2, 3, 7, 11, 13, 17, 19, 23, 27, 31}
493 q
:= make(chan int, nwork
*3)
494 r
:= make(chan int, nwork
*3)
497 var wg sync
.WaitGroup
498 for i
:= 0; i
< nwork
; i
++ {
502 // mess with the fifo-ish nature of range
503 if pn
[w%len
(pn
)] == v
{
515 for i
:= 0; i
< niter
; i
++ {
520 close(q
) // no more work
521 wg
.Wait() // workers done
522 close(r
) // ... so there can be no more results
532 if n
!= niter || s
!= expect
{
533 t
.Errorf("Expected sum %d (got %d) from %d iter (saw %d)",
538 func TestShrinkStackDuringBlockedSend(t
*testing
.T
) {
539 // make sure that channel operations still work when we are
540 // blocked on a channel send and we shrink the stack.
541 // NOTE: this test probably won't fail unless stack1.go:stackDebug
545 done
:= make(chan struct{})
548 for i
:= 0; i
< n
; i
++ {
550 // use lots of stack, briefly.
551 stackGrowthRecursive(20)
556 for i
:= 0; i
< n
; i
++ {
559 t
.Errorf("bad channel read: want %d, got %d", i
, x
)
561 // Waste some time so sender can finish using lots of stack
562 // and block in channel send.
563 time
.Sleep(1 * time
.Millisecond
)
564 // trigger GC which will shrink the stack of the sender.
570 func TestSelectDuplicateChannel(t
*testing
.T
) {
571 // This test makes sure we can queue a G on
572 // the same channel multiple times.
586 time
.Sleep(time
.Millisecond
) // make sure goroutine A gets queued first on c
592 time
.Sleep(time
.Millisecond
) // make sure goroutine B gets queued on c before continuing
594 d
<- 7 // wake up A, it dequeues itself from c. This operation used to corrupt c.recvq.
595 <-e
// A tells us it's done
596 c
<- 8 // wake up B. This operation used to fail because c.recvq was corrupted (it tries to wake up an already running G instead of B)
599 var selectSink
interface{}
601 func TestSelectStackAdjust(t
*testing
.T
) {
602 // Test that channel receive slots that contain local stack
603 // pointers are adjusted correctly by stack shrinking.
606 ready1
:= make(chan bool)
607 ready2
:= make(chan bool)
609 f
:= func(ready
chan bool, dup
bool) {
610 // Temporarily grow the stack to 10K.
611 stackGrowthRecursive((10 << 10) / (128 * 8))
613 // We're ready to trigger GC and stack shrink.
627 // Receive from d. cx won't be affected.
635 // Check that pointer in cx was adjusted correctly.
637 t
.Error("cx no longer points to val")
638 } else if val
!= 42 {
639 t
.Error("val changed")
643 t
.Error("changing *cx failed to change val")
652 // Let the goroutines get into the select.
655 time
.Sleep(10 * time
.Millisecond
)
657 // Force concurrent GC a few times.
658 var before
, after runtime
.MemStats
659 runtime
.ReadMemStats(&before
)
660 for i
:= 0; i
< 100; i
++ {
661 selectSink
= new([1 << 20]byte)
662 runtime
.ReadMemStats(&after
)
663 if after
.NumGC
-before
.NumGC
>= 2 {
667 t
.Fatal("failed to trigger concurrent GC")
677 func BenchmarkChanNonblocking(b
*testing
.B
) {
678 myc
:= make(chan int)
679 b
.RunParallel(func(pb
*testing
.PB
) {
689 func BenchmarkSelectUncontended(b
*testing
.B
) {
690 b
.RunParallel(func(pb
*testing
.PB
) {
691 myc1
:= make(chan int, 1)
692 myc2
:= make(chan int, 1)
705 func BenchmarkSelectSyncContended(b
*testing
.B
) {
706 myc1
:= make(chan int)
707 myc2
:= make(chan int)
708 myc3
:= make(chan int)
709 done
:= make(chan int)
710 b
.RunParallel(func(pb
*testing
.PB
) {
733 func BenchmarkSelectAsyncContended(b
*testing
.B
) {
734 procs
:= runtime
.GOMAXPROCS(0)
735 myc1
:= make(chan int, procs
)
736 myc2
:= make(chan int, procs
)
737 b
.RunParallel(func(pb
*testing
.PB
) {
750 func BenchmarkSelectNonblock(b
*testing
.B
) {
751 myc1
:= make(chan int)
752 myc2
:= make(chan int)
753 myc3
:= make(chan int, 1)
754 myc4
:= make(chan int, 1)
755 b
.RunParallel(func(pb
*testing
.PB
) {
777 func BenchmarkChanUncontended(b
*testing
.B
) {
779 b
.RunParallel(func(pb
*testing
.PB
) {
780 myc
:= make(chan int, C
)
782 for i
:= 0; i
< C
; i
++ {
785 for i
:= 0; i
< C
; i
++ {
792 func BenchmarkChanContended(b
*testing
.B
) {
794 myc
:= make(chan int, C
*runtime
.GOMAXPROCS(0))
795 b
.RunParallel(func(pb
*testing
.PB
) {
797 for i
:= 0; i
< C
; i
++ {
800 for i
:= 0; i
< C
; i
++ {
807 func benchmarkChanSync(b
*testing
.B
, work
int) {
808 const CallsPerSched
= 1000
810 N
:= int32(b
.N
/ CallsPerSched
/ procs
* procs
)
811 c
:= make(chan bool, procs
)
812 myc
:= make(chan int)
813 for p
:= 0; p
< procs
; p
++ {
816 i
:= atomic
.AddInt32(&N
, -1)
820 for g
:= 0; g
< CallsPerSched
; g
++ {
837 for p
:= 0; p
< procs
; p
++ {
842 func BenchmarkChanSync(b
*testing
.B
) {
843 benchmarkChanSync(b
, 0)
846 func BenchmarkChanSyncWork(b
*testing
.B
) {
847 benchmarkChanSync(b
, 1000)
850 func benchmarkChanProdCons(b
*testing
.B
, chanSize
, localWork
int) {
851 const CallsPerSched
= 1000
852 procs
:= runtime
.GOMAXPROCS(-1)
853 N
:= int32(b
.N
/ CallsPerSched
)
854 c
:= make(chan bool, 2*procs
)
855 myc
:= make(chan int, chanSize
)
856 for p
:= 0; p
< procs
; p
++ {
859 for atomic
.AddInt32(&N
, -1) >= 0 {
860 for g
:= 0; g
< CallsPerSched
; g
++ {
861 for i
:= 0; i
< localWork
; i
++ {
878 for i
:= 0; i
< localWork
; i
++ {
886 for p
:= 0; p
< procs
; p
++ {
892 func BenchmarkChanProdCons0(b
*testing
.B
) {
893 benchmarkChanProdCons(b
, 0, 0)
896 func BenchmarkChanProdCons10(b
*testing
.B
) {
897 benchmarkChanProdCons(b
, 10, 0)
900 func BenchmarkChanProdCons100(b
*testing
.B
) {
901 benchmarkChanProdCons(b
, 100, 0)
904 func BenchmarkChanProdConsWork0(b
*testing
.B
) {
905 benchmarkChanProdCons(b
, 0, 100)
908 func BenchmarkChanProdConsWork10(b
*testing
.B
) {
909 benchmarkChanProdCons(b
, 10, 100)
912 func BenchmarkChanProdConsWork100(b
*testing
.B
) {
913 benchmarkChanProdCons(b
, 100, 100)
916 func BenchmarkSelectProdCons(b
*testing
.B
) {
917 const CallsPerSched
= 1000
918 procs
:= runtime
.GOMAXPROCS(-1)
919 N
:= int32(b
.N
/ CallsPerSched
)
920 c
:= make(chan bool, 2*procs
)
921 myc
:= make(chan int, 128)
922 myclose
:= make(chan bool)
923 for p
:= 0; p
< procs
; p
++ {
925 // Producer: sends to myc.
927 // Intended to not fire during benchmarking.
928 mytimer
:= time
.After(time
.Hour
)
929 for atomic
.AddInt32(&N
, -1) >= 0 {
930 for g
:= 0; g
< CallsPerSched
; g
++ {
931 // Model some local work.
932 for i
:= 0; i
< 100; i
++ {
947 // Consumer: receives from myc.
949 // Intended to not fire during benchmarking.
950 mytimer
:= time
.After(time
.Hour
)
961 // Model some local work.
962 for i
:= 0; i
< 100; i
++ {
970 for p
:= 0; p
< procs
; p
++ {
976 func BenchmarkChanCreation(b
*testing
.B
) {
977 b
.RunParallel(func(pb
*testing
.PB
) {
979 myc
:= make(chan int, 1)
986 func BenchmarkChanSem(b
*testing
.B
) {
988 myc
:= make(chan Empty
, runtime
.GOMAXPROCS(0))
989 b
.RunParallel(func(pb
*testing
.PB
) {
997 func BenchmarkChanPopular(b
*testing
.B
) {
1001 var wg sync
.WaitGroup
1003 for j
:= 0; j
< n
; j
++ {
1004 d
:= make(chan bool)
1007 for i
:= 0; i
< b
.N
; i
++ {
1016 for i
:= 0; i
< b
.N
; i
++ {
1017 for _
, d
:= range a
{
1029 func localWork(w
int) {
1031 for i
:= 0; i
< w
; i
++ {