github.com/nicocha30/gvisor-ligolo@v0.0.0-20230726075806-989fa2c0a413/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  }