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