File: mutex.go

package info (click to toggle)
golang-github-anacrolix-sync 0.5.3-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 144 kB
  • sloc: makefile: 2
file content (52 lines) | stat: -rw-r--r-- 962 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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()
}