github.com/songzhibin97/gkit@v1.2.13/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  }