diff options
Diffstat (limited to 'tools/perf/scripts/python/Perf-Trace-Util')
| -rw-r--r-- | tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Core.py | 30 | ||||
| -rw-r--r-- | tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/SchedGui.py | 184 | 
2 files changed, 214 insertions, 0 deletions
| diff --git a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Core.py b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Core.py index 1dc464ee2ca8..aad7525bca1d 100644 --- a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Core.py +++ b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Core.py @@ -89,3 +89,33 @@ def trace_flag_str(value):  	    value &= ~idx      return string + + +def taskState(state): +	states = { +		0 : "R", +		1 : "S", +		2 : "D", +		64: "DEAD" +	} + +	if state not in states: +		return "Unknown" + +	return states[state] + + +class EventHeaders: +	def __init__(self, common_cpu, common_secs, common_nsecs, +		     common_pid, common_comm): +		self.cpu = common_cpu +		self.secs = common_secs +		self.nsecs = common_nsecs +		self.pid = common_pid +		self.comm = common_comm + +	def ts(self): +		return (self.secs * (10 ** 9)) + self.nsecs + +	def ts_format(self): +		return "%d.%d" % (self.secs, int(self.nsecs / 1000)) diff --git a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/SchedGui.py b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/SchedGui.py new file mode 100644 index 000000000000..ae9a56e43e05 --- /dev/null +++ b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/SchedGui.py @@ -0,0 +1,184 @@ +# SchedGui.py - Python extension for perf trace, basic GUI code for +#		traces drawing and overview. +# +# Copyright (C) 2010 by Frederic Weisbecker <[email protected]> +# +# This software is distributed under the terms of the GNU General +# Public License ("GPL") version 2 as published by the Free Software +# Foundation. + + +try: +	import wx +except ImportError: +	raise ImportError, "You need to install the wxpython lib for this script" + + +class RootFrame(wx.Frame): +	Y_OFFSET = 100 +	RECT_HEIGHT = 100 +	RECT_SPACE = 50 +	EVENT_MARKING_WIDTH = 5 + +	def __init__(self, sched_tracer, title, parent = None, id = -1): +		wx.Frame.__init__(self, parent, id, title) + +		(self.screen_width, self.screen_height) = wx.GetDisplaySize() +		self.screen_width -= 10 +		self.screen_height -= 10 +		self.zoom = 0.5 +		self.scroll_scale = 20 +		self.sched_tracer = sched_tracer +		self.sched_tracer.set_root_win(self) +		(self.ts_start, self.ts_end) = sched_tracer.interval() +		self.update_width_virtual() +		self.nr_rects = sched_tracer.nr_rectangles() + 1 +		self.height_virtual = RootFrame.Y_OFFSET + (self.nr_rects * (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)) + +		# whole window panel +		self.panel = wx.Panel(self, size=(self.screen_width, self.screen_height)) + +		# scrollable container +		self.scroll = wx.ScrolledWindow(self.panel) +		self.scroll.SetScrollbars(self.scroll_scale, self.scroll_scale, self.width_virtual / self.scroll_scale, self.height_virtual / self.scroll_scale) +		self.scroll.EnableScrolling(True, True) +		self.scroll.SetFocus() + +		# scrollable drawing area +		self.scroll_panel = wx.Panel(self.scroll, size=(self.screen_width - 15, self.screen_height / 2)) +		self.scroll_panel.Bind(wx.EVT_PAINT, self.on_paint) +		self.scroll_panel.Bind(wx.EVT_KEY_DOWN, self.on_key_press) +		self.scroll_panel.Bind(wx.EVT_LEFT_DOWN, self.on_mouse_down) +		self.scroll.Bind(wx.EVT_PAINT, self.on_paint) +		self.scroll.Bind(wx.EVT_KEY_DOWN, self.on_key_press) +		self.scroll.Bind(wx.EVT_LEFT_DOWN, self.on_mouse_down) + +		self.scroll.Fit() +		self.Fit() + +		self.scroll_panel.SetDimensions(-1, -1, self.width_virtual, self.height_virtual, wx.SIZE_USE_EXISTING) + +		self.txt = None + +		self.Show(True) + +	def us_to_px(self, val): +		return val / (10 ** 3) * self.zoom + +	def px_to_us(self, val): +		return (val / self.zoom) * (10 ** 3) + +	def scroll_start(self): +		(x, y) = self.scroll.GetViewStart() +		return (x * self.scroll_scale, y * self.scroll_scale) + +	def scroll_start_us(self): +		(x, y) = self.scroll_start() +		return self.px_to_us(x) + +	def paint_rectangle_zone(self, nr, color, top_color, start, end): +		offset_px = self.us_to_px(start - self.ts_start) +		width_px = self.us_to_px(end - self.ts_start) + +		offset_py = RootFrame.Y_OFFSET + (nr * (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)) +		width_py = RootFrame.RECT_HEIGHT + +		dc = self.dc + +		if top_color is not None: +			(r, g, b) = top_color +			top_color = wx.Colour(r, g, b) +			brush = wx.Brush(top_color, wx.SOLID) +			dc.SetBrush(brush) +			dc.DrawRectangle(offset_px, offset_py, width_px, RootFrame.EVENT_MARKING_WIDTH) +			width_py -= RootFrame.EVENT_MARKING_WIDTH +			offset_py += RootFrame.EVENT_MARKING_WIDTH + +		(r ,g, b) = color +		color = wx.Colour(r, g, b) +		brush = wx.Brush(color, wx.SOLID) +		dc.SetBrush(brush) +		dc.DrawRectangle(offset_px, offset_py, width_px, width_py) + +	def update_rectangles(self, dc, start, end): +		start += self.ts_start +		end += self.ts_start +		self.sched_tracer.fill_zone(start, end) + +	def on_paint(self, event): +		dc = wx.PaintDC(self.scroll_panel) +		self.dc = dc + +		width = min(self.width_virtual, self.screen_width) +		(x, y) = self.scroll_start() +		start = self.px_to_us(x) +		end = self.px_to_us(x + width) +		self.update_rectangles(dc, start, end) + +	def rect_from_ypixel(self, y): +		y -= RootFrame.Y_OFFSET +		rect = y / (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE) +		height = y % (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE) + +		if rect < 0 or rect > self.nr_rects - 1 or height > RootFrame.RECT_HEIGHT: +			return -1 + +		return rect + +	def update_summary(self, txt): +		if self.txt: +			self.txt.Destroy() +		self.txt = wx.StaticText(self.panel, -1, txt, (0, (self.screen_height / 2) + 50)) + + +	def on_mouse_down(self, event): +		(x, y) = event.GetPositionTuple() +		rect = self.rect_from_ypixel(y) +		if rect == -1: +			return + +		t = self.px_to_us(x) + self.ts_start + +		self.sched_tracer.mouse_down(rect, t) + + +	def update_width_virtual(self): +		self.width_virtual = self.us_to_px(self.ts_end - self.ts_start) + +	def __zoom(self, x): +		self.update_width_virtual() +		(xpos, ypos) = self.scroll.GetViewStart() +		xpos = self.us_to_px(x) / self.scroll_scale +		self.scroll.SetScrollbars(self.scroll_scale, self.scroll_scale, self.width_virtual / self.scroll_scale, self.height_virtual / self.scroll_scale, xpos, ypos) +		self.Refresh() + +	def zoom_in(self): +		x = self.scroll_start_us() +		self.zoom *= 2 +		self.__zoom(x) + +	def zoom_out(self): +		x = self.scroll_start_us() +		self.zoom /= 2 +		self.__zoom(x) + + +	def on_key_press(self, event): +		key = event.GetRawKeyCode() +		if key == ord("+"): +			self.zoom_in() +			return +		if key == ord("-"): +			self.zoom_out() +			return + +		key = event.GetKeyCode() +		(x, y) = self.scroll.GetViewStart() +		if key == wx.WXK_RIGHT: +			self.scroll.Scroll(x + 1, y) +		elif key == wx.WXK_LEFT: +			self.scroll.Scroll(x - 1, y) +		elif key == wx.WXK_DOWN: +			self.scroll.Scroll(x, y + 1) +		elif key == wx.WXK_UP: +			self.scroll.Scroll(x, y - 1) |