test-bdrv-drain: AIO_WAIT_WHILE() in job .commit/.abort
[qemu/ar7.git] / scripts / analyse-locks-simpletrace.py
blob30090bdfff5f09b4df095a3e48136f0657c3fdb8
1 #!/usr/bin/env python
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
10 import os
11 import simpletrace
12 import argparse
13 import numpy as np
15 class MutexAnalyser(simpletrace.Analyzer):
16 "A simpletrace Analyser for checking locks."
18 def __init__(self):
19 self.locks = 0
20 self.locked = 0
21 self.unlocks = 0
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,
27 "lock_time": 0,
28 "acquire_times": [],
29 "locked": 0,
30 "locked_time": 0,
31 "held_times": [],
32 "unlocked": 0}
34 return self.mutex_records[mutex]
36 def qemu_mutex_lock(self, timestamp, mutex, filename, line):
37 self.locks += 1
38 rec = self._get_mutex(mutex)
39 rec["locks"] += 1
40 rec["lock_time"] = timestamp[0]
41 rec["lock_loc"] = (filename, line)
43 def qemu_mutex_locked(self, timestamp, mutex, filename, line):
44 self.locked += 1
45 rec = self._get_mutex(mutex)
46 rec["locked"] += 1
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):
53 self.unlocks += 1
54 rec = self._get_mutex(mutex)
55 rec["unlocked"] += 1
56 held_time = timestamp[0] - rec["locked_time"]
57 rec["held_times"].append(held_time)
58 rec["unlock_loc"] = (filename, line)
61 def get_args():
62 "Grab options"
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__':
70 args = get_args()
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"]))