sync: implement trylock

This commit is contained in:
soypat
2023-11-01 21:16:26 -03:00
committed by Ayke
parent 45764325b4
commit cb39611389
2 changed files with 71 additions and 5 deletions
+35 -5
View File
@@ -3,10 +3,12 @@ package sync
import (
"internal/task"
_ "unsafe"
"runtime/volatile"
)
type Mutex struct {
locked bool
state uint8 // Set to non-zero if locked.
blocked task.Stack
}
@@ -14,18 +16,18 @@ type Mutex struct {
func scheduleTask(*task.Task)
func (m *Mutex) Lock() {
if m.locked {
if m.islocked() {
// Push self onto stack of blocked tasks, and wait to be resumed.
m.blocked.Push(task.Current())
task.Pause()
return
}
m.locked = true
m.setlock(true)
}
func (m *Mutex) Unlock() {
if !m.locked {
if !m.islocked() {
panic("sync: unlock of unlocked Mutex")
}
@@ -33,10 +35,38 @@ func (m *Mutex) Unlock() {
if t := m.blocked.Pop(); t != nil {
scheduleTask(t)
} else {
m.locked = false
m.setlock(false)
}
}
// TryLock tries to lock m and reports whether it succeeded.
//
// Note that while correct uses of TryLock do exist, they are rare,
// and use of TryLock is often a sign of a deeper problem
// in a particular use of mutexes.
func (m *Mutex) TryLock() bool {
if m.islocked() {
return false
}
m.Lock()
return true
}
func (m *Mutex) islocked() bool {
return volatile.LoadUint8(&m.state) != 0
}
func (m *Mutex) setlock(b bool) {
volatile.StoreUint8(&m.state, boolToU8(b))
}
func boolToU8(b bool) uint8 {
if b {
return 1
}
return 0
}
type RWMutex struct {
// waitingWriters are all of the tasks waiting for write locks.
waitingWriters task.Stack