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.
17 func TestChan(t
*testing
.T
) {
18 defer runtime
.GOMAXPROCS(runtime
.GOMAXPROCS(4))
23 for chanCap
:= 0; chanCap
< N
; chanCap
++ {
25 // Ensure that receive from empty chan blocks.
26 c
:= make(chan int, chanCap
)
37 time
.Sleep(time
.Millisecond
)
39 t
.Fatalf("chan[%d]: receive from empty chan", chanCap
)
41 // Ensure that non-blocking receive does not block.
44 t
.Fatalf("chan[%d]: receive from empty chan", chanCap
)
49 t
.Fatalf("chan[%d]: receive from empty chan", chanCap
)
57 // Ensure that send to full chan blocks.
58 c
:= make(chan int, chanCap
)
59 for i
:= 0; i
< chanCap
; i
++ {
65 atomic
.StoreUint32(&sent
, 1)
67 time
.Sleep(time
.Millisecond
)
68 if atomic
.LoadUint32(&sent
) != 0 {
69 t
.Fatalf("chan[%d]: send to full chan", chanCap
)
71 // Ensure that non-blocking send does not block.
74 t
.Fatalf("chan[%d]: send to full chan", chanCap
)
81 // Ensure that we receive 0 from closed chan.
82 c
:= make(chan int, chanCap
)
83 for i
:= 0; i
< chanCap
; i
++ {
87 for i
:= 0; i
< chanCap
; i
++ {
90 t
.Fatalf("chan[%d]: received %v, expected %v", chanCap
, v
, i
)
94 t
.Fatalf("chan[%d]: received %v, expected %v", chanCap
, v
, 0)
96 if v
, ok
:= <-c
; v
!= 0 || ok
{
97 t
.Fatalf("chan[%d]: received %v/%v, expected %v/%v", chanCap
, v
, ok
, 0, false)
102 // Ensure that close unblocks receive.
103 c
:= make(chan int, chanCap
)
104 done
:= make(chan bool)
107 done
<- v
== 0 && ok
== false
109 time
.Sleep(time
.Millisecond
)
112 t
.Fatalf("chan[%d]: received non zero from closed chan", chanCap
)
117 // Send 100 integers,
118 // ensure that we receive them non-corrupted in FIFO order.
119 c
:= make(chan int, chanCap
)
121 for i
:= 0; i
< 100; i
++ {
125 for i
:= 0; i
< 100; i
++ {
128 t
.Fatalf("chan[%d]: received %v, expected %v", chanCap
, v
, i
)
132 // Same, but using recv2.
134 for i
:= 0; i
< 100; i
++ {
138 for i
:= 0; i
< 100; i
++ {
141 t
.Fatalf("chan[%d]: receive failed, expected %v", chanCap
, i
)
144 t
.Fatalf("chan[%d]: received %v, expected %v", chanCap
, v
, i
)
148 // Send 1000 integers in 4 goroutines,
149 // ensure that we receive what we send.
152 for p
:= 0; p
< P
; p
++ {
154 for i
:= 0; i
< L
; i
++ {
159 done
:= make(chan map[int]int)
160 for p
:= 0; p
< P
; p
++ {
162 recv
:= make(map[int]int)
163 for i
:= 0; i
< L
; i
++ {
165 recv
[v
] = recv
[v
] + 1
170 recv
:= make(map[int]int)
171 for p
:= 0; p
< P
; p
++ {
172 for k
, v
:= range <-done
{
173 recv
[k
] = recv
[k
] + v
177 t
.Fatalf("chan[%d]: received %v values, expected %v", chanCap
, len(recv
), L
)
179 for _
, v
:= range recv
{
181 t
.Fatalf("chan[%d]: received %v values, expected %v", chanCap
, v
, P
)
188 c
:= make(chan int, chanCap
)
189 if len(c
) != 0 ||
cap(c
) != chanCap
{
190 t
.Fatalf("chan[%d]: bad len/cap, expect %v/%v, got %v/%v", chanCap
, 0, chanCap
, len(c
), cap(c
))
192 for i
:= 0; i
< chanCap
; i
++ {
195 if len(c
) != chanCap ||
cap(c
) != chanCap
{
196 t
.Fatalf("chan[%d]: bad len/cap, expect %v/%v, got %v/%v", chanCap
, chanCap
, chanCap
, len(c
), cap(c
))
203 func TestNonblockRecvRace(t
*testing
.T
) {
208 if runtime
.GOARCH
== "s390" {
209 // Test uses too much address space on 31-bit S390.
210 t
.Skip("skipping long test on s390")
213 for i
:= 0; i
< n
; i
++ {
214 c
:= make(chan int, 1)
220 t
.Error("chan is not ready")
231 // This test checks that select acts on the state of the channels at one
232 // moment in the execution, not over a smeared time window.
233 // In the test, one goroutine does:
235 // make c1 ready for receiving
236 // create second goroutine
237 // make c2 ready for receiving
238 // make c1 no longer ready for receiving (if possible)
239 // The second goroutine does a non-blocking select receiving from c1 and c2.
240 // From the time the second goroutine is created, at least one of c1 and c2
241 // is always ready for receiving, so the select in the second goroutine must
242 // always receive from one or the other. It must never execute the default case.
243 func TestNonblockSelectRace(t
*testing
.T
) {
248 done
:= make(chan bool, 1)
249 for i
:= 0; i
< n
; i
++ {
250 c1
:= make(chan int, 1)
251 c2
:= make(chan int, 1)
269 t
.Fatal("no chan is ready")
274 // Same as TestNonblockSelectRace, but close(c2) replaces c2 <- 1.
275 func TestNonblockSelectRace2(t
*testing
.T
) {
280 done
:= make(chan bool, 1)
281 for i
:= 0; i
< n
; i
++ {
282 c1
:= make(chan int, 1)
301 t
.Fatal("no chan is ready")
306 func TestSelfSelect(t
*testing
.T
) {
307 // Ensure that send/recv on the same chan in select
308 // does not crash nor deadlock.
309 defer runtime
.GOMAXPROCS(runtime
.GOMAXPROCS(2))
310 for _
, chanCap
:= range []int{0, 10} {
311 var wg sync
.WaitGroup
313 c
:= make(chan int, chanCap
)
314 for p
:= 0; p
< 2; p
++ {
318 for i
:= 0; i
< 1000; i
++ {
319 if p
== 0 || i%2
== 0 {
323 if chanCap
== 0 && v
== p
{
324 t
.Errorf("self receive")
331 if chanCap
== 0 && v
== p
{
332 t
.Errorf("self receive")
345 func TestSelectStress(t
*testing
.T
) {
346 defer runtime
.GOMAXPROCS(runtime
.GOMAXPROCS(10))
348 c
[0] = make(chan int)
349 c
[1] = make(chan int)
350 c
[2] = make(chan int, 2)
351 c
[3] = make(chan int, 3)
356 // There are 4 goroutines that send N values on each of the chans,
357 // + 4 goroutines that receive N values on each of the chans,
358 // + 1 goroutine that sends N values on each of the chans in a single select,
359 // + 1 goroutine that receives N values on each of the chans in a single select.
360 // All these sends, receives and selects interact chaotically at runtime,
361 // but we are careful that this whole construct does not deadlock.
362 var wg sync
.WaitGroup
364 for k
:= 0; k
< 4; k
++ {
367 for i
:= 0; i
< N
; i
++ {
373 for i
:= 0; i
< N
; i
++ {
382 for i
:= 0; i
< 4*N
; i
++ {
411 for i
:= 0; i
< 4*N
; i
++ {
440 func TestSelectFairness(t
*testing
.T
) {
442 if runtime
.GOOS
== "linux" && runtime
.GOARCH
== "ppc64le" {
443 testenv
.SkipFlaky(t
, 22047)
445 c1
:= make(chan byte, trials
+1)
446 c2
:= make(chan byte, trials
+1)
447 for i
:= 0; i
< trials
+1; i
++ {
451 c3
:= make(chan byte)
452 c4
:= make(chan byte)
453 out
:= make(chan byte)
454 done
:= make(chan byte)
455 var wg sync
.WaitGroup
475 for i
:= 0; i
< trials
; i
++ {
476 switch b
:= <-out
; b
{
482 t
.Fatalf("unexpected value %d on channel", b
)
485 // If the select in the goroutine is fair,
486 // cnt1 and cnt2 should be about the same value.
487 // With 10,000 trials, the expected margin of error at
488 // a confidence level of five nines is 4.4172 / (2 * Sqrt(10000)).
489 r
:= float64(cnt1
) / trials
490 e
:= math
.Abs(r
- 0.5)
491 t
.Log(cnt1
, cnt2
, r
, e
)
492 if e
> 4.4172/(2*math
.Sqrt(trials
)) {
493 t
.Errorf("unfair select: in %d trials, results were %d, %d", trials
, cnt1
, cnt2
)
499 func TestChanSendInterface(t
*testing
.T
) {
502 c
:= make(chan interface{}, 1)
515 func TestPseudoRandomSend(t
*testing
.T
) {
517 for _
, chanCap
:= range []int{0, n
} {
518 c
:= make(chan int, chanCap
)
523 for i
:= 0; i
< n
; i
++ {
529 for i
:= 0; i
< n
; i
++ {
538 for _
, i
:= range l
{
542 if n0
<= n
/10 || n1
<= n
/10 {
543 t
.Errorf("Want pseudorandom, got %d zeros and %d ones (chan cap %d)", n0
, n1
, chanCap
)
548 func TestMultiConsumer(t
*testing
.T
) {
552 pn
:= []int{2, 3, 7, 11, 13, 17, 19, 23, 27, 31}
554 q
:= make(chan int, nwork
*3)
555 r
:= make(chan int, nwork
*3)
558 var wg sync
.WaitGroup
559 for i
:= 0; i
< nwork
; i
++ {
563 // mess with the fifo-ish nature of range
564 if pn
[w%len
(pn
)] == v
{
576 for i
:= 0; i
< niter
; i
++ {
581 close(q
) // no more work
582 wg
.Wait() // workers done
583 close(r
) // ... so there can be no more results
593 if n
!= niter || s
!= expect
{
594 t
.Errorf("Expected sum %d (got %d) from %d iter (saw %d)",
599 func TestShrinkStackDuringBlockedSend(t
*testing
.T
) {
600 // make sure that channel operations still work when we are
601 // blocked on a channel send and we shrink the stack.
602 // NOTE: this test probably won't fail unless stack1.go:stackDebug
606 done
:= make(chan struct{})
609 for i
:= 0; i
< n
; i
++ {
611 // use lots of stack, briefly.
612 stackGrowthRecursive(20)
617 for i
:= 0; i
< n
; i
++ {
620 t
.Errorf("bad channel read: want %d, got %d", i
, x
)
622 // Waste some time so sender can finish using lots of stack
623 // and block in channel send.
624 time
.Sleep(1 * time
.Millisecond
)
625 // trigger GC which will shrink the stack of the sender.
631 func TestSelectDuplicateChannel(t
*testing
.T
) {
632 // This test makes sure we can queue a G on
633 // the same channel multiple times.
647 time
.Sleep(time
.Millisecond
) // make sure goroutine A gets queued first on c
653 time
.Sleep(time
.Millisecond
) // make sure goroutine B gets queued on c before continuing
655 d
<- 7 // wake up A, it dequeues itself from c. This operation used to corrupt c.recvq.
656 <-e
// A tells us it's done
657 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)
660 var selectSink
interface{}
662 func TestSelectStackAdjust(t
*testing
.T
) {
663 // Test that channel receive slots that contain local stack
664 // pointers are adjusted correctly by stack shrinking.
667 ready1
:= make(chan bool)
668 ready2
:= make(chan bool)
670 f
:= func(ready
chan bool, dup
bool) {
671 // Temporarily grow the stack to 10K.
672 stackGrowthRecursive((10 << 10) / (128 * 8))
674 // We're ready to trigger GC and stack shrink.
688 // Receive from d. cx won't be affected.
696 // Check that pointer in cx was adjusted correctly.
698 t
.Error("cx no longer points to val")
699 } else if val
!= 42 {
700 t
.Error("val changed")
704 t
.Error("changing *cx failed to change val")
713 // Let the goroutines get into the select.
716 time
.Sleep(10 * time
.Millisecond
)
718 // Force concurrent GC a few times.
719 var before
, after runtime
.MemStats
720 runtime
.ReadMemStats(&before
)
721 for i
:= 0; i
< 100; i
++ {
722 selectSink
= new([1 << 20]byte)
723 runtime
.ReadMemStats(&after
)
724 if after
.NumGC
-before
.NumGC
>= 2 {
728 t
.Fatal("failed to trigger concurrent GC")
738 type struct0
struct{}
740 func BenchmarkMakeChan(b
*testing
.B
) {
741 b
.Run("Byte", func(b
*testing
.B
) {
743 for i
:= 0; i
< b
.N
; i
++ {
744 x
= make(chan byte, 8)
748 b
.Run("Int", func(b
*testing
.B
) {
750 for i
:= 0; i
< b
.N
; i
++ {
751 x
= make(chan int, 8)
755 b
.Run("Ptr", func(b
*testing
.B
) {
757 for i
:= 0; i
< b
.N
; i
++ {
758 x
= make(chan *byte, 8)
762 b
.Run("Struct", func(b
*testing
.B
) {
763 b
.Run("0", func(b
*testing
.B
) {
765 for i
:= 0; i
< b
.N
; i
++ {
766 x
= make(chan struct0
, 8)
770 b
.Run("32", func(b
*testing
.B
) {
772 for i
:= 0; i
< b
.N
; i
++ {
773 x
= make(chan struct32
, 8)
777 b
.Run("40", func(b
*testing
.B
) {
779 for i
:= 0; i
< b
.N
; i
++ {
780 x
= make(chan struct40
, 8)
787 func BenchmarkChanNonblocking(b
*testing
.B
) {
788 myc
:= make(chan int)
789 b
.RunParallel(func(pb
*testing
.PB
) {
799 func BenchmarkSelectUncontended(b
*testing
.B
) {
800 b
.RunParallel(func(pb
*testing
.PB
) {
801 myc1
:= make(chan int, 1)
802 myc2
:= make(chan int, 1)
815 func BenchmarkSelectSyncContended(b
*testing
.B
) {
816 myc1
:= make(chan int)
817 myc2
:= make(chan int)
818 myc3
:= make(chan int)
819 done
:= make(chan int)
820 b
.RunParallel(func(pb
*testing
.PB
) {
843 func BenchmarkSelectAsyncContended(b
*testing
.B
) {
844 procs
:= runtime
.GOMAXPROCS(0)
845 myc1
:= make(chan int, procs
)
846 myc2
:= make(chan int, procs
)
847 b
.RunParallel(func(pb
*testing
.PB
) {
860 func BenchmarkSelectNonblock(b
*testing
.B
) {
861 myc1
:= make(chan int)
862 myc2
:= make(chan int)
863 myc3
:= make(chan int, 1)
864 myc4
:= make(chan int, 1)
865 b
.RunParallel(func(pb
*testing
.PB
) {
887 func BenchmarkChanUncontended(b
*testing
.B
) {
889 b
.RunParallel(func(pb
*testing
.PB
) {
890 myc
:= make(chan int, C
)
892 for i
:= 0; i
< C
; i
++ {
895 for i
:= 0; i
< C
; i
++ {
902 func BenchmarkChanContended(b
*testing
.B
) {
904 myc
:= make(chan int, C
*runtime
.GOMAXPROCS(0))
905 b
.RunParallel(func(pb
*testing
.PB
) {
907 for i
:= 0; i
< C
; i
++ {
910 for i
:= 0; i
< C
; i
++ {
917 func benchmarkChanSync(b
*testing
.B
, work
int) {
918 const CallsPerSched
= 1000
920 N
:= int32(b
.N
/ CallsPerSched
/ procs
* procs
)
921 c
:= make(chan bool, procs
)
922 myc
:= make(chan int)
923 for p
:= 0; p
< procs
; p
++ {
926 i
:= atomic
.AddInt32(&N
, -1)
930 for g
:= 0; g
< CallsPerSched
; g
++ {
947 for p
:= 0; p
< procs
; p
++ {
952 func BenchmarkChanSync(b
*testing
.B
) {
953 benchmarkChanSync(b
, 0)
956 func BenchmarkChanSyncWork(b
*testing
.B
) {
957 benchmarkChanSync(b
, 1000)
960 func benchmarkChanProdCons(b
*testing
.B
, chanSize
, localWork
int) {
961 const CallsPerSched
= 1000
962 procs
:= runtime
.GOMAXPROCS(-1)
963 N
:= int32(b
.N
/ CallsPerSched
)
964 c
:= make(chan bool, 2*procs
)
965 myc
:= make(chan int, chanSize
)
966 for p
:= 0; p
< procs
; p
++ {
969 for atomic
.AddInt32(&N
, -1) >= 0 {
970 for g
:= 0; g
< CallsPerSched
; g
++ {
971 for i
:= 0; i
< localWork
; i
++ {
988 for i
:= 0; i
< localWork
; i
++ {
996 for p
:= 0; p
< procs
; p
++ {
1002 func BenchmarkChanProdCons0(b
*testing
.B
) {
1003 benchmarkChanProdCons(b
, 0, 0)
1006 func BenchmarkChanProdCons10(b
*testing
.B
) {
1007 benchmarkChanProdCons(b
, 10, 0)
1010 func BenchmarkChanProdCons100(b
*testing
.B
) {
1011 benchmarkChanProdCons(b
, 100, 0)
1014 func BenchmarkChanProdConsWork0(b
*testing
.B
) {
1015 benchmarkChanProdCons(b
, 0, 100)
1018 func BenchmarkChanProdConsWork10(b
*testing
.B
) {
1019 benchmarkChanProdCons(b
, 10, 100)
1022 func BenchmarkChanProdConsWork100(b
*testing
.B
) {
1023 benchmarkChanProdCons(b
, 100, 100)
1026 func BenchmarkSelectProdCons(b
*testing
.B
) {
1027 const CallsPerSched
= 1000
1028 procs
:= runtime
.GOMAXPROCS(-1)
1029 N
:= int32(b
.N
/ CallsPerSched
)
1030 c
:= make(chan bool, 2*procs
)
1031 myc
:= make(chan int, 128)
1032 myclose
:= make(chan bool)
1033 for p
:= 0; p
< procs
; p
++ {
1035 // Producer: sends to myc.
1037 // Intended to not fire during benchmarking.
1038 mytimer
:= time
.After(time
.Hour
)
1039 for atomic
.AddInt32(&N
, -1) >= 0 {
1040 for g
:= 0; g
< CallsPerSched
; g
++ {
1041 // Model some local work.
1042 for i
:= 0; i
< 100; i
++ {
1057 // Consumer: receives from myc.
1059 // Intended to not fire during benchmarking.
1060 mytimer
:= time
.After(time
.Hour
)
1071 // Model some local work.
1072 for i
:= 0; i
< 100; i
++ {
1080 for p
:= 0; p
< procs
; p
++ {
1086 func BenchmarkChanCreation(b
*testing
.B
) {
1087 b
.RunParallel(func(pb
*testing
.PB
) {
1089 myc
:= make(chan int, 1)
1096 func BenchmarkChanSem(b
*testing
.B
) {
1098 myc
:= make(chan Empty
, runtime
.GOMAXPROCS(0))
1099 b
.RunParallel(func(pb
*testing
.PB
) {
1107 func BenchmarkChanPopular(b
*testing
.B
) {
1109 c
:= make(chan bool)
1111 var wg sync
.WaitGroup
1113 for j
:= 0; j
< n
; j
++ {
1114 d
:= make(chan bool)
1117 for i
:= 0; i
< b
.N
; i
++ {
1126 for i
:= 0; i
< b
.N
; i
++ {
1127 for _
, d
:= range a
{
1139 func localWork(w
int) {
1141 for i
:= 0; i
< w
; i
++ {