2
0

analyse-locks-simpletrace.py 3.5 KB

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