Skip to content

Commit 5a1b885

Browse files
aykevldeadprogram
authored andcommitted
sync: move Mutex to internal/task
The mutex implementation needs a different implementation once support for threading lands. This implementation just moves code to the internal/task package to centralize these algorithms.
1 parent b15adf2 commit 5a1b885

File tree

3 files changed

+47
-45
lines changed

3 files changed

+47
-45
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package task
2+
3+
type Mutex struct {
4+
locked bool
5+
blocked Stack
6+
}
7+
8+
func (m *Mutex) Lock() {
9+
if m.locked {
10+
// Push self onto stack of blocked tasks, and wait to be resumed.
11+
m.blocked.Push(Current())
12+
Pause()
13+
return
14+
}
15+
16+
m.locked = true
17+
}
18+
19+
func (m *Mutex) Unlock() {
20+
if !m.locked {
21+
panic("sync: unlock of unlocked Mutex")
22+
}
23+
24+
// Wake up a blocked task, if applicable.
25+
if t := m.blocked.Pop(); t != nil {
26+
scheduleTask(t)
27+
} else {
28+
m.locked = false
29+
}
30+
}
31+
32+
// TryLock tries to lock m and reports whether it succeeded.
33+
//
34+
// Note that while correct uses of TryLock do exist, they are rare,
35+
// and use of TryLock is often a sign of a deeper problem
36+
// in a particular use of mutexes.
37+
func (m *Mutex) TryLock() bool {
38+
if m.locked {
39+
return false
40+
}
41+
m.Lock()
42+
return true
43+
}

src/sync/cond.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,6 @@ func (c *Cond) Wait() {
8989
// signal.
9090
task.Pause()
9191
}
92+
93+
//go:linkname scheduleTask runtime.scheduleTask
94+
func scheduleTask(*task.Task)

src/sync/mutex.go

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,9 @@ package sync
22

33
import (
44
"internal/task"
5-
_ "unsafe"
65
)
76

8-
type Mutex struct {
9-
locked bool
10-
blocked task.Stack
11-
}
12-
13-
//go:linkname scheduleTask runtime.scheduleTask
14-
func scheduleTask(*task.Task)
15-
16-
func (m *Mutex) Lock() {
17-
if m.locked {
18-
// Push self onto stack of blocked tasks, and wait to be resumed.
19-
m.blocked.Push(task.Current())
20-
task.Pause()
21-
return
22-
}
23-
24-
m.locked = true
25-
}
26-
27-
func (m *Mutex) Unlock() {
28-
if !m.locked {
29-
panic("sync: unlock of unlocked Mutex")
30-
}
31-
32-
// Wake up a blocked task, if applicable.
33-
if t := m.blocked.Pop(); t != nil {
34-
scheduleTask(t)
35-
} else {
36-
m.locked = false
37-
}
38-
}
39-
40-
// TryLock tries to lock m and reports whether it succeeded.
41-
//
42-
// Note that while correct uses of TryLock do exist, they are rare,
43-
// and use of TryLock is often a sign of a deeper problem
44-
// in a particular use of mutexes.
45-
func (m *Mutex) TryLock() bool {
46-
if m.locked {
47-
return false
48-
}
49-
m.Lock()
50-
return true
51-
}
7+
type Mutex = task.Mutex
528

539
type RWMutex struct {
5410
// waitingWriters are all of the tasks waiting for write locks.

0 commit comments

Comments
 (0)