| | |
| | |
| | |
| |
|
| | package atomic |
| |
|
| | import ( |
| | "unsafe" |
| | ) |
| |
|
| | |
| | |
| | |
| | |
| | |
| | type Value struct { |
| | v any |
| | } |
| |
|
| | |
| | type efaceWords struct { |
| | typ unsafe.Pointer |
| | data unsafe.Pointer |
| | } |
| |
|
| | |
| | |
| | func (v *Value) Load() (val any) { |
| | vp := (*efaceWords)(unsafe.Pointer(v)) |
| | typ := LoadPointer(&vp.typ) |
| | if typ == nil || typ == unsafe.Pointer(&firstStoreInProgress) { |
| | |
| | return nil |
| | } |
| | data := LoadPointer(&vp.data) |
| | vlp := (*efaceWords)(unsafe.Pointer(&val)) |
| | vlp.typ = typ |
| | vlp.data = data |
| | return |
| | } |
| |
|
| | var firstStoreInProgress byte |
| |
|
| | |
| | |
| | |
| | func (v *Value) Store(val any) { |
| | if val == nil { |
| | panic("sync/atomic: store of nil value into Value") |
| | } |
| | vp := (*efaceWords)(unsafe.Pointer(v)) |
| | vlp := (*efaceWords)(unsafe.Pointer(&val)) |
| | for { |
| | typ := LoadPointer(&vp.typ) |
| | if typ == nil { |
| | |
| | |
| | |
| | runtime_procPin() |
| | if !CompareAndSwapPointer(&vp.typ, nil, unsafe.Pointer(&firstStoreInProgress)) { |
| | runtime_procUnpin() |
| | continue |
| | } |
| | |
| | StorePointer(&vp.data, vlp.data) |
| | StorePointer(&vp.typ, vlp.typ) |
| | runtime_procUnpin() |
| | return |
| | } |
| | if typ == unsafe.Pointer(&firstStoreInProgress) { |
| | |
| | |
| | |
| | continue |
| | } |
| | |
| | if typ != vlp.typ { |
| | panic("sync/atomic: store of inconsistently typed value into Value") |
| | } |
| | StorePointer(&vp.data, vlp.data) |
| | return |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | func (v *Value) Swap(new any) (old any) { |
| | if new == nil { |
| | panic("sync/atomic: swap of nil value into Value") |
| | } |
| | vp := (*efaceWords)(unsafe.Pointer(v)) |
| | np := (*efaceWords)(unsafe.Pointer(&new)) |
| | for { |
| | typ := LoadPointer(&vp.typ) |
| | if typ == nil { |
| | |
| | |
| | |
| | runtime_procPin() |
| | if !CompareAndSwapPointer(&vp.typ, nil, unsafe.Pointer(&firstStoreInProgress)) { |
| | runtime_procUnpin() |
| | continue |
| | } |
| | |
| | StorePointer(&vp.data, np.data) |
| | StorePointer(&vp.typ, np.typ) |
| | runtime_procUnpin() |
| | return nil |
| | } |
| | if typ == unsafe.Pointer(&firstStoreInProgress) { |
| | |
| | |
| | |
| | continue |
| | } |
| | |
| | if typ != np.typ { |
| | panic("sync/atomic: swap of inconsistently typed value into Value") |
| | } |
| | op := (*efaceWords)(unsafe.Pointer(&old)) |
| | op.typ, op.data = np.typ, SwapPointer(&vp.data, np.data) |
| | return old |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | func (v *Value) CompareAndSwap(old, new any) (swapped bool) { |
| | if new == nil { |
| | panic("sync/atomic: compare and swap of nil value into Value") |
| | } |
| | vp := (*efaceWords)(unsafe.Pointer(v)) |
| | np := (*efaceWords)(unsafe.Pointer(&new)) |
| | op := (*efaceWords)(unsafe.Pointer(&old)) |
| | if op.typ != nil && np.typ != op.typ { |
| | panic("sync/atomic: compare and swap of inconsistently typed values") |
| | } |
| | for { |
| | typ := LoadPointer(&vp.typ) |
| | if typ == nil { |
| | if old != nil { |
| | return false |
| | } |
| | |
| | |
| | |
| | runtime_procPin() |
| | if !CompareAndSwapPointer(&vp.typ, nil, unsafe.Pointer(&firstStoreInProgress)) { |
| | runtime_procUnpin() |
| | continue |
| | } |
| | |
| | StorePointer(&vp.data, np.data) |
| | StorePointer(&vp.typ, np.typ) |
| | runtime_procUnpin() |
| | return true |
| | } |
| | if typ == unsafe.Pointer(&firstStoreInProgress) { |
| | |
| | |
| | |
| | continue |
| | } |
| | |
| | if typ != np.typ { |
| | panic("sync/atomic: compare and swap of inconsistently typed value into Value") |
| | } |
| | |
| | |
| | |
| | |
| | |
| | data := LoadPointer(&vp.data) |
| | var i any |
| | (*efaceWords)(unsafe.Pointer(&i)).typ = typ |
| | (*efaceWords)(unsafe.Pointer(&i)).data = data |
| | if i != old { |
| | return false |
| | } |
| | return CompareAndSwapPointer(&vp.data, data, np.data) |
| | } |
| | } |
| |
|
| | |
| | func runtime_procPin() int |
| | func runtime_procUnpin() |
| |
|