...
Run Format

Source file test/fixedbugs/issue13160.go

Documentation: test/fixedbugs

  // run
  
  // Copyright 2015 The Go Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
  package main
  
  import (
  	"fmt"
  	"runtime"
  )
  
  const N = 100000
  
  func main() {
  	// Allocate more Ps than processors.  This raises
  	// the chance that we get interrupted by the OS
  	// in exactly the right (wrong!) place.
  	p := runtime.NumCPU()
  	runtime.GOMAXPROCS(2 * p)
  
  	// Allocate some pointers.
  	ptrs := make([]*int, p)
  	for i := 0; i < p; i++ {
  		ptrs[i] = new(int)
  	}
  
  	// Arena where we read and write pointers like crazy.
  	collider := make([]*int, p)
  
  	done := make(chan struct{}, 2*p)
  
  	// Start writers.  They alternately write a pointer
  	// and nil to a slot in the collider.
  	for i := 0; i < p; i++ {
  		i := i
  		go func() {
  			for j := 0; j < N; j++ {
  				// Write a pointer using memmove.
  				copy(collider[i:i+1], ptrs[i:i+1])
  				// Write nil using memclr.
  				// (This is a magic loop that gets lowered to memclr.)
  				r := collider[i : i+1]
  				for k := range r {
  					r[k] = nil
  				}
  			}
  			done <- struct{}{}
  		}()
  	}
  	// Start readers.  They read pointers from slots
  	// and make sure they are valid.
  	for i := 0; i < p; i++ {
  		i := i
  		go func() {
  			for j := 0; j < N; j++ {
  				var ptr [1]*int
  				copy(ptr[:], collider[i:i+1])
  				if ptr[0] != nil && ptr[0] != ptrs[i] {
  					panic(fmt.Sprintf("bad pointer read %p!", ptr[0]))
  				}
  			}
  			done <- struct{}{}
  		}()
  	}
  	for i := 0; i < 2*p; i++ {
  		<-done
  	}
  }
  

View as plain text