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
14 class MutexAnalyser(simpletrace
.Analyzer
):
15 "A simpletrace Analyser for checking locks."
21 self
.mutex_records
= {}
23 def _get_mutex(self
, mutex
):
24 if not mutex
in self
.mutex_records
:
25 self
.mutex_records
[mutex
] = {"locks": 0,
33 return self
.mutex_records
[mutex
]
35 def qemu_mutex_lock(self
, timestamp
, mutex
, filename
, line
):
37 rec
= self
._get
_mutex
(mutex
)
39 rec
["lock_time"] = timestamp
[0]
40 rec
["lock_loc"] = (filename
, line
)
42 def qemu_mutex_locked(self
, timestamp
, mutex
, filename
, line
):
44 rec
= self
._get
_mutex
(mutex
)
46 rec
["locked_time"] = timestamp
[0]
47 acquire_time
= rec
["locked_time"] - rec
["lock_time"]
48 rec
["locked_loc"] = (filename
, line
)
49 rec
["acquire_times"].append(acquire_time
)
51 def qemu_mutex_unlock(self
, timestamp
, mutex
, filename
, line
):
53 rec
= self
._get
_mutex
(mutex
)
55 held_time
= timestamp
[0] - rec
["locked_time"]
56 rec
["held_times"].append(held_time
)
57 rec
["unlock_loc"] = (filename
, line
)
62 parser
= argparse
.ArgumentParser()
63 parser
.add_argument("--output", "-o", type=str, help="Render plot to file")
64 parser
.add_argument("events", type=str, help='trace file read from')
65 parser
.add_argument("tracefile", type=str, help='trace file read from')
66 return parser
.parse_args()
68 if __name__
== '__main__':
71 # Gather data from the trace
72 analyser
= MutexAnalyser()
73 simpletrace
.process(args
.events
, args
.tracefile
, analyser
)
75 print ("Total locks: %d, locked: %d, unlocked: %d" %
76 (analyser
.locks
, analyser
.locked
, analyser
.unlocks
))
78 # Now dump the individual lock stats
79 for key
, val
in sorted(analyser
.mutex_records
.iteritems(),
80 key
=lambda k_v
: k_v
[1]["locks"]):
81 print ("Lock: %#x locks: %d, locked: %d, unlocked: %d" %
82 (key
, val
["locks"], val
["locked"], val
["unlocked"]))
84 acquire_times
= np
.array(val
["acquire_times"])
85 if len(acquire_times
) > 0:
86 print (" Acquire Time: min:%d median:%d avg:%.2f max:%d" %
87 (acquire_times
.min(), np
.median(acquire_times
),
88 acquire_times
.mean(), acquire_times
.max()))
90 held_times
= np
.array(val
["held_times"])
91 if len(held_times
) > 0:
92 print (" Held Time: min:%d median:%d avg:%.2f max:%d" %
93 (held_times
.min(), np
.median(held_times
),
94 held_times
.mean(), held_times
.max()))
96 # Check if any locks still held
97 if val
["locks"] > val
["locked"]:
98 print (" LOCK HELD (%s:%s)" % (val
["locked_loc"]))
99 print (" BLOCKED (%s:%s)" % (val
["lock_loc"]))