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  }