2
0

analyse-locks-simpletrace.py 3.5 KB

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