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.
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).
21 var mtx uint32 = 1 // same for all
23 func CompareAndSwapInt32(val *int32, old, new int32) bool {
24 return CompareAndSwapUint32((*uint32)(unsafe.Pointer(val)), uint32(old), uint32(new))
27 func CompareAndSwapUint32(val *uint32, old, new uint32) (swapped bool) {
29 runtime.RaceSemacquire(&mtx)
30 runtime.RaceRead(unsafe.Pointer(val))
31 runtime.RaceAcquire(unsafe.Pointer(val))
35 runtime.RaceReleaseMerge(unsafe.Pointer(val))
37 runtime.RaceSemrelease(&mtx)
41 func CompareAndSwapInt64(val *int64, old, new int64) bool {
42 return CompareAndSwapUint64((*uint64)(unsafe.Pointer(val)), uint64(old), uint64(new))
45 func CompareAndSwapUint64(val *uint64, old, new uint64) (swapped bool) {
47 runtime.RaceSemacquire(&mtx)
48 runtime.RaceRead(unsafe.Pointer(val))
49 runtime.RaceAcquire(unsafe.Pointer(val))
53 runtime.RaceReleaseMerge(unsafe.Pointer(val))
55 runtime.RaceSemrelease(&mtx)
59 func CompareAndSwapPointer(val *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool) {
61 runtime.RaceSemacquire(&mtx)
62 runtime.RaceRead(unsafe.Pointer(val))
63 runtime.RaceAcquire(unsafe.Pointer(val))
67 runtime.RaceReleaseMerge(unsafe.Pointer(val))
69 runtime.RaceSemrelease(&mtx)
73 func CompareAndSwapUintptr(val *uintptr, old, new uintptr) (swapped bool) {
75 runtime.RaceSemacquire(&mtx)
76 runtime.RaceRead(unsafe.Pointer(val))
77 runtime.RaceAcquire(unsafe.Pointer(val))
81 runtime.RaceReleaseMerge(unsafe.Pointer(val))
83 runtime.RaceSemrelease(&mtx)
87 func AddInt32(val *int32, delta int32) int32 {
88 return int32(AddUint32((*uint32)(unsafe.Pointer(val)), uint32(delta)))
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))
97 runtime.RaceReleaseMerge(unsafe.Pointer(val))
98 runtime.RaceSemrelease(&mtx)
103 func AddInt64(val *int64, delta int64) int64 {
104 return int64(AddUint64((*uint64)(unsafe.Pointer(val)), uint64(delta)))
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))
113 runtime.RaceReleaseMerge(unsafe.Pointer(val))
114 runtime.RaceSemrelease(&mtx)
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))
125 runtime.RaceReleaseMerge(unsafe.Pointer(val))
126 runtime.RaceSemrelease(&mtx)
131 func LoadInt32(addr *int32) int32 {
132 return int32(LoadUint32((*uint32)(unsafe.Pointer(addr))))
135 func LoadUint32(addr *uint32) (val uint32) {
136 runtime.RaceSemacquire(&mtx)
137 runtime.RaceRead(unsafe.Pointer(addr))
138 runtime.RaceAcquire(unsafe.Pointer(addr))
140 runtime.RaceSemrelease(&mtx)
144 func LoadInt64(addr *int64) int64 {
145 return int64(LoadUint64((*uint64)(unsafe.Pointer(addr))))
148 func LoadUint64(addr *uint64) (val uint64) {
149 runtime.RaceSemacquire(&mtx)
150 runtime.RaceRead(unsafe.Pointer(addr))
151 runtime.RaceAcquire(unsafe.Pointer(addr))
153 runtime.RaceSemrelease(&mtx)
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))
162 runtime.RaceSemrelease(&mtx)
166 func LoadUintptr(addr *uintptr) (val uintptr) {
167 runtime.RaceSemacquire(&mtx)
168 runtime.RaceRead(unsafe.Pointer(addr))
169 runtime.RaceAcquire(unsafe.Pointer(addr))
171 runtime.RaceSemrelease(&mtx)
175 func StoreInt32(addr *int32, val int32) {
176 StoreUint32((*uint32)(unsafe.Pointer(addr)), uint32(val))
179 func StoreUint32(addr *uint32, val uint32) {
180 runtime.RaceSemacquire(&mtx)
181 runtime.RaceRead(unsafe.Pointer(addr))
183 runtime.RaceRelease(unsafe.Pointer(addr))
184 runtime.RaceSemrelease(&mtx)
187 func StoreInt64(addr *int64, val int64) {
188 StoreUint64((*uint64)(unsafe.Pointer(addr)), uint64(val))
191 func StoreUint64(addr *uint64, val uint64) {
192 runtime.RaceSemacquire(&mtx)
193 runtime.RaceRead(unsafe.Pointer(addr))
195 runtime.RaceRelease(unsafe.Pointer(addr))
196 runtime.RaceSemrelease(&mtx)
199 func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer) {
200 runtime.RaceSemacquire(&mtx)
201 runtime.RaceRead(unsafe.Pointer(addr))
203 runtime.RaceRelease(unsafe.Pointer(addr))
204 runtime.RaceSemrelease(&mtx)
207 func StoreUintptr(addr *uintptr, val uintptr) {
208 runtime.RaceSemacquire(&mtx)
209 runtime.RaceRead(unsafe.Pointer(addr))
211 runtime.RaceRelease(unsafe.Pointer(addr))
212 runtime.RaceSemrelease(&mtx)