github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/utils/spin_lock.go (about) 1 package utils 2 3 import ( 4 "runtime" 5 "sync/atomic" 6 ) 7 8 // SpinLock implements a simple atomic spin lock, the zero value for a SpinLock is an unlocked spinlock. 9 type SpinLock struct { 10 f uint32 11 } 12 13 // Lock locks sl. If the lock is already in use, the caller blocks until Unlock is called 14 func (sl *SpinLock) Lock() { 15 for !sl.TryLock() { 16 runtime.Gosched() // allow other goroutines to do work. 17 } 18 } 19 20 // Unlock unlocks sl, unlike [Mutex.Unlock](http://golang.org/pkg/sync/#Mutex.Unlock), 21 // there's no harm calling it on an unlocked SpinLock 22 func (sl *SpinLock) Unlock() { 23 atomic.StoreUint32(&sl.f, 0) 24 } 25 26 // TryLock will try to lock sl and return whether it succeed or not without blocking. 27 func (sl *SpinLock) TryLock() bool { 28 return atomic.CompareAndSwapUint32(&sl.f, 0, 1) 29 } 30 31 // String is human readable lock state 32 func (sl *SpinLock) String() string { 33 if atomic.LoadUint32(&sl.f) == 1 { 34 return "Locked" 35 } 36 return "Unlocked" 37 }