github.com/c12o16h1/go/src@v0.0.0-20200114212001-5a151c0f00ed/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 Load8(ptr *uint8) uint8 { 51 return *ptr 52 } 53 54 //go:nosplit 55 //go:noinline 56 func Load64(ptr *uint64) uint64 { 57 return *ptr 58 } 59 60 //go:nosplit 61 //go:noinline 62 func Xadd(ptr *uint32, delta int32) uint32 { 63 new := *ptr + uint32(delta) 64 *ptr = new 65 return new 66 } 67 68 //go:nosplit 69 //go:noinline 70 func Xadd64(ptr *uint64, delta int64) uint64 { 71 new := *ptr + uint64(delta) 72 *ptr = new 73 return new 74 } 75 76 //go:nosplit 77 //go:noinline 78 func Xadduintptr(ptr *uintptr, delta uintptr) uintptr { 79 new := *ptr + delta 80 *ptr = new 81 return new 82 } 83 84 //go:nosplit 85 //go:noinline 86 func Xchg(ptr *uint32, new uint32) uint32 { 87 old := *ptr 88 *ptr = new 89 return old 90 } 91 92 //go:nosplit 93 //go:noinline 94 func Xchg64(ptr *uint64, new uint64) uint64 { 95 old := *ptr 96 *ptr = new 97 return old 98 } 99 100 //go:nosplit 101 //go:noinline 102 func Xchguintptr(ptr *uintptr, new uintptr) uintptr { 103 old := *ptr 104 *ptr = new 105 return old 106 } 107 108 //go:nosplit 109 //go:noinline 110 func And8(ptr *uint8, val uint8) { 111 *ptr = *ptr & val 112 } 113 114 //go:nosplit 115 //go:noinline 116 func Or8(ptr *uint8, val uint8) { 117 *ptr = *ptr | val 118 } 119 120 // NOTE: Do not add atomicxor8 (XOR is not idempotent). 121 122 //go:nosplit 123 //go:noinline 124 func Cas64(ptr *uint64, old, new uint64) bool { 125 if *ptr == old { 126 *ptr = new 127 return true 128 } 129 return false 130 } 131 132 //go:nosplit 133 //go:noinline 134 func Store(ptr *uint32, val uint32) { 135 *ptr = val 136 } 137 138 //go:nosplit 139 //go:noinline 140 func StoreRel(ptr *uint32, val uint32) { 141 *ptr = val 142 } 143 144 //go:nosplit 145 //go:noinline 146 func Store8(ptr *uint8, val uint8) { 147 *ptr = val 148 } 149 150 //go:nosplit 151 //go:noinline 152 func Store64(ptr *uint64, val uint64) { 153 *ptr = val 154 } 155 156 //go:notinheap 157 type noWB struct{} 158 159 //go:noinline 160 //go:nosplit 161 func StorepNoWB(ptr unsafe.Pointer, val unsafe.Pointer) { 162 *(**noWB)(ptr) = (*noWB)(val) 163 } 164 165 //go:nosplit 166 //go:noinline 167 func Cas(ptr *uint32, old, new uint32) bool { 168 if *ptr == old { 169 *ptr = new 170 return true 171 } 172 return false 173 } 174 175 //go:nosplit 176 //go:noinline 177 func Casp1(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool { 178 if *ptr == old { 179 *ptr = new 180 return true 181 } 182 return false 183 } 184 185 //go:nosplit 186 //go:noinline 187 func Casuintptr(ptr *uintptr, old, new uintptr) bool { 188 if *ptr == old { 189 *ptr = new 190 return true 191 } 192 return false 193 } 194 195 //go:nosplit 196 //go:noinline 197 func CasRel(ptr *uint32, old, new uint32) bool { 198 if *ptr == old { 199 *ptr = new 200 return true 201 } 202 return false 203 } 204 205 //go:nosplit 206 //go:noinline 207 func Storeuintptr(ptr *uintptr, new uintptr) { 208 *ptr = new 209 } 210 211 //go:nosplit 212 //go:noinline 213 func Loaduintptr(ptr *uintptr) uintptr { 214 return *ptr 215 } 216 217 //go:nosplit 218 //go:noinline 219 func Loaduint(ptr *uint) uint { 220 return *ptr 221 } 222 223 //go:nosplit 224 //go:noinline 225 func Loadint64(ptr *int64) int64 { 226 return *ptr 227 } 228 229 //go:nosplit 230 //go:noinline 231 func Xaddint64(ptr *int64, delta int64) int64 { 232 new := *ptr + delta 233 *ptr = new 234 return new 235 }