Source file src/runtime/chanbarrier_test.go

     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  
     5  package runtime_test
     6  
     7  import (
     8  	"runtime"
     9  	"sync"
    10  	"testing"
    11  )
    12  
    13  type response struct {
    14  }
    15  
    16  type myError struct {
    17  }
    18  
    19  func (myError) Error() string { return "" }
    20  
    21  func 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  
    47  func TestChanSendSelectBarrier(t *testing.T) {
    48  	t.Parallel()
    49  	testChanSendBarrier(true)
    50  }
    51  
    52  func TestChanSendBarrier(t *testing.T) {
    53  	t.Parallel()
    54  	testChanSendBarrier(false)
    55  }
    56  
    57  func 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
    85  func makeByte() []byte {
    86  	return make([]byte, 1<<10)
    87  }
    88  

View as plain text