| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152 |
- package sync
- import (
- "runtime"
- "sync"
- "time"
- )
- type Mutex struct {
- mu sync.Mutex
- hold *int // Unique value for passing to pprof.
- stack [32]uintptr // The stack for the current holder.
- start time.Time // When the lock was obtained.
- entries int // Number of entries returned from runtime.Callers.
- }
- func (m *Mutex) Lock() {
- if contentionOn {
- v := new(int)
- lockBlockers.Add(v, 0)
- m.mu.Lock()
- lockBlockers.Remove(v)
- m.hold = v
- lockHolders.Add(v, 0)
- } else {
- m.mu.Lock()
- }
- if lockTimesOn {
- m.entries = runtime.Callers(2, m.stack[:])
- m.start = time.Now()
- }
- }
- func (m *Mutex) Unlock() {
- if lockTimesOn {
- d := time.Since(m.start)
- var key [32]uintptr
- copy(key[:], m.stack[:m.entries])
- lockStatsMu.Lock()
- v, ok := lockStatsByStack[key]
- if !ok {
- v.Init()
- }
- v.Add(d)
- lockStatsByStack[key] = v
- lockStatsMu.Unlock()
- }
- if contentionOn {
- lockHolders.Remove(m.hold)
- }
- m.mu.Unlock()
- }
|