github.com/metacubex/gvisor@v0.0.0-20240320004321-933faba989ec/pkg/sentry/kernel/atomicptr_bucket_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 descriptorBucketAtomicPtr struct { 18 ptr unsafe.Pointer `state:".(*descriptorBucket)"` 19 } 20 21 func (p *descriptorBucketAtomicPtr) savePtr() *descriptorBucket { 22 return p.Load() 23 } 24 25 func (p *descriptorBucketAtomicPtr) loadPtr(_ context.Context, v *descriptorBucket) { 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 *descriptorBucketAtomicPtr) Load() *descriptorBucket { 34 return (*descriptorBucket)(atomic.LoadPointer(&p.ptr)) 35 } 36 37 // Store sets the value returned by Load to x. 38 func (p *descriptorBucketAtomicPtr) Store(x *descriptorBucket) { 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 *descriptorBucketAtomicPtr) Swap(x *descriptorBucket) *descriptorBucket { 44 return (*descriptorBucket)(atomic.SwapPointer(&p.ptr, (unsafe.Pointer)(x))) 45 }