init
This commit is contained in:
10
vendor/github.com/anacrolix/sync/aliases.go
generated
vendored
Normal file
10
vendor/github.com/anacrolix/sync/aliases.go
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
package sync
|
||||
|
||||
import "sync"
|
||||
|
||||
type (
|
||||
WaitGroup = sync.WaitGroup
|
||||
Cond = sync.Cond
|
||||
Pool = sync.Pool
|
||||
Locker = sync.Locker
|
||||
)
|
3
vendor/github.com/anacrolix/sync/go.mod
generated
vendored
Normal file
3
vendor/github.com/anacrolix/sync/go.mod
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
module github.com/anacrolix/sync
|
||||
|
||||
require github.com/anacrolix/missinggo v0.0.0-20180725070939-60ef2fbf63df
|
17
vendor/github.com/anacrolix/sync/go.sum
generated
vendored
Normal file
17
vendor/github.com/anacrolix/sync/go.sum
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
github.com/RoaringBitmap/roaring v0.4.7/go.mod h1:8khRDP4HmeXns4xIj9oGrKSz7XTQiJx2zgh7AcNke4w=
|
||||
github.com/anacrolix/envpprof v0.0.0-20180404065416-323002cec2fa/go.mod h1:KgHhUaQMc8cC0+cEflSgCFNFbKwi5h54gqtVn8yhP7c=
|
||||
github.com/anacrolix/missinggo v0.0.0-20180725070939-60ef2fbf63df h1:+se8qhX5ivmSCkP+gZXyFx2ETjk1pmnrYJ0Iyc+hZKY=
|
||||
github.com/anacrolix/missinggo v0.0.0-20180725070939-60ef2fbf63df/go.mod h1:kwGiTUTZ0+p4vAz3VbAI5a30t2YbvemcmspjKwrAz5s=
|
||||
github.com/anacrolix/tagflag v0.0.0-20180109131632-2146c8d41bf0/go.mod h1:1m2U/K6ZT+JZG0+bdMK6qauP49QT4wE5pmhJXOKKCHw=
|
||||
github.com/bradfitz/iter v0.0.0-20140124041915-454541ec3da2/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/dustin/go-humanize v0.0.0-20180421182945-02af3965c54e/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/huandu/xstrings v1.0.0 h1:pO2K/gKgKaat5LdpAhxhluX2GPQMaI3W5FUz/I/UnWk=
|
||||
github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo=
|
||||
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8=
|
||||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
37
vendor/github.com/anacrolix/sync/lockstats.go
generated
vendored
Normal file
37
vendor/github.com/anacrolix/sync/lockstats.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
package sync
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
"github.com/anacrolix/missinggo/perf"
|
||||
)
|
||||
|
||||
var (
|
||||
// Stats on lock usage by call graph.
|
||||
lockStatsMu sync.Mutex
|
||||
lockStatsByStack map[lockStackKey]lockStats
|
||||
)
|
||||
|
||||
type (
|
||||
lockStats = perf.Event
|
||||
lockStackKey = [32]uintptr
|
||||
lockCount = int64
|
||||
)
|
||||
|
||||
type stackLockStats struct {
|
||||
stack lockStackKey
|
||||
lockStats
|
||||
}
|
||||
|
||||
func sortedLockTimes() (ret []stackLockStats) {
|
||||
lockStatsMu.Lock()
|
||||
for stack, stats := range lockStatsByStack {
|
||||
ret = append(ret, stackLockStats{stack, stats})
|
||||
}
|
||||
lockStatsMu.Unlock()
|
||||
sort.Slice(ret, func(i, j int) bool {
|
||||
return ret[i].Total > ret[j].Total
|
||||
})
|
||||
return
|
||||
}
|
52
vendor/github.com/anacrolix/sync/mutex.go
generated
vendored
Normal file
52
vendor/github.com/anacrolix/sync/mutex.go
generated
vendored
Normal file
@@ -0,0 +1,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()
|
||||
}
|
43
vendor/github.com/anacrolix/sync/rwmutex.go
generated
vendored
Normal file
43
vendor/github.com/anacrolix/sync/rwmutex.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
package sync
|
||||
|
||||
import "sync"
|
||||
|
||||
// This RWMutex's RLock and RUnlock methods don't allow shared reading because
|
||||
// there's no way to determine what goroutine has stopped holding the read
|
||||
// lock when RUnlock is called. So for debugging purposes when the package is
|
||||
// Enable()d, it's just like Mutex.
|
||||
type RWMutex struct {
|
||||
ins Mutex // Instrumented
|
||||
rw sync.RWMutex // Real McCoy
|
||||
}
|
||||
|
||||
func (me *RWMutex) Lock() {
|
||||
if noSharedLocking {
|
||||
me.ins.Lock()
|
||||
} else {
|
||||
me.rw.Lock()
|
||||
}
|
||||
}
|
||||
|
||||
func (me *RWMutex) Unlock() {
|
||||
if noSharedLocking {
|
||||
me.ins.Unlock()
|
||||
} else {
|
||||
me.rw.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (me *RWMutex) RLock() {
|
||||
if noSharedLocking {
|
||||
me.ins.Lock()
|
||||
} else {
|
||||
me.rw.RLock()
|
||||
}
|
||||
}
|
||||
func (me *RWMutex) RUnlock() {
|
||||
if noSharedLocking {
|
||||
me.ins.Unlock()
|
||||
} else {
|
||||
me.rw.RUnlock()
|
||||
}
|
||||
}
|
92
vendor/github.com/anacrolix/sync/sync.go
generated
vendored
Normal file
92
vendor/github.com/anacrolix/sync/sync.go
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
// Package sync is an extension of the stdlib "sync" package. It has extra
|
||||
// functionality that helps debug the use of synchronization primitives. The
|
||||
// package should be importable in place of "sync". The extra functionality
|
||||
// can be enabled by calling Enable() or passing a non-empty PPROF_SYNC
|
||||
// environment variable to the process.
|
||||
//
|
||||
// Several profiles are exposed on the default HTTP muxer (and to
|
||||
// "/debug/pprof" when "net/http/pprof" is imported by the process).
|
||||
// "lockHolders" lists the stack traces of goroutines that called Mutex.Lock
|
||||
// that haven't subsequently been Unlocked. "lockBlockers" contains goroutines
|
||||
// that are waiting to obtain locks. "/debug/lockTimes" or PrintLockTimes()
|
||||
// shows the longest time a lock is held for each stack trace.
|
||||
//
|
||||
// Note that currently RWMutex is treated like a Mutex when the package is
|
||||
// enabled.
|
||||
package sync
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"runtime/pprof"
|
||||
"strings"
|
||||
"sync"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/anacrolix/missinggo"
|
||||
)
|
||||
|
||||
var (
|
||||
// Protects initialization and enabling of the package.
|
||||
enableMu sync.Mutex
|
||||
// Whether shared locks must be handled as exclusive locks.
|
||||
noSharedLocking = false
|
||||
contentionOn = false
|
||||
lockTimesOn = false
|
||||
// Current lock holders.
|
||||
lockHolders *pprof.Profile
|
||||
// Those blocked on acquiring a lock.
|
||||
lockBlockers *pprof.Profile
|
||||
)
|
||||
|
||||
// Writes out the longest time a Mutex remains locked for each stack trace
|
||||
// that locks a Mutex.
|
||||
func PrintLockTimes(w io.Writer) {
|
||||
lockTimes := sortedLockTimes()
|
||||
tw := tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
|
||||
defer tw.Flush()
|
||||
w = tw
|
||||
for _, elem := range lockTimes {
|
||||
fmt.Fprintf(w, "%s (%s * %d [%s, %s])\n", elem.Total, elem.MeanTime(), elem.Count, elem.Min, elem.Max)
|
||||
missinggo.WriteStack(w, elem.stack[:])
|
||||
}
|
||||
}
|
||||
|
||||
func Enable() {
|
||||
EnableContention()
|
||||
EnableLockTimes()
|
||||
}
|
||||
|
||||
func EnableContention() {
|
||||
lockHolders = pprof.NewProfile("lockHolders")
|
||||
lockBlockers = pprof.NewProfile("lockBlockers")
|
||||
noSharedLocking = true
|
||||
contentionOn = true
|
||||
}
|
||||
|
||||
func EnableLockTimes() {
|
||||
lockStatsByStack = make(map[lockStackKey]lockStats)
|
||||
http.DefaultServeMux.HandleFunc("/debug/lockTimes", func(w http.ResponseWriter, r *http.Request) {
|
||||
PrintLockTimes(w)
|
||||
})
|
||||
noSharedLocking = true
|
||||
lockTimesOn = true
|
||||
}
|
||||
|
||||
func init() {
|
||||
env := os.Getenv("PPROF_SYNC")
|
||||
all := true
|
||||
if strings.Contains(env, "times") {
|
||||
EnableLockTimes()
|
||||
all = false
|
||||
}
|
||||
if strings.Contains(env, "contention") {
|
||||
EnableContention()
|
||||
all = false
|
||||
}
|
||||
if all && env != "" {
|
||||
Enable()
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user