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