Skip to content

Commit f10da24

Browse files
committed
implement mutex blocking
1 parent d5c997a commit f10da24

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

src/sync/mutex.go

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,43 @@
11
package sync
22

3+
import (
4+
"internal/task"
5+
_ "unsafe"
6+
)
7+
38
// These mutexes assume there is only one thread of operation: no goroutines,
49
// interrupts or anything else.
510

611
type Mutex struct {
7-
locked bool
12+
locked bool
13+
blocked task.Stack
814
}
915

16+
//go:linkname scheduleTask runtime.runqueuePushBack
17+
func scheduleTask(*task.Task)
18+
1019
func (m *Mutex) Lock() {
1120
if m.locked {
12-
panic("todo: block on locked mutex")
21+
// Push self onto stack of blocked tasks, and wait to be resumed.
22+
m.blocked.Push(task.Current())
23+
task.Pause()
24+
return
1325
}
26+
1427
m.locked = true
1528
}
1629

1730
func (m *Mutex) Unlock() {
1831
if !m.locked {
1932
panic("sync: unlock of unlocked Mutex")
2033
}
21-
m.locked = false
34+
35+
// Wake up a blocked task, if applicable.
36+
if t := m.blocked.Pop(); t != nil {
37+
scheduleTask(t)
38+
} else {
39+
m.locked = false
40+
}
2241
}
2342

2443
type RWMutex struct {

0 commit comments

Comments
 (0)