forked from Tribler/tribler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tribler_lockprofiler.py
79 lines (61 loc) · 2.6 KB
/
tribler_lockprofiler.py
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import sys
import logging
from threading import current_thread, local, setprofile
from time import time
from Tribler.Main.tribler import run
stats = {}
threadlocal = local()
logger = logging.getLogger(__name__)
def lock_profile(frame, event, arg):
global stats, threadlocal
if not hasattr(threadlocal, "lines"):
threadlocal.lines = []
code = frame.f_code
filename = code.co_filename
lineno = code.co_firstlineno
if event in ['call', 'c_call']:
dataline = "%.3f %s:%d" % (time(), filename, lineno)
if dataline not in threadlocal.lines:
threadlocal.lines.append(dataline)
if len(threadlocal.lines) > 35:
threadlocal.lines = threadlocal.lines[1:]
if arg and getattr(arg, '__name__', None):
callname = arg.__name__
if callname in ['acquire', 'release', 'wait']:
lockobj = arg.__self__
if lockobj not in stats:
stats[lockobj] = {}
thread = current_thread()
name = thread.getName()
if name not in stats[lockobj]:
stats[lockobj][name] = [sys.maxsize, sys.maxsize,
sys.maxsize, sys.maxsize, sys.maxsize, sys.maxsize, False]
index = 0
if callname == 'release':
index = 2
elif callname == 'wait':
index = 4
if event == 'c_return':
index += 1
stats[lockobj][name][index] = time()
stats[lockobj][name][6] = index == 1
doCheck = event == 'c_return' or (event == 'c_call' and callname == 'release')
if doCheck:
took = stats[lockobj][name][index] - stats[lockobj][name][index - 1]
if took > 2:
logger.info("%s waited more than %.2f to %s lock %s:%d", name, took, callname, filename, lineno)
if hasattr(threadlocal, "lines"):
for line in threadlocal.lines:
logger.info("\t%s", line)
if index == 0:
for otherthread in stats[lockobj]:
if otherthread != name:
if stats[lockobj][otherthread][6]:
logger.info("%s waiting for lock acquired by %s", name, otherthread)
if False and hasattr(threadlocal, "lines"):
for line in threadlocal.lines:
logger.info("\t%s", line)
if __name__ == '__main__':
sys.setprofile(lock_profile)
setprofile(lock_profile)
run()