v8.run/go/exp@v0.0.26-0.20230226010534-afcdbd3f782d/sync2/ptrl.go (about)

     1  package sync2
     2  
     3  import (
     4  	"runtime"
     5  	"sync/atomic"
     6  	"unsafe"
     7  )
     8  
     9  type PointerLock[T any] struct {
    10  	value unsafe.Pointer
    11  }
    12  
    13  func NewPointerLock[T any]() PointerLock[T] {
    14  	return PointerLock[T]{
    15  		value: unsafe.Pointer(new(T)),
    16  	}
    17  }
    18  
    19  func (p *PointerLock[T]) Lock() *T {
    20  	for {
    21  		if old := atomic.SwapPointer(&p.value, nil); old != nil {
    22  			return (*T)(old)
    23  		}
    24  		runtime.Gosched()
    25  	}
    26  }
    27  
    28  func (p *PointerLock[T]) Unlock(v *T) {
    29  	atomic.StorePointer(&p.value, unsafe.Pointer(v))
    30  }