github.com/code-reading/golang@v0.0.0-20220303082512-ba5bc0e589a3/go/src/runtime/internal/atomic/atomic_wasm.go (about) 1 // Copyright 2018 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 // TODO(neelance): implement with actual atomic operations as soon as threads are available 6 // See https://github.com/WebAssembly/design/issues/1073 7 8 // Export some functions via linkname to assembly in sync/atomic. 9 //go:linkname Load 10 //go:linkname Loadp 11 //go:linkname Load64 12 //go:linkname Loadint32 13 //go:linkname Loadint64 14 //go:linkname Loaduintptr 15 //go:linkname Xadd 16 //go:linkname Xaddint32 17 //go:linkname Xaddint64 18 //go:linkname Xadd64 19 //go:linkname Xadduintptr 20 //go:linkname Xchg 21 //go:linkname Xchg64 22 //go:linkname Xchgint32 23 //go:linkname Xchgint64 24 //go:linkname Xchguintptr 25 //go:linkname Cas 26 //go:linkname Cas64 27 //go:linkname Casint32 28 //go:linkname Casint64 29 //go:linkname Casuintptr 30 //go:linkname Store 31 //go:linkname Store64 32 //go:linkname Storeint32 33 //go:linkname Storeint64 34 //go:linkname Storeuintptr 35 36 package atomic 37 38 import "unsafe" 39 40 //go:nosplit 41 //go:noinline 42 func Load(ptr *uint32) uint32 { 43 return *ptr 44 } 45 46 //go:nosplit 47 //go:noinline 48 func Loadp(ptr unsafe.Pointer) unsafe.Pointer { 49 return *(*unsafe.Pointer)(ptr) 50 } 51 52 //go:nosplit 53 //go:noinline 54 func LoadAcq(ptr *uint32) uint32 { 55 return *ptr 56 } 57 58 //go:nosplit 59 //go:noinline 60 func LoadAcq64(ptr *uint64) uint64 { 61 return *ptr 62 } 63 64 //go:nosplit 65 //go:noinline 66 func LoadAcquintptr(ptr *uintptr) uintptr { 67 return *ptr 68 } 69 70 //go:nosplit 71 //go:noinline 72 func Load8(ptr *uint8) uint8 { 73 return *ptr 74 } 75 76 //go:nosplit 77 //go:noinline 78 func Load64(ptr *uint64) uint64 { 79 return *ptr 80 } 81 82 //go:nosplit 83 //go:noinline 84 func Xadd(ptr *uint32, delta int32) uint32 { 85 new := *ptr + uint32(delta) 86 *ptr = new 87 return new 88 } 89 90 //go:nosplit 91 //go:noinline 92 func Xadd64(ptr *uint64, delta int64) uint64 { 93 new := *ptr + uint64(delta) 94 *ptr = new 95 return new 96 } 97 98 //go:nosplit 99 //go:noinline 100 func Xadduintptr(ptr *uintptr, delta uintptr) uintptr { 101 new := *ptr + delta 102 *ptr = new 103 return new 104 } 105 106 //go:nosplit 107 //go:noinline 108 func Xchg(ptr *uint32, new uint32) uint32 { 109 old := *ptr 110 *ptr = new 111 return old 112 } 113 114 //go:nosplit 115 //go:noinline 116 func Xchg64(ptr *uint64, new uint64) uint64 { 117 old := *ptr 118 *ptr = new 119 return old 120 } 121 122 //go:nosplit 123 //go:noinline 124 func Xchgint32(ptr *int32, new int32) int32 { 125 old := *ptr 126 *ptr = new 127 return old 128 } 129 130 //go:nosplit 131 //go:noinline 132 func Xchgint64(ptr *int64, new int64) int64 { 133 old := *ptr 134 *ptr = new 135 return old 136 } 137 138 //go:nosplit 139 //go:noinline 140 func Xchguintptr(ptr *uintptr, new uintptr) uintptr { 141 old := *ptr 142 *ptr = new 143 return old 144 } 145 146 //go:nosplit 147 //go:noinline 148 func And8(ptr *uint8, val uint8) { 149 *ptr = *ptr & val 150 } 151 152 //go:nosplit 153 //go:noinline 154 func Or8(ptr *uint8, val uint8) { 155 *ptr = *ptr | val 156 } 157 158 // NOTE: Do not add atomicxor8 (XOR is not idempotent). 159 160 //go:nosplit 161 //go:noinline 162 func And(ptr *uint32, val uint32) { 163 *ptr = *ptr & val 164 } 165 166 //go:nosplit 167 //go:noinline 168 func Or(ptr *uint32, val uint32) { 169 *ptr = *ptr | val 170 } 171 172 //go:nosplit 173 //go:noinline 174 func Cas64(ptr *uint64, old, new uint64) bool { 175 if *ptr == old { 176 *ptr = new 177 return true 178 } 179 return false 180 } 181 182 //go:nosplit 183 //go:noinline 184 func Store(ptr *uint32, val uint32) { 185 *ptr = val 186 } 187 188 //go:nosplit 189 //go:noinline 190 func StoreRel(ptr *uint32, val uint32) { 191 *ptr = val 192 } 193 194 //go:nosplit 195 //go:noinline 196 func StoreRel64(ptr *uint64, val uint64) { 197 *ptr = val 198 } 199 200 //go:nosplit 201 //go:noinline 202 func StoreReluintptr(ptr *uintptr, val uintptr) { 203 *ptr = val 204 } 205 206 //go:nosplit 207 //go:noinline 208 func Store8(ptr *uint8, val uint8) { 209 *ptr = val 210 } 211 212 //go:nosplit 213 //go:noinline 214 func Store64(ptr *uint64, val uint64) { 215 *ptr = val 216 } 217 218 // StorepNoWB performs *ptr = val atomically and without a write 219 // barrier. 220 // 221 // NO go:noescape annotation; see atomic_pointer.go. 222 func StorepNoWB(ptr unsafe.Pointer, val unsafe.Pointer) 223 224 //go:nosplit 225 //go:noinline 226 func Casint32(ptr *int32, old, new int32) bool { 227 if *ptr == old { 228 *ptr = new 229 return true 230 } 231 return false 232 } 233 234 //go:nosplit 235 //go:noinline 236 func Casint64(ptr *int64, old, new int64) bool { 237 if *ptr == old { 238 *ptr = new 239 return true 240 } 241 return false 242 } 243 244 //go:nosplit 245 //go:noinline 246 func Cas(ptr *uint32, old, new uint32) bool { 247 if *ptr == old { 248 *ptr = new 249 return true 250 } 251 return false 252 } 253 254 //go:nosplit 255 //go:noinline 256 func Casp1(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool { 257 if *ptr == old { 258 *ptr = new 259 return true 260 } 261 return false 262 } 263 264 //go:nosplit 265 //go:noinline 266 func Casuintptr(ptr *uintptr, old, new uintptr) bool { 267 if *ptr == old { 268 *ptr = new 269 return true 270 } 271 return false 272 } 273 274 //go:nosplit 275 //go:noinline 276 func CasRel(ptr *uint32, old, new uint32) bool { 277 if *ptr == old { 278 *ptr = new 279 return true 280 } 281 return false 282 } 283 284 //go:nosplit 285 //go:noinline 286 func Storeint32(ptr *int32, new int32) { 287 *ptr = new 288 } 289 290 //go:nosplit 291 //go:noinline 292 func Storeint64(ptr *int64, new int64) { 293 *ptr = new 294 } 295 296 //go:nosplit 297 //go:noinline 298 func Storeuintptr(ptr *uintptr, new uintptr) { 299 *ptr = new 300 } 301 302 //go:nosplit 303 //go:noinline 304 func Loaduintptr(ptr *uintptr) uintptr { 305 return *ptr 306 } 307 308 //go:nosplit 309 //go:noinline 310 func Loaduint(ptr *uint) uint { 311 return *ptr 312 } 313 314 //go:nosplit 315 //go:noinline 316 func Loadint32(ptr *int32) int32 { 317 return *ptr 318 } 319 320 //go:nosplit 321 //go:noinline 322 func Loadint64(ptr *int64) int64 { 323 return *ptr 324 } 325 326 //go:nosplit 327 //go:noinline 328 func Xaddint32(ptr *int32, delta int32) int32 { 329 new := *ptr + delta 330 *ptr = new 331 return new 332 } 333 334 //go:nosplit 335 //go:noinline 336 func Xaddint64(ptr *int64, delta int64) int64 { 337 new := *ptr + delta 338 *ptr = new 339 return new 340 }