2
0

analyse-locks-simpletrace.py 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. #
  4. # Analyse lock events and compute statistics
  5. #
  6. # Author: Alex Bennée <alex.bennee@linaro.org>
  7. #
  8. import simpletrace
  9. import argparse
  10. import numpy as np
  11. class MutexAnalyser(simpletrace.Analyzer):
  12. "A simpletrace Analyser for checking locks."
  13. def __init__(self):
  14. self.locks = 0
  15. self.locked = 0
  16. self.unlocks = 0
  17. self.mutex_records = {}
  18. def _get_mutex(self, mutex):
  19. if not mutex in self.mutex_records:
  20. self.mutex_records[mutex] = {"locks": 0,
  21. "lock_time": 0,
  22. "acquire_times": [],
  23. "locked": 0,
  24. "locked_time": 0,
  25. "held_times": [],
  26. "unlocked": 0}
  27. return self.mutex_records[mutex]
  28. def qemu_mutex_lock(self, timestamp, mutex, filename, line):
  29. self.locks += 1
  30. rec = self._get_mutex(mutex)
  31. rec["locks"] += 1
  32. rec["lock_time"] = timestamp[0]
  33. rec["lock_loc"] = (filename, line)
  34. def qemu_mutex_locked(self, timestamp, mutex, filename, line):
  35. self.locked += 1
  36. rec = self._get_mutex(mutex)
  37. rec["locked"] += 1
  38. rec["locked_time"] = timestamp[0]
  39. acquire_time = rec["locked_time"] - rec["lock_time"]
  40. rec["locked_loc"] = (filename, line)
  41. rec["acquire_times"].append(acquire_time)
  42. def qemu_mutex_unlock(self, timestamp, mutex, filename, line):
  43. self.unlocks += 1
  44. rec = self._get_mutex(mutex)
  45. rec["unlocked"] += 1
  46. held_time = timestamp[0] - rec["locked_time"]
  47. rec["held_times"].append(held_time)
  48. rec["unlock_loc"] = (filename, line)
  49. def get_args():
  50. "Grab options"
  51. parser = argparse.ArgumentParser()
  52. parser.add_argument("--output", "-o", type=str, help="Render plot to file")
  53. parser.add_argument("events", type=str, help='trace file read from')
  54. parser.add_argument("tracefile", type=str, help='trace file read from')
  55. return parser.parse_args()
  56. if __name__ == '__main__':
  57. args = get_args()
  58. # Gather data from the trace
  59. analyser = MutexAnalyser()
  60. simpletrace.process(args.events, args.tracefile, analyser)
  61. print ("Total locks: %d, locked: %d, unlocked: %d" %
  62. (analyser.locks, analyser.locked, analyser.unlocks))
  63. # Now dump the individual lock stats
  64. for key, val in sorted(analyser.mutex_records.items(),
  65. key=lambda k_v: k_v[1]["locks"]):
  66. print ("Lock: %#x locks: %d, locked: %d, unlocked: %d" %
  67. (key, val["locks"], val["locked"], val["unlocked"]))
  68. acquire_times = np.array(val["acquire_times"])
  69. if len(acquire_times) > 0:
  70. print (" Acquire Time: min:%d median:%d avg:%.2f max:%d" %
  71. (acquire_times.min(), np.median(acquire_times),
  72. acquire_times.mean(), acquire_times.max()))
  73. held_times = np.array(val["held_times"])
  74. if len(held_times) > 0:
  75. print (" Held Time: min:%d median:%d avg:%.2f max:%d" %
  76. (held_times.min(), np.median(held_times),
  77. held_times.mean(), held_times.max()))
  78. # Check if any locks still held
  79. if val["locks"] > val["locked"]:
  80. print (" LOCK HELD (%s:%s)" % (val["locked_loc"]))
  81. print (" BLOCKED (%s:%s)" % (val["lock_loc"]))