[pypy-commit] pypy stmgc-c7: add basic plot_stm_log script
Raemi
noreply at buildbot.pypy.org
Tue Nov 18 17:14:32 CET 2014
Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: stmgc-c7
Changeset: r74572:08677229ea71
Date: 2014-11-18 17:14 +0100
http://bitbucket.org/pypy/pypy/changeset/08677229ea71/
Log: add basic plot_stm_log script
diff --git a/pypy/stm/plot_stm_log.py b/pypy/stm/plot_stm_log.py
new file mode 100755
--- /dev/null
+++ b/pypy/stm/plot_stm_log.py
@@ -0,0 +1,188 @@
+#!/usr/bin/env python
+import matplotlib
+import sys
+matplotlib.use('gtkagg')
+
+args = None
+import matplotlib.pyplot as plt
+
+import print_stm_log as psl
+
+
+########## DRAWING STUFF ##########
+
+BOX_HEIGHT = 0.8
+HALF_HEIGHT = 0.1 + BOX_HEIGHT / 2
+QUARTER_HEIGHT = 0.1 + BOX_HEIGHT / 4
+
+
+def plot_boxes(boxes, y, ax):
+ coords = [(x, w) for x, w, c, i in boxes]
+ colors = [c for x, w, c, i in boxes]
+ bars = ax.broken_barh(coords, (y+0.1, BOX_HEIGHT),
+ facecolors=colors, lw=1, edgecolor=(0, 0, 0),
+ picker=True, antialiased=False, rasterized=True)
+
+ bars.boxes = boxes
+
+
+def plot_hlines(hlines, y, ax):
+ args = [[[x1, x2], [y+HALF_HEIGHT, y+HALF_HEIGHT], color] for
+ x1, x2, color in hlines]
+ # flatten:
+ args = [item for sublist in args for item in sublist]
+ ax.plot(*args, linewidth=3, antialiased=False, rasterized=True)
+
+
+####################################
+
+
+def add_box(boxes, x1, x2, color, info):
+ boxes.append((x1, x2-x1, color, info))
+
+
+def add_hline(hlines, x1, x2, color):
+ hlines.append((x1, x2, color))
+
+
+def add_transaction(boxes, hlines, inited, inevitabled,
+ ended, aborted, atomics, info=""):
+ assert inited is not None
+
+ if inevitabled is not None:
+ add_box(boxes, inited, inevitabled, 'b', info)
+ add_box(boxes, inevitabled, ended, 'orange', info)
+ elif not aborted:
+ add_box(boxes, inited, ended, 'g', info)
+ else:
+ add_box(boxes, inited, ended, 'r', info)
+
+ for start, end in atomics:
+ add_hline(hlines, start, end, 'magenta')
+
+
+class Transaction(object):
+ def __init__(self, thread_num, start_time):
+ self.thread_num = thread_num
+ self.start_time = start_time
+ self.stop_time = 0
+ self.aborted = False
+ self.pauses = []
+
+
+def plot_log(logentries, ax):
+ curr_trs = {}
+ finished_trs = {}
+ for entry in logentries:
+ th_num = entry.threadnum
+
+ if entry.event == psl.STM_TRANSACTION_START:
+ if th_num in curr_trs:
+ print "WARNING: Start of transaction while there is one already running"
+ curr_trs[th_num] = Transaction(th_num, entry.timestamp)
+ elif entry.event == psl.STM_TRANSACTION_COMMIT:
+ tr = curr_trs.get(th_num)
+ if tr is not None:
+ tr.stop_time = entry.timestamp
+ xs = finished_trs.setdefault(th_num, [])
+ xs.append(curr_trs[th_num])
+ del curr_trs[th_num]
+ elif entry.event == psl.STM_TRANSACTION_ABORT:
+ tr = curr_trs.get(th_num)
+ if tr is not None:
+ tr.stop_time = entry.timestamp
+ tr.aborted = True
+ xs = finished_trs.setdefault(th_num, [])
+ xs.append(curr_trs[th_num])
+ del curr_trs[th_num]
+ elif entry.event in (psl.STM_WAIT_SYNC_PAUSE, psl.STM_WAIT_CONTENTION,
+ psl.STM_WAIT_FREE_SEGMENT):
+ pass
+ elif entry.event == psl.STM_WAIT_DONE:
+ pass
+
+
+ plt.ion()
+ for th_num, trs in finished_trs.items():
+ plt.draw()
+ plt.show()
+ print "Thread", th_num
+
+ boxes = []
+ hlines = []
+ for tr in trs:
+ add_transaction(boxes, hlines,
+ tr.start_time, None, tr.stop_time,
+ tr.aborted, [])
+ plot_boxes(boxes, th_num, ax)
+ plot_hlines(hlines, th_num, ax)
+
+ plt.ioff()
+
+ return finished_trs
+
+
+def onpick(event):
+ if hasattr(event.artist, "info"):
+ print "== pick ==\n", event.artist.info
+ if hasattr(event.artist, "boxes"):
+ x = event.mouseevent.xdata
+ for x1, w, c, i in event.artist.boxes:
+ if x >= x1 and x <= x1+w:
+ print "== pick ==\n", i
+ break
+ else:
+ print "== pick ==\nCould not find info"
+
+
+
+
+def plot(logentries):
+ global fig
+
+
+ print "Draw..."
+ fig = plt.figure()
+ grid_spec = matplotlib.gridspec.GridSpec(1, 1)
+ axs = [fig.add_subplot(grid_spec[0])]
+
+ trs = plot_log(logentries, axs[0])
+
+ thread_count = len(trs)
+
+ axs[0].set_ylabel("Thread")
+ axs[0].set_ylim(0, thread_count)
+ axs[0].set_yticks([r+0.5 for r in range(thread_count)])
+ axs[0].set_yticklabels(range(1, thread_count+1))
+ #axs[0].set_xticks([])
+ print "Drawn."
+
+ axs[0].set_xlabel("Runtime [s]")
+
+ # adjust labels:
+ first_trs = [th[0].start_time for th in trs.values()]
+ last_trs = [th[-1].stop_time for th in trs.values()]
+ start_time, stop_time = min(first_trs), max(last_trs)
+ offset = (stop_time - start_time) * 0.1
+ axs[0].set_xlim((start_time - offset, stop_time + offset))
+
+ def label_format(x, pos):
+ return "%.2f" % (x - start_time)
+ major_formatter = matplotlib.ticker.FuncFormatter(label_format)
+ axs[0].xaxis.set_major_formatter(major_formatter)
+
+ # event connect
+ fig.canvas.mpl_connect('pick_event', onpick)
+
+ plt.draw()
+ plt.show()
+
+# ____________________________________________________________
+
+def main(argv):
+ assert len(argv) == 1, "expected a filename argument"
+ plot(psl.parse_log(argv[0]))
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
More information about the pypy-commit
mailing list