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