github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/pkg/sync/atomic/race.go (about) 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 SwapInt32(addr *int32, new int32) (old int32) { 24 return int32(SwapUint32((*uint32)(unsafe.Pointer(addr)), uint32(new))) 25 } 26 27 func SwapUint32(addr *uint32, new uint32) (old uint32) { 28 _ = *addr 29 runtime.RaceSemacquire(&mtx) 30 runtime.RaceRead(unsafe.Pointer(addr)) 31 runtime.RaceAcquire(unsafe.Pointer(addr)) 32 old = *addr 33 *addr = new 34 runtime.RaceReleaseMerge(unsafe.Pointer(addr)) 35 runtime.RaceSemrelease(&mtx) 36 return 37 } 38 39 func SwapInt64(addr *int64, new int64) (old int64) { 40 return int64(SwapUint64((*uint64)(unsafe.Pointer(addr)), uint64(new))) 41 } 42 43 func SwapUint64(addr *uint64, new uint64) (old uint64) { 44 _ = *addr 45 runtime.RaceSemacquire(&mtx) 46 runtime.RaceRead(unsafe.Pointer(addr)) 47 runtime.RaceAcquire(unsafe.Pointer(addr)) 48 old = *addr 49 *addr = new 50 runtime.RaceReleaseMerge(unsafe.Pointer(addr)) 51 runtime.RaceSemrelease(&mtx) 52 return 53 } 54 55 func SwapUintptr(addr *uintptr, new uintptr) (old uintptr) { 56 return uintptr(SwapPointer((*unsafe.Pointer)(unsafe.Pointer(addr)), unsafe.Pointer(new))) 57 } 58 59 func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer) { 60 _ = *addr 61 runtime.RaceSemacquire(&mtx) 62 runtime.RaceRead(unsafe.Pointer(addr)) 63 runtime.RaceAcquire(unsafe.Pointer(addr)) 64 old = *addr 65 *addr = new 66 runtime.RaceReleaseMerge(unsafe.Pointer(addr)) 67 runtime.RaceSemrelease(&mtx) 68 return 69 } 70 71 func CompareAndSwapInt32(val *int32, old, new int32) bool { 72 return CompareAndSwapUint32((*uint32)(unsafe.Pointer(val)), uint32(old), uint32(new)) 73 } 74 75 func CompareAndSwapUint32(val *uint32, old, new uint32) (swapped bool) { 76 _ = *val 77 swapped = false 78 runtime.RaceSemacquire(&mtx) 79 runtime.RaceRead(unsafe.Pointer(val)) 80 runtime.RaceAcquire(unsafe.Pointer(val)) 81 if *val == old { 82 *val = new 83 swapped = true 84 runtime.RaceReleaseMerge(unsafe.Pointer(val)) 85 } 86 runtime.RaceSemrelease(&mtx) 87 return 88 } 89 90 func CompareAndSwapInt64(val *int64, old, new int64) bool { 91 return CompareAndSwapUint64((*uint64)(unsafe.Pointer(val)), uint64(old), uint64(new)) 92 } 93 94 func CompareAndSwapUint64(val *uint64, old, new uint64) (swapped bool) { 95 _ = *val 96 swapped = false 97 runtime.RaceSemacquire(&mtx) 98 runtime.RaceRead(unsafe.Pointer(val)) 99 runtime.RaceAcquire(unsafe.Pointer(val)) 100 if *val == old { 101 *val = new 102 swapped = true 103 runtime.RaceReleaseMerge(unsafe.Pointer(val)) 104 } 105 runtime.RaceSemrelease(&mtx) 106 return 107 } 108 109 func CompareAndSwapPointer(val *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool) { 110 _ = *val 111 swapped = false 112 runtime.RaceSemacquire(&mtx) 113 runtime.RaceRead(unsafe.Pointer(val)) 114 runtime.RaceAcquire(unsafe.Pointer(val)) 115 if *val == old { 116 *val = new 117 swapped = true 118 runtime.RaceReleaseMerge(unsafe.Pointer(val)) 119 } 120 runtime.RaceSemrelease(&mtx) 121 return 122 } 123 124 func CompareAndSwapUintptr(val *uintptr, old, new uintptr) (swapped bool) { 125 _ = *val 126 swapped = false 127 runtime.RaceSemacquire(&mtx) 128 runtime.RaceRead(unsafe.Pointer(val)) 129 runtime.RaceAcquire(unsafe.Pointer(val)) 130 if *val == old { 131 *val = new 132 swapped = true 133 runtime.RaceReleaseMerge(unsafe.Pointer(val)) 134 } 135 runtime.RaceSemrelease(&mtx) 136 return 137 } 138 139 func AddInt32(val *int32, delta int32) int32 { 140 return int32(AddUint32((*uint32)(unsafe.Pointer(val)), uint32(delta))) 141 } 142 143 func AddUint32(val *uint32, delta uint32) (new uint32) { 144 _ = *val 145 runtime.RaceSemacquire(&mtx) 146 runtime.RaceRead(unsafe.Pointer(val)) 147 runtime.RaceAcquire(unsafe.Pointer(val)) 148 *val = *val + delta 149 new = *val 150 runtime.RaceReleaseMerge(unsafe.Pointer(val)) 151 runtime.RaceSemrelease(&mtx) 152 153 return 154 } 155 156 func AddInt64(val *int64, delta int64) int64 { 157 return int64(AddUint64((*uint64)(unsafe.Pointer(val)), uint64(delta))) 158 } 159 160 func AddUint64(val *uint64, delta uint64) (new uint64) { 161 _ = *val 162 runtime.RaceSemacquire(&mtx) 163 runtime.RaceRead(unsafe.Pointer(val)) 164 runtime.RaceAcquire(unsafe.Pointer(val)) 165 *val = *val + delta 166 new = *val 167 runtime.RaceReleaseMerge(unsafe.Pointer(val)) 168 runtime.RaceSemrelease(&mtx) 169 170 return 171 } 172 173 func AddUintptr(val *uintptr, delta uintptr) (new uintptr) { 174 _ = *val 175 runtime.RaceSemacquire(&mtx) 176 runtime.RaceRead(unsafe.Pointer(val)) 177 runtime.RaceAcquire(unsafe.Pointer(val)) 178 *val = *val + delta 179 new = *val 180 runtime.RaceReleaseMerge(unsafe.Pointer(val)) 181 runtime.RaceSemrelease(&mtx) 182 183 return 184 } 185 186 func LoadInt32(addr *int32) int32 { 187 return int32(LoadUint32((*uint32)(unsafe.Pointer(addr)))) 188 } 189 190 func LoadUint32(addr *uint32) (val uint32) { 191 _ = *addr 192 runtime.RaceSemacquire(&mtx) 193 runtime.RaceRead(unsafe.Pointer(addr)) 194 runtime.RaceAcquire(unsafe.Pointer(addr)) 195 val = *addr 196 runtime.RaceSemrelease(&mtx) 197 return 198 } 199 200 func LoadInt64(addr *int64) int64 { 201 return int64(LoadUint64((*uint64)(unsafe.Pointer(addr)))) 202 } 203 204 func LoadUint64(addr *uint64) (val uint64) { 205 _ = *addr 206 runtime.RaceSemacquire(&mtx) 207 runtime.RaceRead(unsafe.Pointer(addr)) 208 runtime.RaceAcquire(unsafe.Pointer(addr)) 209 val = *addr 210 runtime.RaceSemrelease(&mtx) 211 return 212 } 213 214 func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer) { 215 _ = *addr 216 runtime.RaceSemacquire(&mtx) 217 runtime.RaceRead(unsafe.Pointer(addr)) 218 runtime.RaceAcquire(unsafe.Pointer(addr)) 219 val = *addr 220 runtime.RaceSemrelease(&mtx) 221 return 222 } 223 224 func LoadUintptr(addr *uintptr) (val uintptr) { 225 _ = *addr 226 runtime.RaceSemacquire(&mtx) 227 runtime.RaceRead(unsafe.Pointer(addr)) 228 runtime.RaceAcquire(unsafe.Pointer(addr)) 229 val = *addr 230 runtime.RaceSemrelease(&mtx) 231 return 232 } 233 234 func StoreInt32(addr *int32, val int32) { 235 StoreUint32((*uint32)(unsafe.Pointer(addr)), uint32(val)) 236 } 237 238 func StoreUint32(addr *uint32, val uint32) { 239 _ = *addr 240 runtime.RaceSemacquire(&mtx) 241 runtime.RaceRead(unsafe.Pointer(addr)) 242 *addr = val 243 runtime.RaceRelease(unsafe.Pointer(addr)) 244 runtime.RaceSemrelease(&mtx) 245 } 246 247 func StoreInt64(addr *int64, val int64) { 248 StoreUint64((*uint64)(unsafe.Pointer(addr)), uint64(val)) 249 } 250 251 func StoreUint64(addr *uint64, val uint64) { 252 _ = *addr 253 runtime.RaceSemacquire(&mtx) 254 runtime.RaceRead(unsafe.Pointer(addr)) 255 *addr = val 256 runtime.RaceRelease(unsafe.Pointer(addr)) 257 runtime.RaceSemrelease(&mtx) 258 } 259 260 func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer) { 261 _ = *addr 262 runtime.RaceSemacquire(&mtx) 263 runtime.RaceRead(unsafe.Pointer(addr)) 264 *addr = val 265 runtime.RaceRelease(unsafe.Pointer(addr)) 266 runtime.RaceSemrelease(&mtx) 267 } 268 269 func StoreUintptr(addr *uintptr, val uintptr) { 270 _ = *addr 271 runtime.RaceSemacquire(&mtx) 272 runtime.RaceRead(unsafe.Pointer(addr)) 273 *addr = val 274 runtime.RaceRelease(unsafe.Pointer(addr)) 275 runtime.RaceSemrelease(&mtx) 276 }