Files
netstack/tmutex/tmutex.go
impact-eintr af8c2fbd42 base package
2022-11-21 14:55:24 +08:00

52 lines
991 B
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package tmutex
import (
"sync/atomic"
)
type Mutex struct {
v int32
ch chan struct{}
}
func (m *Mutex) Init() {
m.v = 1
m.ch = make(chan struct{}, 1)
}
func (m *Mutex) Lock() {
// ==0时 只有一个锁持有者
if atomic.AddInt32(&m.v, -1) == 0 {
return
}
// !=0时 有多个想持有锁者
for {
if v := atomic.LoadInt32(&m.v);v >= 0 && atomic.SwapInt32(&m.v, -1) == 1 {
return
}
<-m.ch // 排队阻塞 等待锁释放
}
}
func (m *Mutex) TryLock() bool {
v := atomic.LoadInt32(&m.v)
if v <= 0 {
return false
}
// CAS操作需要输入两个数值一个旧值期望操作前的值和一个新值
// 在操作期间先比较下旧值有没有发生变化,
// 如果没有发生变化,才交换成新值,发生了变化则不交换。
return atomic.CompareAndSwapInt32(&m.v, 1, 0)
}
func (m *Mutex) Unlock() {
if atomic.SwapInt32(&m.v, 1) == 0 { // 没有任何持有者
return
}
select {
case m.ch <- struct{}{}:
default:
}
}