github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/pkg/sentry/kernel/atomicptr_descriptor_unsafe.go (about) 1 package kernel 2 3 import ( 4 "context" 5 "sync/atomic" 6 "unsafe" 7 ) 8 9 // An AtomicPtr is a pointer to a value of type Value that can be atomically 10 // loaded and stored. The zero value of an AtomicPtr represents nil. 11 // 12 // Note that copying AtomicPtr by value performs a non-atomic read of the 13 // stored pointer, which is unsafe if Store() can be called concurrently; in 14 // this case, do `dst.Store(src.Load())` instead. 15 // 16 // +stateify savable 17 type descriptorAtomicPtr struct { 18 ptr unsafe.Pointer `state:".(*descriptor)"` 19 } 20 21 func (p *descriptorAtomicPtr) savePtr() *descriptor { 22 return p.Load() 23 } 24 25 func (p *descriptorAtomicPtr) loadPtr(_ context.Context, v *descriptor) { 26 p.Store(v) 27 } 28 29 // Load returns the value set by the most recent Store. It returns nil if there 30 // has been no previous call to Store. 31 // 32 //go:nosplit 33 func (p *descriptorAtomicPtr) Load() *descriptor { 34 return (*descriptor)(atomic.LoadPointer(&p.ptr)) 35 } 36 37 // Store sets the value returned by Load to x. 38 func (p *descriptorAtomicPtr) Store(x *descriptor) { 39 atomic.StorePointer(&p.ptr, (unsafe.Pointer)(x)) 40 } 41 42 // Swap atomically stores `x` into *p and returns the previous *p value. 43 func (p *descriptorAtomicPtr) Swap(x *descriptor) *descriptor { 44 return (*descriptor)(atomic.SwapPointer(&p.ptr, (unsafe.Pointer)(x))) 45 }