Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / libgo / go / sync / atomic / race.go
1 // Copyright 2011 The Go Authors.  All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // +build race
6
7 package atomic
8
9 import (
10         "runtime"
11         "unsafe"
12 )
13
14 // We use runtime.RaceRead() inside of atomic operations to catch races
15 // between atomic and non-atomic operations.  It will also catch races
16 // between Mutex.Lock() and mutex overwrite (mu = Mutex{}).  Since we use
17 // only RaceRead() we won't catch races with non-atomic loads.
18 // Otherwise (if we use RaceWrite()) we will report races
19 // between atomic operations (false positives).
20
21 var mtx uint32 = 1 // same for all
22
23 func CompareAndSwapInt32(val *int32, old, new int32) bool {
24         return CompareAndSwapUint32((*uint32)(unsafe.Pointer(val)), uint32(old), uint32(new))
25 }
26
27 func CompareAndSwapUint32(val *uint32, old, new uint32) (swapped bool) {
28         swapped = false
29         runtime.RaceSemacquire(&mtx)
30         runtime.RaceRead(unsafe.Pointer(val))
31         runtime.RaceAcquire(unsafe.Pointer(val))
32         if *val == old {
33                 *val = new
34                 swapped = true
35                 runtime.RaceReleaseMerge(unsafe.Pointer(val))
36         }
37         runtime.RaceSemrelease(&mtx)
38         return
39 }
40
41 func CompareAndSwapInt64(val *int64, old, new int64) bool {
42         return CompareAndSwapUint64((*uint64)(unsafe.Pointer(val)), uint64(old), uint64(new))
43 }
44
45 func CompareAndSwapUint64(val *uint64, old, new uint64) (swapped bool) {
46         swapped = false
47         runtime.RaceSemacquire(&mtx)
48         runtime.RaceRead(unsafe.Pointer(val))
49         runtime.RaceAcquire(unsafe.Pointer(val))
50         if *val == old {
51                 *val = new
52                 swapped = true
53                 runtime.RaceReleaseMerge(unsafe.Pointer(val))
54         }
55         runtime.RaceSemrelease(&mtx)
56         return
57 }
58
59 func CompareAndSwapPointer(val *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool) {
60         swapped = false
61         runtime.RaceSemacquire(&mtx)
62         runtime.RaceRead(unsafe.Pointer(val))
63         runtime.RaceAcquire(unsafe.Pointer(val))
64         if *val == old {
65                 *val = new
66                 swapped = true
67                 runtime.RaceReleaseMerge(unsafe.Pointer(val))
68         }
69         runtime.RaceSemrelease(&mtx)
70         return
71 }
72
73 func CompareAndSwapUintptr(val *uintptr, old, new uintptr) (swapped bool) {
74         swapped = false
75         runtime.RaceSemacquire(&mtx)
76         runtime.RaceRead(unsafe.Pointer(val))
77         runtime.RaceAcquire(unsafe.Pointer(val))
78         if *val == old {
79                 *val = new
80                 swapped = true
81                 runtime.RaceReleaseMerge(unsafe.Pointer(val))
82         }
83         runtime.RaceSemrelease(&mtx)
84         return
85 }
86
87 func AddInt32(val *int32, delta int32) int32 {
88         return int32(AddUint32((*uint32)(unsafe.Pointer(val)), uint32(delta)))
89 }
90
91 func AddUint32(val *uint32, delta uint32) (new uint32) {
92         runtime.RaceSemacquire(&mtx)
93         runtime.RaceRead(unsafe.Pointer(val))
94         runtime.RaceAcquire(unsafe.Pointer(val))
95         *val = *val + delta
96         new = *val
97         runtime.RaceReleaseMerge(unsafe.Pointer(val))
98         runtime.RaceSemrelease(&mtx)
99
100         return
101 }
102
103 func AddInt64(val *int64, delta int64) int64 {
104         return int64(AddUint64((*uint64)(unsafe.Pointer(val)), uint64(delta)))
105 }
106
107 func AddUint64(val *uint64, delta uint64) (new uint64) {
108         runtime.RaceSemacquire(&mtx)
109         runtime.RaceRead(unsafe.Pointer(val))
110         runtime.RaceAcquire(unsafe.Pointer(val))
111         *val = *val + delta
112         new = *val
113         runtime.RaceReleaseMerge(unsafe.Pointer(val))
114         runtime.RaceSemrelease(&mtx)
115
116         return
117 }
118
119 func AddUintptr(val *uintptr, delta uintptr) (new uintptr) {
120         runtime.RaceSemacquire(&mtx)
121         runtime.RaceRead(unsafe.Pointer(val))
122         runtime.RaceAcquire(unsafe.Pointer(val))
123         *val = *val + delta
124         new = *val
125         runtime.RaceReleaseMerge(unsafe.Pointer(val))
126         runtime.RaceSemrelease(&mtx)
127
128         return
129 }
130
131 func LoadInt32(addr *int32) int32 {
132         return int32(LoadUint32((*uint32)(unsafe.Pointer(addr))))
133 }
134
135 func LoadUint32(addr *uint32) (val uint32) {
136         runtime.RaceSemacquire(&mtx)
137         runtime.RaceRead(unsafe.Pointer(addr))
138         runtime.RaceAcquire(unsafe.Pointer(addr))
139         val = *addr
140         runtime.RaceSemrelease(&mtx)
141         return
142 }
143
144 func LoadInt64(addr *int64) int64 {
145         return int64(LoadUint64((*uint64)(unsafe.Pointer(addr))))
146 }
147
148 func LoadUint64(addr *uint64) (val uint64) {
149         runtime.RaceSemacquire(&mtx)
150         runtime.RaceRead(unsafe.Pointer(addr))
151         runtime.RaceAcquire(unsafe.Pointer(addr))
152         val = *addr
153         runtime.RaceSemrelease(&mtx)
154         return
155 }
156
157 func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer) {
158         runtime.RaceSemacquire(&mtx)
159         runtime.RaceRead(unsafe.Pointer(addr))
160         runtime.RaceAcquire(unsafe.Pointer(addr))
161         val = *addr
162         runtime.RaceSemrelease(&mtx)
163         return
164 }
165
166 func LoadUintptr(addr *uintptr) (val uintptr) {
167         runtime.RaceSemacquire(&mtx)
168         runtime.RaceRead(unsafe.Pointer(addr))
169         runtime.RaceAcquire(unsafe.Pointer(addr))
170         val = *addr
171         runtime.RaceSemrelease(&mtx)
172         return
173 }
174
175 func StoreInt32(addr *int32, val int32) {
176         StoreUint32((*uint32)(unsafe.Pointer(addr)), uint32(val))
177 }
178
179 func StoreUint32(addr *uint32, val uint32) {
180         runtime.RaceSemacquire(&mtx)
181         runtime.RaceRead(unsafe.Pointer(addr))
182         *addr = val
183         runtime.RaceRelease(unsafe.Pointer(addr))
184         runtime.RaceSemrelease(&mtx)
185 }
186
187 func StoreInt64(addr *int64, val int64) {
188         StoreUint64((*uint64)(unsafe.Pointer(addr)), uint64(val))
189 }
190
191 func StoreUint64(addr *uint64, val uint64) {
192         runtime.RaceSemacquire(&mtx)
193         runtime.RaceRead(unsafe.Pointer(addr))
194         *addr = val
195         runtime.RaceRelease(unsafe.Pointer(addr))
196         runtime.RaceSemrelease(&mtx)
197 }
198
199 func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer) {
200         runtime.RaceSemacquire(&mtx)
201         runtime.RaceRead(unsafe.Pointer(addr))
202         *addr = val
203         runtime.RaceRelease(unsafe.Pointer(addr))
204         runtime.RaceSemrelease(&mtx)
205 }
206
207 func StoreUintptr(addr *uintptr, val uintptr) {
208         runtime.RaceSemacquire(&mtx)
209         runtime.RaceRead(unsafe.Pointer(addr))
210         *addr = val
211         runtime.RaceRelease(unsafe.Pointer(addr))
212         runtime.RaceSemrelease(&mtx)
213 }