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