]> Cypherpunks.ru repositories - gostls13.git/blob - test/fixedbugs/issue13160.go
7eb4811373c32863da12d615b5962c47bfae8c52
[gostls13.git] / test / fixedbugs / issue13160.go
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 }