summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/perf/scripts/python/sched-migration.py177
1 files changed, 92 insertions, 85 deletions
diff --git a/tools/perf/scripts/python/sched-migration.py b/tools/perf/scripts/python/sched-migration.py
index 9d46377f793b..6d7281a7de33 100644
--- a/tools/perf/scripts/python/sched-migration.py
+++ b/tools/perf/scripts/python/sched-migration.py
@@ -28,11 +28,11 @@ from Core import *
class RootFrame(wx.Frame):
Y_OFFSET = 100
- CPU_HEIGHT = 100
- CPU_SPACE = 50
+ RECT_HEIGHT = 100
+ RECT_SPACE = 50
EVENT_MARKING_WIDTH = 5
- def __init__(self, timeslices, parent = None, id = -1, title = "Migration"):
+ 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()
@@ -40,11 +40,12 @@ class RootFrame(wx.Frame):
self.screen_height -= 10
self.zoom = 0.5
self.scroll_scale = 20
- self.timeslices = timeslices
- (self.ts_start, self.ts_end) = timeslices.interval()
+ 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_cpus = timeslices.max_cpu() + 1
- self.height_virtual = RootFrame.Y_OFFSET + (self.nr_cpus * (RootFrame.CPU_HEIGHT + RootFrame.CPU_SPACE))
+ 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))
@@ -87,69 +88,38 @@ class RootFrame(wx.Frame):
(x, y) = self.scroll_start()
return self.px_to_us(x)
- def update_rectangle_cpu(self, dc, slice, cpu, offset_time):
- rq = slice.rqs[cpu]
-
- if slice.total_load != 0:
- load_rate = rq.load() / float(slice.total_load)
- else:
- load_rate = 0
+ 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
- offset_px = self.us_to_px(slice.start - offset_time)
- width_px = self.us_to_px(slice.end - slice.start)
- (x, y) = self.scroll_start()
+ dc = self.dc
- if width_px == 0:
- return
+ 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
- offset_py = RootFrame.Y_OFFSET + (cpu * (RootFrame.CPU_HEIGHT + RootFrame.CPU_SPACE))
- width_py = RootFrame.CPU_HEIGHT
-
- if cpu in slice.event_cpus:
- rgb = rq.event.color()
- if rgb is not None:
- (r, g, b) = rgb
- color = wx.Colour(r, g, b)
- brush = wx.Brush(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
-
- red_power = int(0xff - (0xff * load_rate))
- color = wx.Colour(0xff, red_power, red_power)
+ (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):
- if len(self.timeslices) == 0:
- return
- start += self.timeslices[0].start
- end += self.timeslices[0].start
-
- color = wx.Colour(0, 0, 0)
- brush = wx.Brush(color, wx.SOLID)
- dc.SetBrush(brush)
-
- i = self.timeslices.find_time_slice(start)
- if i == -1:
- return
-
- for i in xrange(i, len(self.timeslices)):
- timeslice = self.timeslices[i]
- if timeslice.start > end:
- return
-
- for cpu in timeslice.rqs:
- self.update_rectangle_cpu(dc, timeslice, cpu, self.timeslices[0].start)
+ start += self.ts_start
+ end += self.ts_start
+ self.sched_tracer.fill_zone(start, end)
def on_paint(self, event):
- color = wx.Colour(0xff, 0xff, 0xff)
- brush = wx.Brush(color, wx.SOLID)
dc = wx.PaintDC(self.scroll_panel)
- dc.SetBrush(brush)
+ self.dc = dc
width = min(self.width_virtual, self.screen_width)
(x, y) = self.scroll_start()
@@ -157,45 +127,31 @@ class RootFrame(wx.Frame):
end = self.px_to_us(x + width)
self.update_rectangles(dc, start, end)
- def cpu_from_ypixel(self, y):
+ def rect_from_ypixel(self, y):
y -= RootFrame.Y_OFFSET
- cpu = y / (RootFrame.CPU_HEIGHT + RootFrame.CPU_SPACE)
- height = y % (RootFrame.CPU_HEIGHT + RootFrame.CPU_SPACE)
+ rect = y / (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)
+ height = y % (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)
- if cpu < 0 or cpu > self.nr_cpus - 1 or height > RootFrame.CPU_HEIGHT:
+ if rect < 0 or rect > self.nr_rects - 1 or height > RootFrame.RECT_HEIGHT:
return -1
- return cpu
-
- def update_summary(self, cpu, t):
- idx = self.timeslices.find_time_slice(t)
- if idx == -1:
- return
-
- ts = self.timeslices[idx]
- rq = ts.rqs[cpu]
- raw = "CPU: %d\n" % cpu
- raw += "Last event : %s\n" % rq.event.__repr__()
- raw += "Timestamp : %d.%06d\n" % (ts.start / (10 ** 9), (ts.start % (10 ** 9)) / 1000)
- raw += "Duration : %6d us\n" % ((ts.end - ts.start) / (10 ** 6))
- raw += "Load = %d\n" % rq.load()
- for t in rq.tasks:
- raw += "%s \n" % thread_name(t)
+ return rect
+ def update_summary(self, txt):
if self.txt:
self.txt.Destroy()
- self.txt = wx.StaticText(self.panel, -1, raw, (0, (self.screen_height / 2) + 50))
+ self.txt = wx.StaticText(self.panel, -1, txt, (0, (self.screen_height / 2) + 50))
def on_mouse_down(self, event):
(x, y) = event.GetPositionTuple()
- cpu = self.cpu_from_ypixel(y)
- if cpu == -1:
+ rect = self.rect_from_ypixel(y)
+ if rect == -1:
return
- t = self.px_to_us(x) + self.timeslices[0].start
+ t = self.px_to_us(x) + self.ts_start
- self.update_summary(cpu, t)
+ self.sched_tracer.mouse_down(rect, t)
def update_width_virtual(self):
@@ -501,13 +457,64 @@ class TimeSliceList(UserList):
return found
+ def set_root_win(self, win):
+ self.root_win = win
+
+ def mouse_down(self, cpu, t):
+ idx = self.find_time_slice(t)
+ if idx == -1:
+ return
+
+ ts = self[idx]
+ rq = ts.rqs[cpu]
+ raw = "CPU: %d\n" % cpu
+ raw += "Last event : %s\n" % rq.event.__repr__()
+ raw += "Timestamp : %d.%06d\n" % (ts.start / (10 ** 9), (ts.start % (10 ** 9)) / 1000)
+ raw += "Duration : %6d us\n" % ((ts.end - ts.start) / (10 ** 6))
+ raw += "Load = %d\n" % rq.load()
+ for t in rq.tasks:
+ raw += "%s \n" % thread_name(t)
+
+ self.root_win.update_summary(raw)
+
+ def update_rectangle_cpu(self, slice, cpu):
+ rq = slice.rqs[cpu]
+
+ if slice.total_load != 0:
+ load_rate = rq.load() / float(slice.total_load)
+ else:
+ load_rate = 0
+
+ red_power = int(0xff - (0xff * load_rate))
+ color = (0xff, red_power, red_power)
+
+ top_color = None
+
+ if cpu in slice.event_cpus:
+ top_color = rq.event.color()
+
+ self.root_win.paint_rectangle_zone(cpu, color, top_color, slice.start, slice.end)
+
+ def fill_zone(self, start, end):
+ i = self.find_time_slice(start)
+ if i == -1:
+ return
+
+ for i in xrange(i, len(self.data)):
+ timeslice = self.data[i]
+ if timeslice.start > end:
+ return
+
+ for cpu in timeslice.rqs:
+ self.update_rectangle_cpu(timeslice, cpu)
+
def interval(self):
if len(self.data) == 0:
return (0, 0)
return (self.data[0].start, self.data[-1].end)
- def max_cpu(self):
+ def nr_rectangles(self):
last_ts = self.data[-1]
max_cpu = 0
for cpu in last_ts.rqs:
@@ -557,7 +564,7 @@ def trace_begin():
def trace_end():
app = wx.App(False)
timeslices = parser.timeslices
- frame = RootFrame(timeslices)
+ frame = RootFrame(timeslices, "Migration")
app.MainLoop()
def sched__sched_stat_runtime(event_name, context, common_cpu,