const (
mutexLocked = 1 << iota
mutexWoken
mutexStarving
mutexWaiterShift = iota
)
type Mutex struct {
sync.Mutex
}
func (m *Mutex) TryLock() bool {
if atomic.CompareAndSwapInt32((*int32)(unsafe.Pointer(&m.Mutex)), 0, mutexLocked) {
return true
}
old := atomic.LoadInt32((*int32)(unsafe.Pointer(&m.Mutex)))
if old&(mutexLocked|mutexStarving|mutexWoken) != 0 {
return false
}
n := old | mutexLocked
return atomic.CompareAndSwapInt32((*int32)(unsafe.Pointer(&m.Mutex)), old, n)
}
func (m *Mutex) Count() int {
v := atomic.LoadInt32((*int32)(unsafe.Pointer(&m.Mutex)))
v = v >> mutexWaiterShift
v = v + (v & mutexLocked)
return int(v)
}
func (m *Mutex) IsLocked() bool {
return m.isState(mutexLocked)
}
func (m *Mutex) IsWoken() bool {
return m.isState(mutexWoken)
}
func (m *Mutex) IsStarving() bool {
return m.isState(mutexStarving)
}
func (m *Mutex) isState(state int32) bool {
return atomic.LoadInt32((*int32)(unsafe.Pointer(&m.Mutex)))&state == state
}
网友评论