github.com/nicocha30/gvisor-ligolo@v0.0.0-20230726075806-989fa2c0a413/pkg/sentry/kernel/atomicptr_bucket_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 descriptorBucketAtomicPtr struct { 17 ptr unsafe.Pointer `state:".(*descriptorBucket)"` 18 } 19 20 func (p *descriptorBucketAtomicPtr) savePtr() *descriptorBucket { 21 return p.Load() 22 } 23 24 func (p *descriptorBucketAtomicPtr) loadPtr(v *descriptorBucket) { 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 *descriptorBucketAtomicPtr) Load() *descriptorBucket { 33 return (*descriptorBucket)(atomic.LoadPointer(&p.ptr)) 34 } 35 36 // Store sets the value returned by Load to x. 37 func (p *descriptorBucketAtomicPtr) Store(x *descriptorBucket) { 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 *descriptorBucketAtomicPtr) Swap(x *descriptorBucket) *descriptorBucket { 43 return (*descriptorBucket)(atomic.SwapPointer(&p.ptr, (unsafe.Pointer)(x))) 44 }