123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- package backable_ringbuffer
- // Copied from github.com/smallnest/ringbuffer
- import (
- "sync"
- "sync/atomic"
- "unsafe"
- )
- const (
- mutexLocked = 1 << iota // mutex is locked
- mutexWoken
- mutexStarving
- mutexWaiterShift = iota
- )
- // Mutex is a locker which supports TryLock.
- 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
- }
- new := old | mutexLocked
- return atomic.CompareAndSwapInt32((*int32)(unsafe.Pointer(&m.Mutex)), old, new)
- }
- 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 {
- state := atomic.LoadInt32((*int32)(unsafe.Pointer(&m.Mutex)))
- return state&mutexLocked == mutexLocked
- }
- func (m *Mutex) IsWoken() bool {
- state := atomic.LoadInt32((*int32)(unsafe.Pointer(&m.Mutex)))
- return state&mutexWoken == mutexWoken
- }
- func (m *Mutex) IsStarving() bool {
- state := atomic.LoadInt32((*int32)(unsafe.Pointer(&m.Mutex)))
- return state&mutexStarving == mutexStarving
- }
|