Skip to content

Commit d49bfdd

Browse files
committed
refactor and fix bug
1 parent cac73a8 commit d49bfdd

File tree

2 files changed

+68
-50
lines changed

2 files changed

+68
-50
lines changed

common.go

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,30 @@
11
package sync
22

3-
import "sync"
3+
import (
4+
"sync"
5+
"unsafe"
6+
)
47

5-
type Cond sync.Cond
8+
type Cond struct {
9+
sync.Cond
10+
}
611

712
func NewCond(l Locker) *Cond {
8-
return (*Cond)(sync.NewCond(l))
13+
return (*Cond)(unsafe.Pointer(sync.NewCond(l)))
14+
}
15+
16+
type Locker struct {
17+
sync.Locker
18+
}
19+
20+
type Once struct {
21+
sync.Once
22+
}
23+
24+
type Pool struct {
25+
sync.Pool
926
}
1027

11-
type Locker sync.Locker
12-
type Once sync.Once
13-
type Pool sync.Pool
14-
type WaitGroup sync.WaitGroup
28+
type WaitGroup struct {
29+
sync.WaitGroup
30+
}

sync.go

Lines changed: 45 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,18 @@ import (
1414
)
1515

1616
type Mutex struct {
17-
mutexInfo
17+
mointor
1818
sync.Mutex
1919
}
2020

2121
func (m *Mutex) Lock() {
22-
holder, elem := m.mutexInfo.wait()
22+
holder, elem := m.mointor.wait()
2323
m.Mutex.Lock()
24-
m.mutexInfo.using(holder, elem)
24+
m.mointor.using(holder, elem)
2525
}
2626

2727
func (m *Mutex) Unlock() {
28-
m.mutexInfo.release()
28+
m.mointor.release()
2929
m.Mutex.Unlock()
3030
}
3131

@@ -50,73 +50,75 @@ func (rw *RWMutex) RUnlock() {
5050
}
5151

5252
var (
53-
lockMutex = new(sync.Mutex)
54-
waitTargets = make(map[int32]*mutexInfo)
53+
globalMutex = new(sync.Mutex)
54+
waitTargets = make(map[int32]*mointor)
5555
goroutineBegin = []byte("goroutine ")
5656
goroutineEnd = []byte("\n\n")
5757
)
5858

59-
func goroutine(id int32, stack []byte) []byte {
60-
head := append(strconv.AppendInt(goroutineBegin, int64(id), 10), ' ')
61-
begin := bytes.Index(stack, head)
62-
end := bytes.Index(stack[begin:], goroutineEnd)
63-
if end == -1 {
64-
end = len(stack) - begin
65-
}
66-
return stack[begin : begin+end]
67-
}
68-
69-
type mutexInfo struct {
59+
type mointor struct {
7060
holder int32
7161
waiting *list.List
7262
}
7363

74-
func (lock *mutexInfo) wait() (int32, *list.Element) {
75-
lockMutex.Lock()
76-
defer lockMutex.Unlock()
64+
func (m *mointor) wait() (int32, *list.Element) {
65+
globalMutex.Lock()
66+
defer globalMutex.Unlock()
7767

7868
holder := goid.Get()
79-
waitTargets[holder] = lock
69+
waitTargets[holder] = m
8070

81-
if lock.waiting == nil {
82-
lock.waiting = list.New()
71+
if m.waiting == nil {
72+
m.waiting = list.New()
8373
}
8474

85-
lock.verify(holder, []*mutexInfo{lock})
86-
return holder, lock.waiting.PushBack(holder)
75+
m.verify(holder, []int32{holder})
76+
return holder, m.waiting.PushBack(holder)
8777
}
8878

89-
func (lock *mutexInfo) verify(holder int32, link []*mutexInfo) {
90-
if lock.holder != 0 {
91-
if lock.holder == holder {
79+
func (m *mointor) verify(holder int32, holderLink []int32) {
80+
if m.holder != 0 {
81+
if m.holder == holder {
82+
buf := new(bytes.Buffer)
83+
fmt.Fprintln(buf, "[DEAD LOCK]\n")
84+
85+
// dump goroutines
9286
stackBuf := new(bytes.Buffer)
9387
prof := pprof.Lookup("goroutine")
9488
prof.WriteTo(stackBuf, 2)
9589
stack := stackBuf.Bytes()
96-
97-
buf := new(bytes.Buffer)
98-
fmt.Fprintln(buf, "[DEAD LOCK]\n")
99-
fmt.Fprintf(buf, "%s\n\n", goroutine(holder, stack))
100-
for i := 0; i < len(link); i++ {
101-
fmt.Fprintf(buf, "%s\n\n", goroutine(link[i].holder, stack))
90+
fmt.Fprintf(buf, "%s\n\n", traceGoroutine(holder, stack))
91+
for i := 0; i < len(holderLink); i++ {
92+
fmt.Fprintf(buf, "%s\n\n", traceGoroutine(holderLink[i], stack))
10293
}
94+
10395
panic(buf.String())
10496
}
105-
if waitTarget, exists := waitTargets[lock.holder]; exists {
106-
waitTarget.verify(holder, append(link, waitTarget))
97+
if waitTarget, exists := waitTargets[m.holder]; exists {
98+
waitTarget.verify(holder, append(holderLink, waitTarget.holder))
10799
}
108100
}
109101
}
110102

111-
func (lock *mutexInfo) using(holder int32, elem *list.Element) {
112-
lockMutex.Lock()
113-
defer lockMutex.Unlock()
103+
func (m *mointor) using(holder int32, elem *list.Element) {
104+
globalMutex.Lock()
105+
defer globalMutex.Unlock()
114106

115107
delete(waitTargets, holder)
116-
atomic.StoreInt32(&lock.holder, holder)
117-
lock.waiting.Remove(elem)
108+
atomic.StoreInt32(&m.holder, holder)
109+
m.waiting.Remove(elem)
118110
}
119111

120-
func (lock *mutexInfo) release() {
121-
atomic.StoreInt32(&lock.holder, 0)
112+
func (m *mointor) release() {
113+
atomic.StoreInt32(&m.holder, 0)
114+
}
115+
116+
func traceGoroutine(id int32, stack []byte) []byte {
117+
head := append(strconv.AppendInt(goroutineBegin, int64(id), 10), ' ')
118+
begin := bytes.Index(stack, head)
119+
end := bytes.Index(stack[begin:], goroutineEnd)
120+
if end == -1 {
121+
end = len(stack) - begin
122+
}
123+
return stack[begin : begin+end]
122124
}

0 commit comments

Comments
 (0)