2 # -*- coding: utf-8 -*-
4 # Analyse lock events and compute statistics
6 # Author: Alex Bennée <alex.bennee@linaro.org>
9 from __future__
import print_function
15 class MutexAnalyser(simpletrace
.Analyzer
):
16 "A simpletrace Analyser for checking locks."
22 self
.mutex_records
= {}
24 def _get_mutex(self
, mutex
):
25 if not mutex
in self
.mutex_records
:
26 self
.mutex_records
[mutex
] = {"locks": 0,
34 return self
.mutex_records
[mutex
]
36 def qemu_mutex_lock(self
, timestamp
, mutex
, filename
, line
):
38 rec
= self
._get
_mutex
(mutex
)
40 rec
["lock_time"] = timestamp
[0]
41 rec
["lock_loc"] = (filename
, line
)
43 def qemu_mutex_locked(self
, timestamp
, mutex
, filename
, line
):
45 rec
= self
._get
_mutex
(mutex
)
47 rec
["locked_time"] = timestamp
[0]
48 acquire_time
= rec
["locked_time"] - rec
["lock_time"]
49 rec
["locked_loc"] = (filename
, line
)
50 rec
["acquire_times"].append(acquire_time
)
52 def qemu_mutex_unlock(self
, timestamp
, mutex
, filename
, line
):
54 rec
= self
._get
_mutex
(mutex
)
56 held_time
= timestamp
[0] - rec
["locked_time"]
57 rec
["held_times"].append(held_time
)
58 rec
["unlock_loc"] = (filename
, line
)
63 parser
= argparse
.ArgumentParser()
64 parser
.add_argument("--output", "-o", type=str, help="Render plot to file")
65 parser
.add_argument("events", type=str, help='trace file read from')
66 parser
.add_argument("tracefile", type=str, help='trace file read from')
67 return parser
.parse_args()
69 if __name__
== '__main__':
72 # Gather data from the trace
73 analyser
= MutexAnalyser()
74 simpletrace
.process(args
.events
, args
.tracefile
, analyser
)
76 print ("Total locks: %d, locked: %d, unlocked: %d" %
77 (analyser
.locks
, analyser
.locked
, analyser
.unlocks
))
79 # Now dump the individual lock stats
80 for key
, val
in sorted(analyser
.mutex_records
.iteritems(),
81 key
=lambda k_v
: k_v
[1]["locks"]):
82 print ("Lock: %#x locks: %d, locked: %d, unlocked: %d" %
83 (key
, val
["locks"], val
["locked"], val
["unlocked"]))
85 acquire_times
= np
.array(val
["acquire_times"])
86 if len(acquire_times
) > 0:
87 print (" Acquire Time: min:%d median:%d avg:%.2f max:%d" %
88 (acquire_times
.min(), np
.median(acquire_times
),
89 acquire_times
.mean(), acquire_times
.max()))
91 held_times
= np
.array(val
["held_times"])
92 if len(held_times
) > 0:
93 print (" Held Time: min:%d median:%d avg:%.2f max:%d" %
94 (held_times
.min(), np
.median(held_times
),
95 held_times
.mean(), held_times
.max()))
97 # Check if any locks still held
98 if val
["locks"] > val
["locked"]:
99 print (" LOCK HELD (%s:%s)" % (val
["locked_loc"]))
100 print (" BLOCKED (%s:%s)" % (val
["lock_loc"]))