gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/sync/atomicptr/generic_atomicptr_unsafe.go (about) 1 // Copyright 2019 The gVisor Authors. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 // Package seqatomic doesn't exist. This file must be instantiated using the 7 // go_template_instance rule in tools/go_generics/defs.bzl. 8 package seqatomic 9 10 import ( 11 "context" 12 "sync/atomic" 13 "unsafe" 14 ) 15 16 // Value is a required type parameter. 17 type Value struct{} 18 19 // An AtomicPtr is a pointer to a value of type Value that can be atomically 20 // loaded and stored. The zero value of an AtomicPtr represents nil. 21 // 22 // Note that copying AtomicPtr by value performs a non-atomic read of the 23 // stored pointer, which is unsafe if Store() can be called concurrently; in 24 // this case, do `dst.Store(src.Load())` instead. 25 // 26 // +stateify savable 27 type AtomicPtr struct { 28 ptr unsafe.Pointer `state:".(*Value)"` 29 } 30 31 func (p *AtomicPtr) savePtr() *Value { 32 return p.Load() 33 } 34 35 func (p *AtomicPtr) loadPtr(_ context.Context, v *Value) { 36 p.Store(v) 37 } 38 39 // Load returns the value set by the most recent Store. It returns nil if there 40 // has been no previous call to Store. 41 // 42 //go:nosplit 43 func (p *AtomicPtr) Load() *Value { 44 return (*Value)(atomic.LoadPointer(&p.ptr)) 45 } 46 47 // Store sets the value returned by Load to x. 48 func (p *AtomicPtr) Store(x *Value) { 49 atomic.StorePointer(&p.ptr, (unsafe.Pointer)(x)) 50 } 51 52 // Swap atomically stores `x` into *p and returns the previous *p value. 53 func (p *AtomicPtr) Swap(x *Value) *Value { 54 return (*Value)(atomic.SwapPointer(&p.ptr, (unsafe.Pointer)(x))) 55 }