diff options
Diffstat (limited to 'test/fixedbugs/issue13160.go')
-rw-r--r-- | test/fixedbugs/issue13160.go | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/test/fixedbugs/issue13160.go b/test/fixedbugs/issue13160.go new file mode 100644 index 0000000..c21ecf6 --- /dev/null +++ b/test/fixedbugs/issue13160.go @@ -0,0 +1,70 @@ +// 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 + } +} |