Source file
src/runtime/race/race_linux_test.go
1
2
3
4
5
6
7 package race_test
8
9 import (
10 "sync/atomic"
11 "syscall"
12 "testing"
13 "unsafe"
14 )
15
16 func TestAtomicMmap(t *testing.T) {
17
18
19
20 mem, err := syscall.Mmap(-1, 0, 1<<20, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_ANON|syscall.MAP_PRIVATE)
21 if err != nil {
22 t.Fatalf("mmap failed: %v", err)
23 }
24 defer syscall.Munmap(mem)
25 a := (*uint64)(unsafe.Pointer(&mem[0]))
26 if *a != 0 {
27 t.Fatalf("bad atomic value: %v, want 0", *a)
28 }
29 atomic.AddUint64(a, 1)
30 if *a != 1 {
31 t.Fatalf("bad atomic value: %v, want 1", *a)
32 }
33 atomic.AddUint64(a, 1)
34 if *a != 2 {
35 t.Fatalf("bad atomic value: %v, want 2", *a)
36 }
37 }
38
39 func TestAtomicPageBoundary(t *testing.T) {
40
41
42
43
44
45 pagesize := syscall.Getpagesize()
46 b, err := syscall.Mmap(0, 0, 2*pagesize, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_ANON|syscall.MAP_PRIVATE)
47 if err != nil {
48 t.Fatalf("mmap failed %s", err)
49 }
50 defer syscall.Munmap(b)
51 err = syscall.Mprotect(b[pagesize:], syscall.PROT_NONE)
52 if err != nil {
53 t.Fatalf("mprotect high failed %s\n", err)
54 }
55
56
57 a := (*uint32)(unsafe.Pointer(&b[pagesize-4]))
58 atomic.StoreUint32(a, 1)
59 if x := atomic.LoadUint32(a); x != 1 {
60 t.Fatalf("bad atomic value: %v, want 1", x)
61 }
62 if x := atomic.AddUint32(a, 1); x != 2 {
63 t.Fatalf("bad atomic value: %v, want 2", x)
64 }
65 }
66
View as plain text