github.com/songzhibin97/gkit@v1.2.13/internal/sys/mutex/mutex.go (about) 1 package mutex 2 3 import ( 4 "sync" 5 "sync/atomic" 6 "unsafe" 7 ) 8 9 // 复制Mutex定义的常量 10 const ( 11 mutexLocked = 1 << iota // 加锁标识位置 12 mutexWoken // 唤醒标识位置 13 mutexStarving // 锁饥饿标识位置 14 mutexWaiterShift = iota // 标识waiter的起始bit位置 15 ) 16 17 // Mutex 支持 TryLock 18 type Mutex struct { 19 sync.Mutex 20 } 21 22 func (m *Mutex) TryLock() bool { 23 // 如果能成功抢到锁 24 if atomic.CompareAndSwapInt32((*int32)(unsafe.Pointer(&m.Mutex)), 0, mutexLocked) { 25 return true 26 } 27 28 // 如果处于唤醒、加锁或者饥饿状态,这次请求就不参与竞争了,返回false 29 old := atomic.LoadInt32((*int32)(unsafe.Pointer(&m.Mutex))) 30 if old&(mutexLocked|mutexStarving|mutexWoken) != 0 { 31 return false 32 } 33 34 // 尝试在竞争的状态下请求锁 35 _new := old | mutexLocked 36 return atomic.CompareAndSwapInt32((*int32)(unsafe.Pointer(&m.Mutex)), old, _new) 37 } 38 39 // Count 指标信息 获取等待锁的数量 40 func (m *Mutex) Count() int { 41 // 获取state字段的值 42 v := atomic.LoadInt32((*int32)(unsafe.Pointer(&m.Mutex))) 43 v = v >> mutexWaiterShift // 得到等待者的数值 44 v = v + (v & mutexLocked) // 再加上锁持有者的数量,0或者1 45 return int(v) 46 } 47 48 // IsLocked 锁是否被持有 49 func (m *Mutex) IsLocked() bool { 50 state := atomic.LoadInt32((*int32)(unsafe.Pointer(&m.Mutex))) 51 return state&mutexLocked == mutexLocked 52 } 53 54 // IsWoken 是否有等待者被唤醒 55 func (m *Mutex) IsWoken() bool { 56 state := atomic.LoadInt32((*int32)(unsafe.Pointer(&m.Mutex))) 57 return state&mutexWoken == mutexWoken 58 } 59 60 // IsStarving 锁是否处于饥饿状态 61 func (m *Mutex) IsStarving() bool { 62 state := atomic.LoadInt32((*int32)(unsafe.Pointer(&m.Mutex))) 63 return state&mutexStarving == mutexStarving 64 }