modernc.org/gc@v1.0.1-0.20240304020402-f0dba7c97c2b/testdata/errchk/test/fixedbugs/issue13160.go (about)

     1  // run
     2  
     3  // Copyright 2015 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  package main
     8  
     9  import (
    10  	"fmt"
    11  	"runtime"
    12  )
    13  
    14  const N = 100000
    15  
    16  func main() {
    17  	// Allocate more Ps than processors.  This raises
    18  	// the chance that we get interrupted by the OS
    19  	// in exactly the right (wrong!) place.
    20  	p := runtime.NumCPU()
    21  	runtime.GOMAXPROCS(2 * p)
    22  
    23  	// Allocate some pointers.
    24  	ptrs := make([]*int, p)
    25  	for i := 0; i < p; i++ {
    26  		ptrs[i] = new(int)
    27  	}
    28  
    29  	// Arena where we read and write pointers like crazy.
    30  	collider := make([]*int, p)
    31  
    32  	done := make(chan struct{}, 2*p)
    33  
    34  	// Start writers.  They alternately write a pointer
    35  	// and nil to a slot in the collider.
    36  	for i := 0; i < p; i++ {
    37  		i := i
    38  		go func() {
    39  			for j := 0; j < N; j++ {
    40  				// Write a pointer using memmove.
    41  				copy(collider[i:i+1], ptrs[i:i+1])
    42  				// Write nil using memclr.
    43  				// (This is a magic loop that gets lowered to memclr.)
    44  				r := collider[i : i+1]
    45  				for k := range r {
    46  					r[k] = nil
    47  				}
    48  			}
    49  			done <- struct{}{}
    50  		}()
    51  	}
    52  	// Start readers.  They read pointers from slots
    53  	// and make sure they are valid.
    54  	for i := 0; i < p; i++ {
    55  		i := i
    56  		go func() {
    57  			for j := 0; j < N; j++ {
    58  				var ptr [1]*int
    59  				copy(ptr[:], collider[i:i+1])
    60  				if ptr[0] != nil && ptr[0] != ptrs[i] {
    61  					panic(fmt.Sprintf("bad pointer read %p!", ptr[0]))
    62  				}
    63  			}
    64  			done <- struct{}{}
    65  		}()
    66  	}
    67  	for i := 0; i < 2*p; i++ {
    68  		<-done
    69  	}
    70  }