github.com/primecitizens/pcz/std@v0.2.1/core/atomic/atomic_wasm.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright 2023 The Prime Citizens 3 // 4 // Copyright 2018 The Go Authors. All rights reserved. 5 // Use of this source code is governed by a BSD-style 6 // license that can be found in the LICENSE file. 7 8 // TODO(neelance): implement with actual atomic operations as soon as threads are available 9 // See https://github.com/WebAssembly/design/issues/1073 10 11 //go:build wasm 12 13 package atomic 14 15 import "unsafe" 16 17 //go:nosplit 18 //go:noinline 19 func PublicationBarrier() {} 20 21 // 22 // Store 23 // 24 25 //go:nosplit 26 //go:noinline 27 func Store8(ptr *uint8, val uint8) { 28 *ptr = val 29 } 30 31 //go:nosplit 32 //go:noinline 33 func Store32(ptr *uint32, val uint32) { 34 *ptr = val 35 } 36 37 //go:nosplit 38 //go:noinline 39 func Store64(ptr *uint64, val uint64) { 40 *ptr = val 41 } 42 43 //go:nosplit 44 //go:noinline 45 func StoreUintptr(ptr *uintptr, new uintptr) { 46 *ptr = new 47 } 48 49 // StorePointer performs *ptr = val atomically and without a write 50 // barrier. 51 // 52 // NO go:noescape annotation; see atomic_pointer.go. 53 func StorePointer(ptr unsafe.Pointer, val unsafe.Pointer) 54 55 //go:nosplit 56 //go:noinline 57 func StoreInt32(ptr *int32, new int32) { 58 *ptr = new 59 } 60 61 //go:nosplit 62 //go:noinline 63 func StoreInt64(ptr *int64, new int64) { 64 *ptr = new 65 } 66 67 // 68 // StoreRel 69 // 70 71 //go:nosplit 72 //go:noinline 73 func StoreRel32(ptr *uint32, val uint32) { 74 *ptr = val 75 } 76 77 //go:nosplit 78 //go:noinline 79 func StoreRel64(ptr *uint64, val uint64) { 80 *ptr = val 81 } 82 83 //go:nosplit 84 //go:noinline 85 func StoreRelUintptr(ptr *uintptr, val uintptr) { 86 *ptr = val 87 } 88 89 // 90 // Load 91 // 92 93 //go:nosplit 94 //go:noinline 95 func Load8(ptr *uint8) uint8 { 96 return *ptr 97 } 98 99 //go:nosplit 100 //go:noinline 101 func Load32(ptr *uint32) uint32 { 102 return *ptr 103 } 104 105 //go:nosplit 106 //go:noinline 107 func Load64(ptr *uint64) uint64 { 108 return *ptr 109 } 110 111 //go:nosplit 112 //go:noinline 113 func LoadUint(ptr *uint) uint { 114 return *ptr 115 } 116 117 //go:nosplit 118 //go:noinline 119 func LoadUintptr(ptr *uintptr) uintptr { 120 return *ptr 121 } 122 123 //go:nosplit 124 //go:noinline 125 func LoadPointer(ptr unsafe.Pointer) unsafe.Pointer { 126 return *(*unsafe.Pointer)(ptr) 127 } 128 129 //go:nosplit 130 //go:noinline 131 func LoadInt32(ptr *int32) int32 { 132 return *ptr 133 } 134 135 //go:nosplit 136 //go:noinline 137 func LoadInt64(ptr *int64) int64 { 138 return *ptr 139 } 140 141 // 142 // LoadAcq 143 // 144 145 //go:nosplit 146 //go:noinline 147 func LoadAcq32(ptr *uint32) uint32 { 148 return *ptr 149 } 150 151 //go:nosplit 152 //go:noinline 153 func LoadAcq64(ptr *uint64) uint64 { 154 return *ptr 155 } 156 157 //go:nosplit 158 //go:noinline 159 func LoadAcqUintptr(ptr *uintptr) uintptr { 160 return *ptr 161 } 162 163 // 164 // bitwise 165 // 166 // NOTE: Do not add atomicxor8 (XOR is not idempotent). 167 168 //go:nosplit 169 //go:noinline 170 func And8(ptr *uint8, val uint8) { 171 *ptr = *ptr & val 172 } 173 174 //go:nosplit 175 //go:noinline 176 func And32(ptr *uint32, val uint32) { 177 *ptr = *ptr & val 178 } 179 180 //go:nosplit 181 //go:noinline 182 func Or8(ptr *uint8, val uint8) { 183 *ptr = *ptr | val 184 } 185 186 //go:nosplit 187 //go:noinline 188 func Or32(ptr *uint32, val uint32) { 189 *ptr = *ptr | val 190 } 191 192 // 193 // Swap 194 // 195 196 //go:nosplit 197 //go:noinline 198 func Swap32(ptr *uint32, new uint32) uint32 { 199 old := *ptr 200 *ptr = new 201 return old 202 } 203 204 //go:nosplit 205 //go:noinline 206 func Swap64(ptr *uint64, new uint64) uint64 { 207 old := *ptr 208 *ptr = new 209 return old 210 } 211 212 //go:nosplit 213 //go:noinline 214 func SwapUintptr(ptr *uintptr, new uintptr) uintptr { 215 old := *ptr 216 *ptr = new 217 return old 218 } 219 220 //go:nosplit 221 //go:noinline 222 func SwapInt32(ptr *int32, new int32) int32 { 223 old := *ptr 224 *ptr = new 225 return old 226 } 227 228 //go:nosplit 229 //go:noinline 230 func SwapInt64(ptr *int64, new int64) int64 { 231 old := *ptr 232 *ptr = new 233 return old 234 } 235 236 // 237 // Add 238 // 239 240 //go:nosplit 241 //go:noinline 242 func Add32(ptr *uint32, delta int32) uint32 { 243 new := *ptr + uint32(delta) 244 *ptr = new 245 return new 246 } 247 248 //go:nosplit 249 //go:noinline 250 func Add64(ptr *uint64, delta int64) uint64 { 251 new := *ptr + uint64(delta) 252 *ptr = new 253 return new 254 } 255 256 //go:nosplit 257 //go:noinline 258 func AddUintptr(ptr *uintptr, delta uintptr) uintptr { 259 new := *ptr + delta 260 *ptr = new 261 return new 262 } 263 264 //go:nosplit 265 //go:noinline 266 func AddInt32(ptr *int32, delta int32) int32 { 267 new := *ptr + delta 268 *ptr = new 269 return new 270 } 271 272 //go:nosplit 273 //go:noinline 274 func AddInt64(ptr *int64, delta int64) int64 { 275 new := *ptr + delta 276 *ptr = new 277 return new 278 } 279 280 // 281 // Compare and swap 282 // 283 284 //go:nosplit 285 //go:noinline 286 func Cas32(ptr *uint32, old, new uint32) bool { 287 if *ptr == old { 288 *ptr = new 289 return true 290 } 291 return false 292 } 293 294 //go:nosplit 295 //go:noinline 296 func Cas64(ptr *uint64, old, new uint64) bool { 297 if *ptr == old { 298 *ptr = new 299 return true 300 } 301 return false 302 } 303 304 //go:nosplit 305 //go:noinline 306 func CasUintptr(ptr *uintptr, old, new uintptr) bool { 307 if *ptr == old { 308 *ptr = new 309 return true 310 } 311 return false 312 } 313 314 //go:nosplit 315 //go:noinline 316 func CasUnsafePointer(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool { 317 if *ptr == old { 318 *ptr = new 319 return true 320 } 321 return false 322 } 323 324 //go:nosplit 325 //go:noinline 326 func CasInt32(ptr *int32, old, new int32) bool { 327 if *ptr == old { 328 *ptr = new 329 return true 330 } 331 return false 332 } 333 334 //go:nosplit 335 //go:noinline 336 func CasInt64(ptr *int64, old, new int64) bool { 337 if *ptr == old { 338 *ptr = new 339 return true 340 } 341 return false 342 } 343 344 // 345 // CasRel 346 // 347 348 //go:nosplit 349 //go:noinline 350 func CasRel32(ptr *uint32, old, new uint32) bool { 351 if *ptr == old { 352 *ptr = new 353 return true 354 } 355 return false 356 }