github.com/andy2046/gopie@v0.7.0/pkg/spinlock/spinlock.go (about) 1 // Package spinlock implements Spinlock. 2 package spinlock 3 4 import ( 5 "runtime" 6 "sync/atomic" 7 ) 8 9 // Locker is the Spinlock implementation. 10 type Locker struct { 11 noCopy noCopy 12 lock uintptr 13 } 14 15 // New creates a Locker. 16 func New() *Locker { 17 return &Locker{} 18 } 19 20 // Lock wait in a loop to acquire the spinlock. 21 func (l *Locker) Lock() { 22 for !atomic.CompareAndSwapUintptr(&l.lock, 0, 1) { 23 runtime.Gosched() 24 } 25 } 26 27 // Unlock release the spinlock. 28 func (l *Locker) Unlock() { 29 atomic.StoreUintptr(&l.lock, 0) 30 } 31 32 // TryLock try to acquire the spinlock, 33 // it returns true if succeed, false otherwise. 34 func (l *Locker) TryLock() bool { 35 return atomic.CompareAndSwapUintptr(&l.lock, 0, 1) 36 } 37 38 // IsLocked returns true if locked, false otherwise. 39 func (l *Locker) IsLocked() bool { 40 return atomic.LoadUintptr(&l.lock) == 1 41 } 42 43 // noCopy may be embedded into structs which must not be copied 44 // after the first use. 45 type noCopy struct{} 46 47 // Lock is a no-op used by -copylocks checker from `go vet`. 48 func (*noCopy) Lock() {} 49 func (*noCopy) Unlock() {}