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 } 71