1// Copyright 2015 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 5package runtime_test 6 7import ( 8 "runtime" 9 "sync" 10 "testing" 11) 12 13type response struct { 14} 15 16type myError struct { 17} 18 19func (myError) Error() string { return "" } 20 21func doRequest(useSelect bool) (*response, error) { 22 type async struct { 23 resp *response 24 err error 25 } 26 ch := make(chan *async, 0) 27 done := make(chan struct{}, 0) 28 29 if useSelect { 30 go func() { 31 select { 32 case ch <- &async{resp: nil, err: myError{}}: 33 case <-done: 34 } 35 }() 36 } else { 37 go func() { 38 ch <- &async{resp: nil, err: myError{}} 39 }() 40 } 41 42 r := <-ch 43 runtime.Gosched() 44 return r.resp, r.err 45} 46 47func TestChanSendSelectBarrier(t *testing.T) { 48 t.Parallel() 49 testChanSendBarrier(true) 50} 51 52func TestChanSendBarrier(t *testing.T) { 53 t.Parallel() 54 testChanSendBarrier(false) 55} 56 57func testChanSendBarrier(useSelect bool) { 58 var wg sync.WaitGroup 59 outer := 100 60 inner := 100000 61 if testing.Short() || runtime.GOARCH == "wasm" { 62 outer = 10 63 inner = 1000 64 } 65 for i := 0; i < outer; i++ { 66 wg.Add(1) 67 go func() { 68 defer wg.Done() 69 var garbage []byte 70 for j := 0; j < inner; j++ { 71 _, err := doRequest(useSelect) 72 _, ok := err.(myError) 73 if !ok { 74 panic(1) 75 } 76 garbage = makeByte() 77 } 78 _ = garbage 79 }() 80 } 81 wg.Wait() 82} 83 84//go:noinline 85func makeByte() []byte { 86 return make([]byte, 1<<10) 87} 88