github.com/gopherjs/gopherjs@v1.19.0-beta1.0.20240506212314-27071a8796e4/compiler/natives/src/sync/atomic/atomic.go (about) 1 //go:build js 2 // +build js 3 4 package atomic 5 6 import ( 7 "unsafe" 8 9 "github.com/gopherjs/gopherjs/js" 10 ) 11 12 func SwapInt32(addr *int32, new int32) int32 { 13 old := *addr 14 *addr = new 15 return old 16 } 17 18 func SwapInt64(addr *int64, new int64) int64 { 19 old := *addr 20 *addr = new 21 return old 22 } 23 24 func SwapUint32(addr *uint32, new uint32) uint32 { 25 old := *addr 26 *addr = new 27 return old 28 } 29 30 func SwapUint64(addr *uint64, new uint64) uint64 { 31 old := *addr 32 *addr = new 33 return old 34 } 35 36 func SwapUintptr(addr *uintptr, new uintptr) uintptr { 37 old := *addr 38 *addr = new 39 return old 40 } 41 42 func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer { 43 old := *addr 44 *addr = new 45 return old 46 } 47 48 func CompareAndSwapInt32(addr *int32, old, new int32) bool { 49 if *addr == old { 50 *addr = new 51 return true 52 } 53 return false 54 } 55 56 func CompareAndSwapInt64(addr *int64, old, new int64) bool { 57 if *addr == old { 58 *addr = new 59 return true 60 } 61 return false 62 } 63 64 func CompareAndSwapUint32(addr *uint32, old, new uint32) bool { 65 if *addr == old { 66 *addr = new 67 return true 68 } 69 return false 70 } 71 72 func CompareAndSwapUint64(addr *uint64, old, new uint64) bool { 73 if *addr == old { 74 *addr = new 75 return true 76 } 77 return false 78 } 79 80 func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) bool { 81 if *addr == old { 82 *addr = new 83 return true 84 } 85 return false 86 } 87 88 func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) bool { 89 if *addr == old { 90 *addr = new 91 return true 92 } 93 return false 94 } 95 96 func AddInt32(addr *int32, delta int32) int32 { 97 new := *addr + delta 98 *addr = new 99 return new 100 } 101 102 func AddUint32(addr *uint32, delta uint32) uint32 { 103 new := *addr + delta 104 *addr = new 105 return new 106 } 107 108 func AddInt64(addr *int64, delta int64) int64 { 109 new := *addr + delta 110 *addr = new 111 return new 112 } 113 114 func AddUint64(addr *uint64, delta uint64) uint64 { 115 new := *addr + delta 116 *addr = new 117 return new 118 } 119 120 func AddUintptr(addr *uintptr, delta uintptr) uintptr { 121 new := *addr + delta 122 *addr = new 123 return new 124 } 125 126 func LoadInt32(addr *int32) int32 { 127 return *addr 128 } 129 130 func LoadInt64(addr *int64) int64 { 131 return *addr 132 } 133 134 func LoadUint32(addr *uint32) uint32 { 135 return *addr 136 } 137 138 func LoadUint64(addr *uint64) uint64 { 139 return *addr 140 } 141 142 func LoadUintptr(addr *uintptr) uintptr { 143 return *addr 144 } 145 146 func LoadPointer(addr *unsafe.Pointer) unsafe.Pointer { 147 return *addr 148 } 149 150 func StoreInt32(addr *int32, val int32) { 151 *addr = val 152 } 153 154 func StoreInt64(addr *int64, val int64) { 155 *addr = val 156 } 157 158 func StoreUint32(addr *uint32, val uint32) { 159 *addr = val 160 } 161 162 func StoreUint64(addr *uint64, val uint64) { 163 *addr = val 164 } 165 166 func StoreUintptr(addr *uintptr, val uintptr) { 167 *addr = val 168 } 169 170 func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer) { 171 *addr = val 172 } 173 174 func (v *Value) Load() (x interface{}) { 175 return v.v 176 } 177 178 func (v *Value) Store(new interface{}) { 179 v.checkNew("store", new) 180 v.v = new 181 } 182 183 func (v *Value) Swap(new interface{}) (old interface{}) { 184 v.checkNew("swap", new) 185 old, v.v = v.v, new 186 return old 187 } 188 189 func (v *Value) CompareAndSwap(old, new interface{}) (swapped bool) { 190 v.checkNew("compare and swap", new) 191 192 if !(v.v == nil && old == nil) && !sameType(old, new) { 193 panic("sync/atomic: compare and swap of inconsistently typed values into Value") 194 } 195 196 if v.v != old { 197 return false 198 } 199 200 v.v = new 201 202 return true 203 } 204 205 func (v *Value) checkNew(op string, new interface{}) { 206 if new == nil { 207 panic("sync/atomic: " + op + " of nil value into Value") 208 } 209 210 if v.v != nil && !sameType(new, v.v) { 211 panic("sync/atomic: " + op + " of inconsistently typed value into Value") 212 } 213 } 214 215 // sameType returns true if x and y contain the same concrete Go types. 216 func sameType(x, y interface{}) bool { 217 // This relies upon the fact that an interface in GopherJS is represented 218 // by the instance of the underlying Go type. Primitive values (e.g. bools) 219 // are still wrapped into a Go type object, so we can rely upon constructors 220 // existing and differing for different types. 221 return js.InternalObject(x).Get("constructor") == js.InternalObject(y).Get("constructor") 222 } 223 224 //gopherjs:purge for go1.19 without generics 225 type Pointer[T any] struct{}