1dcee3bd3SJeff Roberson#!/usr/local/bin/python 2dcee3bd3SJeff Roberson 3dcee3bd3SJeff Roberson# Copyright (c) 2002-2003, Jeffrey Roberson <jeff@freebsd.org> 4dcee3bd3SJeff Roberson# All rights reserved. 5dcee3bd3SJeff Roberson# 6dcee3bd3SJeff Roberson# Redistribution and use in source and binary forms, with or without 7dcee3bd3SJeff Roberson# modification, are permitted provided that the following conditions 8dcee3bd3SJeff Roberson# are met: 9dcee3bd3SJeff Roberson# 1. Redistributions of source code must retain the above copyright 10dcee3bd3SJeff Roberson# notice unmodified, this list of conditions, and the following 11dcee3bd3SJeff Roberson# disclaimer. 12dcee3bd3SJeff Roberson# 2. Redistributions in binary form must reproduce the above copyright 13dcee3bd3SJeff Roberson# notice, this list of conditions and the following disclaimer in the 14dcee3bd3SJeff Roberson# documentation and/or other materials provided with the distribution. 15dcee3bd3SJeff Roberson# 16dcee3bd3SJeff Roberson# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17dcee3bd3SJeff Roberson# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18dcee3bd3SJeff Roberson# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19dcee3bd3SJeff Roberson# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20dcee3bd3SJeff Roberson# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21dcee3bd3SJeff Roberson# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22dcee3bd3SJeff Roberson# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23dcee3bd3SJeff Roberson# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24dcee3bd3SJeff Roberson# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25dcee3bd3SJeff Roberson# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26dcee3bd3SJeff Roberson# 27dcee3bd3SJeff Roberson# $FreeBSD$ 28dcee3bd3SJeff Roberson 29dcee3bd3SJeff Robersonimport sys 30dcee3bd3SJeff Robersonimport re 31dcee3bd3SJeff Robersonfrom Tkinter import * 32dcee3bd3SJeff Roberson 33698e6141SAndrew R. Reiter# To use: 34698e6141SAndrew R. Reiter# - Install the ports/x11-toolkits/py-tkinter package. 35698e6141SAndrew R. Reiter# - Add KTR_SCHED to KTR_COMPILE and KTR_MASK in your KERNCONF 36698e6141SAndrew R. Reiter# - It is encouraged to increase KTR_ENTRIES size to 32768 to gather 37698e6141SAndrew R. Reiter# enough information for analysis. 38698e6141SAndrew R. Reiter# - Rebuild kernel with proper changes to KERNCONF. 39698e6141SAndrew R. Reiter# - Dump the trace to a file: 'ktrdump -ct > ktr.out' 40698e6141SAndrew R. Reiter# - Run the python script: 'python schedgraph.py ktr.out' 41698e6141SAndrew R. Reiter# 42698e6141SAndrew R. Reiter# To do: 43dcee3bd3SJeff Roberson# 1) Add a per-thread summary display 44dcee3bd3SJeff Roberson# 2) Add bounding box style zoom. 45dcee3bd3SJeff Roberson# 3) Click to center. 46dcee3bd3SJeff Roberson# 4) Implement some sorting mechanism. 47dcee3bd3SJeff Roberson 48dcee3bd3SJeff Robersonticksps = None 49dcee3bd3SJeff Robersonstatus = None 50dcee3bd3SJeff Robersonconfigtypes = [] 51dcee3bd3SJeff Roberson 52dcee3bd3SJeff Robersondef ticks2sec(ticks): 534a2e6a08SJeff Roberson us = ticksps / 1000000 544a2e6a08SJeff Roberson ticks /= us 55dcee3bd3SJeff Roberson if (ticks < 1000): 56dcee3bd3SJeff Roberson return (str(ticks) + "us") 57dcee3bd3SJeff Roberson ticks /= 1000 58dcee3bd3SJeff Roberson if (ticks < 1000): 59dcee3bd3SJeff Roberson return (str(ticks) + "ms") 60dcee3bd3SJeff Roberson ticks /= 1000 61dcee3bd3SJeff Roberson return (str(ticks) + "s") 62dcee3bd3SJeff Roberson 63dcee3bd3SJeff Robersonclass Scaler(Frame): 64dcee3bd3SJeff Roberson def __init__(self, master, target): 65dcee3bd3SJeff Roberson Frame.__init__(self, master) 66dcee3bd3SJeff Roberson self.scale = Scale(self, command=self.scaleset, 670482a607SJeff Roberson from_=1000, to_=10000000, orient=HORIZONTAL, 680482a607SJeff Roberson resolution=1000) 69dcee3bd3SJeff Roberson self.label = Label(self, text="Ticks per pixel") 70dcee3bd3SJeff Roberson self.label.pack(side=LEFT) 71dcee3bd3SJeff Roberson self.scale.pack(fill="both", expand=1) 72dcee3bd3SJeff Roberson self.target = target 73dcee3bd3SJeff Roberson self.scale.set(target.scaleget()) 74dcee3bd3SJeff Roberson self.initialized = 1 75dcee3bd3SJeff Roberson 76dcee3bd3SJeff Roberson def scaleset(self, value): 77dcee3bd3SJeff Roberson self.target.scaleset(int(value)) 78dcee3bd3SJeff Roberson 79dcee3bd3SJeff Roberson def set(self, value): 80dcee3bd3SJeff Roberson self.scale.set(value) 81dcee3bd3SJeff Roberson 82dcee3bd3SJeff Robersonclass Status(Frame): 83dcee3bd3SJeff Roberson def __init__(self, master): 84dcee3bd3SJeff Roberson Frame.__init__(self, master) 85dcee3bd3SJeff Roberson self.label = Label(self, bd=1, relief=SUNKEN, anchor=W) 86dcee3bd3SJeff Roberson self.label.pack(fill="both", expand=1) 87dcee3bd3SJeff Roberson self.clear() 88dcee3bd3SJeff Roberson 89dcee3bd3SJeff Roberson def set(self, str): 90dcee3bd3SJeff Roberson self.label.config(text=str) 91dcee3bd3SJeff Roberson 92dcee3bd3SJeff Roberson def clear(self): 93dcee3bd3SJeff Roberson self.label.config(text="") 94dcee3bd3SJeff Roberson 95dcee3bd3SJeff Roberson def startup(self, str): 96dcee3bd3SJeff Roberson self.set(str) 97dcee3bd3SJeff Roberson root.update() 98dcee3bd3SJeff Roberson 99dcee3bd3SJeff Robersonclass EventConf(Frame): 100dcee3bd3SJeff Roberson def __init__(self, master, name, color, enabled): 101dcee3bd3SJeff Roberson Frame.__init__(self, master) 102dcee3bd3SJeff Roberson self.name = name 103dcee3bd3SJeff Roberson self.color = StringVar() 104dcee3bd3SJeff Roberson self.color_default = color 105dcee3bd3SJeff Roberson self.color_current = color 106dcee3bd3SJeff Roberson self.color.set(color) 107dcee3bd3SJeff Roberson self.enabled = IntVar() 108dcee3bd3SJeff Roberson self.enabled_default = enabled 109dcee3bd3SJeff Roberson self.enabled_current = enabled 110dcee3bd3SJeff Roberson self.enabled.set(enabled) 111dcee3bd3SJeff Roberson self.draw() 112dcee3bd3SJeff Roberson 113dcee3bd3SJeff Roberson def draw(self): 114dcee3bd3SJeff Roberson self.label = Label(self, text=self.name, anchor=W) 115dcee3bd3SJeff Roberson self.sample = Canvas(self, width=24, height=24, 116dcee3bd3SJeff Roberson bg='grey') 117dcee3bd3SJeff Roberson self.rect = self.sample.create_rectangle(0, 0, 24, 24, 118dcee3bd3SJeff Roberson fill=self.color.get()) 119dcee3bd3SJeff Roberson self.list = OptionMenu(self, self.color, 120dcee3bd3SJeff Roberson "dark red", "red", "pink", 121dcee3bd3SJeff Roberson "dark orange", "orange", 122dcee3bd3SJeff Roberson "yellow", "light yellow", 123dcee3bd3SJeff Roberson "dark green", "green", "light green", 124dcee3bd3SJeff Roberson "dark blue", "blue", "light blue", 125dcee3bd3SJeff Roberson "dark violet", "violet", "purple", 126dcee3bd3SJeff Roberson "dark grey", "light grey", 127dcee3bd3SJeff Roberson "white", "black", 128dcee3bd3SJeff Roberson command=self.setcolor) 129dcee3bd3SJeff Roberson self.checkbox = Checkbutton(self, text="enabled", 130dcee3bd3SJeff Roberson variable=self.enabled) 131dcee3bd3SJeff Roberson self.label.grid(row=0, column=0, sticky=E+W) 132dcee3bd3SJeff Roberson self.sample.grid(row=0, column=1) 133dcee3bd3SJeff Roberson self.list.grid(row=0, column=2, sticky=E+W) 134dcee3bd3SJeff Roberson self.checkbox.grid(row=0, column=3) 135dcee3bd3SJeff Roberson self.columnconfigure(0, weight=1) 136dcee3bd3SJeff Roberson self.columnconfigure(2, minsize=110) 137dcee3bd3SJeff Roberson 138dcee3bd3SJeff Roberson def setcolor(self, color): 139dcee3bd3SJeff Roberson self.color.set(color) 140dcee3bd3SJeff Roberson self.sample.itemconfigure(self.rect, fill=color) 141dcee3bd3SJeff Roberson 142dcee3bd3SJeff Roberson def apply(self): 143dcee3bd3SJeff Roberson cchange = 0 144dcee3bd3SJeff Roberson echange = 0 145dcee3bd3SJeff Roberson if (self.color_current != self.color.get()): 146dcee3bd3SJeff Roberson cchange = 1 147dcee3bd3SJeff Roberson if (self.enabled_current != self.enabled.get()): 148dcee3bd3SJeff Roberson echange = 1 149dcee3bd3SJeff Roberson self.color_current = self.color.get() 150dcee3bd3SJeff Roberson self.enabled_current = self.enabled.get() 151dcee3bd3SJeff Roberson if (echange != 0): 152dcee3bd3SJeff Roberson if (self.enabled_current): 153dcee3bd3SJeff Roberson graph.setcolor(self.name, self.color_current) 154dcee3bd3SJeff Roberson else: 155dcee3bd3SJeff Roberson graph.hide(self.name) 156dcee3bd3SJeff Roberson return 157dcee3bd3SJeff Roberson if (cchange != 0): 158dcee3bd3SJeff Roberson graph.setcolor(self.name, self.color_current) 159dcee3bd3SJeff Roberson 160dcee3bd3SJeff Roberson def revert(self): 161dcee3bd3SJeff Roberson self.setcolor(self.color_current) 162dcee3bd3SJeff Roberson self.enabled.set(self.enabled_current) 163dcee3bd3SJeff Roberson 164dcee3bd3SJeff Roberson def default(self): 165dcee3bd3SJeff Roberson self.setcolor(self.color_default) 166dcee3bd3SJeff Roberson self.enabled.set(self.enabled_default) 167dcee3bd3SJeff Roberson 168dcee3bd3SJeff Robersonclass EventConfigure(Toplevel): 169dcee3bd3SJeff Roberson def __init__(self): 170dcee3bd3SJeff Roberson Toplevel.__init__(self) 171dcee3bd3SJeff Roberson self.resizable(0, 0) 172dcee3bd3SJeff Roberson self.title("Event Configuration") 173dcee3bd3SJeff Roberson self.items = LabelFrame(self, text="Event Type") 174dcee3bd3SJeff Roberson self.buttons = Frame(self) 175dcee3bd3SJeff Roberson self.drawbuttons() 176dcee3bd3SJeff Roberson self.items.grid(row=0, column=0, sticky=E+W) 177dcee3bd3SJeff Roberson self.columnconfigure(0, weight=1) 178dcee3bd3SJeff Roberson self.buttons.grid(row=1, column=0, sticky=E+W) 179dcee3bd3SJeff Roberson self.types = [] 180dcee3bd3SJeff Roberson self.irow = 0 181dcee3bd3SJeff Roberson for type in configtypes: 182dcee3bd3SJeff Roberson self.additem(type.name, type.color, type.enabled) 183dcee3bd3SJeff Roberson 184dcee3bd3SJeff Roberson def additem(self, name, color, enabled=1): 185dcee3bd3SJeff Roberson item = EventConf(self.items, name, color, enabled) 186dcee3bd3SJeff Roberson self.types.append(item) 187dcee3bd3SJeff Roberson item.grid(row=self.irow, column=0, sticky=E+W) 188dcee3bd3SJeff Roberson self.irow += 1 189dcee3bd3SJeff Roberson 190dcee3bd3SJeff Roberson def drawbuttons(self): 191dcee3bd3SJeff Roberson self.apply = Button(self.buttons, text="Apply", 192dcee3bd3SJeff Roberson command=self.apress) 193dcee3bd3SJeff Roberson self.revert = Button(self.buttons, text="Revert", 194dcee3bd3SJeff Roberson command=self.rpress) 195dcee3bd3SJeff Roberson self.default = Button(self.buttons, text="Default", 196dcee3bd3SJeff Roberson command=self.dpress) 197dcee3bd3SJeff Roberson self.apply.grid(row=0, column=0, sticky=E+W) 198dcee3bd3SJeff Roberson self.revert.grid(row=0, column=1, sticky=E+W) 199dcee3bd3SJeff Roberson self.default.grid(row=0, column=2, sticky=E+W) 200dcee3bd3SJeff Roberson self.buttons.columnconfigure(0, weight=1) 201dcee3bd3SJeff Roberson self.buttons.columnconfigure(1, weight=1) 202dcee3bd3SJeff Roberson self.buttons.columnconfigure(2, weight=1) 203dcee3bd3SJeff Roberson 204dcee3bd3SJeff Roberson def apress(self): 205dcee3bd3SJeff Roberson for item in self.types: 206dcee3bd3SJeff Roberson item.apply() 207dcee3bd3SJeff Roberson 208dcee3bd3SJeff Roberson def rpress(self): 209dcee3bd3SJeff Roberson for item in self.types: 210dcee3bd3SJeff Roberson item.revert() 211dcee3bd3SJeff Roberson 212dcee3bd3SJeff Roberson def dpress(self): 213dcee3bd3SJeff Roberson for item in self.types: 214dcee3bd3SJeff Roberson item.default() 215dcee3bd3SJeff Roberson 216dcee3bd3SJeff Robersonclass EventView(Toplevel): 217dcee3bd3SJeff Roberson def __init__(self, event, canvas): 218dcee3bd3SJeff Roberson Toplevel.__init__(self) 219dcee3bd3SJeff Roberson self.resizable(0, 0) 220dcee3bd3SJeff Roberson self.title("Event") 221dcee3bd3SJeff Roberson self.event = event 222dcee3bd3SJeff Roberson self.frame = Frame(self) 223dcee3bd3SJeff Roberson self.frame.grid(row=0, column=0, sticky=N+S+E+W) 224dcee3bd3SJeff Roberson self.buttons = Frame(self) 225dcee3bd3SJeff Roberson self.buttons.grid(row=1, column=0, sticky=E+W) 226dcee3bd3SJeff Roberson self.canvas = canvas 227dcee3bd3SJeff Roberson self.drawlabels() 228dcee3bd3SJeff Roberson self.drawbuttons() 229dcee3bd3SJeff Roberson event.displayref(canvas) 230dcee3bd3SJeff Roberson self.bind("<Destroy>", self.destroycb) 231dcee3bd3SJeff Roberson 232dcee3bd3SJeff Roberson def destroycb(self, event): 233dcee3bd3SJeff Roberson self.unbind("<Destroy>") 234dcee3bd3SJeff Roberson if (self.event != None): 235dcee3bd3SJeff Roberson self.event.displayunref(self.canvas) 236dcee3bd3SJeff Roberson self.event = None 237dcee3bd3SJeff Roberson self.destroy() 238dcee3bd3SJeff Roberson 239dcee3bd3SJeff Roberson def clearlabels(self): 240dcee3bd3SJeff Roberson for label in self.frame.grid_slaves(): 241dcee3bd3SJeff Roberson label.grid_remove() 242dcee3bd3SJeff Roberson 243dcee3bd3SJeff Roberson def drawlabels(self): 244dcee3bd3SJeff Roberson ypos = 0 245dcee3bd3SJeff Roberson labels = self.event.labels() 246dcee3bd3SJeff Roberson while (len(labels) < 7): 247dcee3bd3SJeff Roberson labels.append(("", "", 0)) 248dcee3bd3SJeff Roberson for label in labels: 249dcee3bd3SJeff Roberson name, value, linked = label 250dcee3bd3SJeff Roberson l = Label(self.frame, text=name, bd=1, width=15, 251dcee3bd3SJeff Roberson relief=SUNKEN, anchor=W) 252dcee3bd3SJeff Roberson if (linked): 253dcee3bd3SJeff Roberson fgcolor = "blue" 254dcee3bd3SJeff Roberson else: 255dcee3bd3SJeff Roberson fgcolor = "black" 256dcee3bd3SJeff Roberson r = Label(self.frame, text=value, bd=1, 257dcee3bd3SJeff Roberson relief=SUNKEN, anchor=W, fg=fgcolor) 258dcee3bd3SJeff Roberson l.grid(row=ypos, column=0, sticky=E+W) 259dcee3bd3SJeff Roberson r.grid(row=ypos, column=1, sticky=E+W) 260dcee3bd3SJeff Roberson if (linked): 261dcee3bd3SJeff Roberson r.bind("<Button-1>", self.linkpress) 262dcee3bd3SJeff Roberson ypos += 1 263dcee3bd3SJeff Roberson self.frame.columnconfigure(1, minsize=80) 264dcee3bd3SJeff Roberson 265dcee3bd3SJeff Roberson def drawbuttons(self): 266dcee3bd3SJeff Roberson self.back = Button(self.buttons, text="<", command=self.bpress) 267dcee3bd3SJeff Roberson self.forw = Button(self.buttons, text=">", command=self.fpress) 268dcee3bd3SJeff Roberson self.new = Button(self.buttons, text="new", command=self.npress) 269dcee3bd3SJeff Roberson self.back.grid(row=0, column=0, sticky=E+W) 270dcee3bd3SJeff Roberson self.forw.grid(row=0, column=1, sticky=E+W) 271dcee3bd3SJeff Roberson self.new.grid(row=0, column=2, sticky=E+W) 272dcee3bd3SJeff Roberson self.buttons.columnconfigure(2, weight=1) 273dcee3bd3SJeff Roberson 274dcee3bd3SJeff Roberson def newevent(self, event): 275dcee3bd3SJeff Roberson self.event.displayunref(self.canvas) 276dcee3bd3SJeff Roberson self.clearlabels() 277dcee3bd3SJeff Roberson self.event = event 278dcee3bd3SJeff Roberson self.event.displayref(self.canvas) 279dcee3bd3SJeff Roberson self.drawlabels() 280dcee3bd3SJeff Roberson 281dcee3bd3SJeff Roberson def npress(self): 282dcee3bd3SJeff Roberson EventView(self.event, self.canvas) 283dcee3bd3SJeff Roberson 284dcee3bd3SJeff Roberson def bpress(self): 285dcee3bd3SJeff Roberson prev = self.event.prev() 286dcee3bd3SJeff Roberson if (prev == None): 287dcee3bd3SJeff Roberson return 288dcee3bd3SJeff Roberson while (prev.real == 0): 289dcee3bd3SJeff Roberson prev = prev.prev() 290dcee3bd3SJeff Roberson if (prev == None): 291dcee3bd3SJeff Roberson return 292dcee3bd3SJeff Roberson self.newevent(prev) 293dcee3bd3SJeff Roberson 294dcee3bd3SJeff Roberson def fpress(self): 295dcee3bd3SJeff Roberson next = self.event.next() 296dcee3bd3SJeff Roberson if (next == None): 297dcee3bd3SJeff Roberson return 298dcee3bd3SJeff Roberson while (next.real == 0): 299dcee3bd3SJeff Roberson next = next.next() 300dcee3bd3SJeff Roberson if (next == None): 301dcee3bd3SJeff Roberson return 302dcee3bd3SJeff Roberson self.newevent(next) 303dcee3bd3SJeff Roberson 304dcee3bd3SJeff Roberson def linkpress(self, wevent): 305dcee3bd3SJeff Roberson event = self.event.getlinked() 306dcee3bd3SJeff Roberson if (event != None): 307dcee3bd3SJeff Roberson self.newevent(event) 308dcee3bd3SJeff Roberson 309dcee3bd3SJeff Robersonclass Event: 310dcee3bd3SJeff Roberson name = "none" 311dcee3bd3SJeff Roberson color = "grey" 312dcee3bd3SJeff Roberson def __init__(self, source, cpu, timestamp, last=0): 313dcee3bd3SJeff Roberson self.source = source 314dcee3bd3SJeff Roberson self.cpu = cpu 315dcee3bd3SJeff Roberson self.timestamp = int(timestamp) 316dcee3bd3SJeff Roberson self.entries = [] 317dcee3bd3SJeff Roberson self.real = 1 318dcee3bd3SJeff Roberson self.idx = None 319dcee3bd3SJeff Roberson self.state = 0 320dcee3bd3SJeff Roberson self.item = None 321dcee3bd3SJeff Roberson self.dispcnt = 0 322dcee3bd3SJeff Roberson self.linked = None 323dcee3bd3SJeff Roberson if (last): 324dcee3bd3SJeff Roberson source.lastevent(self) 325dcee3bd3SJeff Roberson else: 326dcee3bd3SJeff Roberson source.event(self) 327dcee3bd3SJeff Roberson 328dcee3bd3SJeff Roberson def status(self): 329dcee3bd3SJeff Roberson statstr = self.name + " " + self.source.name 330dcee3bd3SJeff Roberson statstr += " on: cpu" + str(self.cpu) 331dcee3bd3SJeff Roberson statstr += " at: " + str(self.timestamp) 332dcee3bd3SJeff Roberson statstr += self.stattxt() 333dcee3bd3SJeff Roberson status.set(statstr) 334dcee3bd3SJeff Roberson 335dcee3bd3SJeff Roberson def stattxt(self): 336dcee3bd3SJeff Roberson return "" 337dcee3bd3SJeff Roberson 338dcee3bd3SJeff Roberson def textadd(self, tuple): 339dcee3bd3SJeff Roberson pass 340dcee3bd3SJeff Roberson self.entries.append(tuple) 341dcee3bd3SJeff Roberson 342dcee3bd3SJeff Roberson def labels(self): 343dcee3bd3SJeff Roberson return [("Source:", self.source.name, 0), 344dcee3bd3SJeff Roberson ("Event:", self.name, 0), 345dcee3bd3SJeff Roberson ("CPU:", self.cpu, 0), 346dcee3bd3SJeff Roberson ("Timestamp:", self.timestamp, 0)] + self.entries 347dcee3bd3SJeff Roberson def mouseenter(self, canvas, item): 348dcee3bd3SJeff Roberson self.displayref(canvas) 349dcee3bd3SJeff Roberson self.status() 350dcee3bd3SJeff Roberson 351dcee3bd3SJeff Roberson def mouseexit(self, canvas, item): 352dcee3bd3SJeff Roberson self.displayunref(canvas) 353dcee3bd3SJeff Roberson status.clear() 354dcee3bd3SJeff Roberson 355dcee3bd3SJeff Roberson def mousepress(self, canvas, item): 356dcee3bd3SJeff Roberson EventView(self, canvas) 357dcee3bd3SJeff Roberson 358dcee3bd3SJeff Roberson def next(self): 359dcee3bd3SJeff Roberson return self.source.eventat(self.idx + 1) 360dcee3bd3SJeff Roberson 361dcee3bd3SJeff Roberson def prev(self): 362dcee3bd3SJeff Roberson return self.source.eventat(self.idx - 1) 363dcee3bd3SJeff Roberson 364dcee3bd3SJeff Roberson def displayref(self, canvas): 365dcee3bd3SJeff Roberson if (self.dispcnt == 0): 366dcee3bd3SJeff Roberson canvas.itemconfigure(self.item, width=2) 367dcee3bd3SJeff Roberson self.dispcnt += 1 368dcee3bd3SJeff Roberson 369dcee3bd3SJeff Roberson def displayunref(self, canvas): 370dcee3bd3SJeff Roberson self.dispcnt -= 1 371dcee3bd3SJeff Roberson if (self.dispcnt == 0): 372dcee3bd3SJeff Roberson canvas.itemconfigure(self.item, width=0) 373dcee3bd3SJeff Roberson canvas.tag_raise("point", "state") 374dcee3bd3SJeff Roberson 375dcee3bd3SJeff Roberson def getlinked(self): 376dcee3bd3SJeff Roberson return self.linked.findevent(self.timestamp) 377dcee3bd3SJeff Roberson 378dcee3bd3SJeff Robersonclass PointEvent(Event): 379dcee3bd3SJeff Roberson def __init__(self, thread, cpu, timestamp, last=0): 380dcee3bd3SJeff Roberson Event.__init__(self, thread, cpu, timestamp, last) 381dcee3bd3SJeff Roberson 382dcee3bd3SJeff Roberson def draw(self, canvas, xpos, ypos): 383dcee3bd3SJeff Roberson l = canvas.create_oval(xpos - 6, ypos + 1, xpos + 6, ypos - 11, 384dcee3bd3SJeff Roberson fill=self.color, tags=("all", "point", "event") 385dcee3bd3SJeff Roberson + (self.name,), width=0) 386dcee3bd3SJeff Roberson canvas.events[l] = self 387dcee3bd3SJeff Roberson self.item = l 388dcee3bd3SJeff Roberson if (self.enabled == 0): 389dcee3bd3SJeff Roberson canvas.itemconfigure(l, state="hidden") 390dcee3bd3SJeff Roberson 391dcee3bd3SJeff Roberson return (xpos) 392dcee3bd3SJeff Roberson 393dcee3bd3SJeff Robersonclass StateEvent(Event): 394dcee3bd3SJeff Roberson def __init__(self, thread, cpu, timestamp, last=0): 395dcee3bd3SJeff Roberson Event.__init__(self, thread, cpu, timestamp, last) 396dcee3bd3SJeff Roberson self.duration = 0 397dcee3bd3SJeff Roberson self.skipnext = 0 398dcee3bd3SJeff Roberson self.skipself = 0 399dcee3bd3SJeff Roberson self.state = 1 400dcee3bd3SJeff Roberson 401dcee3bd3SJeff Roberson def draw(self, canvas, xpos, ypos): 402dcee3bd3SJeff Roberson next = self.nextstate() 403dcee3bd3SJeff Roberson if (self.skipself == 1 or next == None): 404dcee3bd3SJeff Roberson return (xpos) 4059a5c9d55SJeff Roberson while (self.skipnext): 406dcee3bd3SJeff Roberson skipped = next 407dcee3bd3SJeff Roberson next.skipself = 1 408dcee3bd3SJeff Roberson next.real = 0 409dcee3bd3SJeff Roberson next = next.nextstate() 410dcee3bd3SJeff Roberson if (next == None): 411dcee3bd3SJeff Roberson next = skipped 4129a5c9d55SJeff Roberson self.skipnext -= 1 413dcee3bd3SJeff Roberson self.duration = next.timestamp - self.timestamp 4140482a607SJeff Roberson if (self.duration < 0): 4150482a607SJeff Roberson self.duration = 0 4160482a607SJeff Roberson print "Unsynchronized timestamp" 4170482a607SJeff Roberson print self.cpu, self.timestamp 4180482a607SJeff Roberson print next.cpu, next.timestamp 419dcee3bd3SJeff Roberson delta = self.duration / canvas.ratio 420dcee3bd3SJeff Roberson l = canvas.create_rectangle(xpos, ypos, 421dcee3bd3SJeff Roberson xpos + delta, ypos - 10, fill=self.color, width=0, 422dcee3bd3SJeff Roberson tags=("all", "state", "event") + (self.name,)) 423dcee3bd3SJeff Roberson canvas.events[l] = self 424dcee3bd3SJeff Roberson self.item = l 425dcee3bd3SJeff Roberson if (self.enabled == 0): 426dcee3bd3SJeff Roberson canvas.itemconfigure(l, state="hidden") 427dcee3bd3SJeff Roberson 428dcee3bd3SJeff Roberson return (xpos + delta) 429dcee3bd3SJeff Roberson 430dcee3bd3SJeff Roberson def stattxt(self): 431dcee3bd3SJeff Roberson return " duration: " + ticks2sec(self.duration) 432dcee3bd3SJeff Roberson 433dcee3bd3SJeff Roberson def nextstate(self): 434dcee3bd3SJeff Roberson next = self.next() 435dcee3bd3SJeff Roberson while (next != None and next.state == 0): 436dcee3bd3SJeff Roberson next = next.next() 437dcee3bd3SJeff Roberson return (next) 438dcee3bd3SJeff Roberson 439dcee3bd3SJeff Roberson def labels(self): 440dcee3bd3SJeff Roberson return [("Source:", self.source.name, 0), 441dcee3bd3SJeff Roberson ("Event:", self.name, 0), 442dcee3bd3SJeff Roberson ("Timestamp:", self.timestamp, 0), 443dcee3bd3SJeff Roberson ("CPU:", self.cpu, 0), 444dcee3bd3SJeff Roberson ("Duration:", ticks2sec(self.duration), 0)] \ 445dcee3bd3SJeff Roberson + self.entries 446dcee3bd3SJeff Roberson 447dcee3bd3SJeff Robersonclass Count(Event): 448dcee3bd3SJeff Roberson name = "Count" 449dcee3bd3SJeff Roberson color = "red" 450dcee3bd3SJeff Roberson enabled = 1 451dcee3bd3SJeff Roberson def __init__(self, source, cpu, timestamp, count): 452dcee3bd3SJeff Roberson self.count = int(count) 453dcee3bd3SJeff Roberson Event.__init__(self, source, cpu, timestamp) 454dcee3bd3SJeff Roberson self.duration = 0 455dcee3bd3SJeff Roberson self.textadd(("count:", self.count, 0)) 456dcee3bd3SJeff Roberson 457dcee3bd3SJeff Roberson def draw(self, canvas, xpos, ypos): 458dcee3bd3SJeff Roberson next = self.next() 459dcee3bd3SJeff Roberson self.duration = next.timestamp - self.timestamp 460dcee3bd3SJeff Roberson delta = self.duration / canvas.ratio 461dcee3bd3SJeff Roberson yhight = self.source.yscale() * self.count 462dcee3bd3SJeff Roberson l = canvas.create_rectangle(xpos, ypos - yhight, 463dcee3bd3SJeff Roberson xpos + delta, ypos, fill=self.color, width=0, 464dcee3bd3SJeff Roberson tags=("all", "count", "event") + (self.name,)) 465dcee3bd3SJeff Roberson canvas.events[l] = self 466dcee3bd3SJeff Roberson self.item = l 467dcee3bd3SJeff Roberson if (self.enabled == 0): 468dcee3bd3SJeff Roberson canvas.itemconfigure(l, state="hidden") 469dcee3bd3SJeff Roberson return (xpos + delta) 470dcee3bd3SJeff Roberson 471dcee3bd3SJeff Roberson def stattxt(self): 472dcee3bd3SJeff Roberson return " count: " + str(self.count) 473dcee3bd3SJeff Roberson 474dcee3bd3SJeff Robersonconfigtypes.append(Count) 475dcee3bd3SJeff Roberson 476dcee3bd3SJeff Robersonclass Running(StateEvent): 477dcee3bd3SJeff Roberson name = "running" 478dcee3bd3SJeff Roberson color = "green" 479dcee3bd3SJeff Roberson enabled = 1 480dcee3bd3SJeff Roberson def __init__(self, thread, cpu, timestamp, prio): 481dcee3bd3SJeff Roberson StateEvent.__init__(self, thread, cpu, timestamp) 482dcee3bd3SJeff Roberson self.prio = prio 483dcee3bd3SJeff Roberson self.textadd(("prio:", self.prio, 0)) 484dcee3bd3SJeff Roberson 485dcee3bd3SJeff Robersonconfigtypes.append(Running) 486dcee3bd3SJeff Roberson 487dcee3bd3SJeff Robersonclass Idle(StateEvent): 488dcee3bd3SJeff Roberson name = "idle" 489dcee3bd3SJeff Roberson color = "grey" 490dcee3bd3SJeff Roberson enabled = 0 491dcee3bd3SJeff Roberson def __init__(self, thread, cpu, timestamp, prio): 492dcee3bd3SJeff Roberson StateEvent.__init__(self, thread, cpu, timestamp) 493dcee3bd3SJeff Roberson self.prio = prio 494dcee3bd3SJeff Roberson self.textadd(("prio:", self.prio, 0)) 495dcee3bd3SJeff Roberson 496dcee3bd3SJeff Robersonconfigtypes.append(Idle) 497dcee3bd3SJeff Roberson 498dcee3bd3SJeff Robersonclass Yielding(StateEvent): 499dcee3bd3SJeff Roberson name = "yielding" 500dcee3bd3SJeff Roberson color = "yellow" 501dcee3bd3SJeff Roberson enabled = 1 502dcee3bd3SJeff Roberson def __init__(self, thread, cpu, timestamp, prio): 503dcee3bd3SJeff Roberson StateEvent.__init__(self, thread, cpu, timestamp) 5044a2e6a08SJeff Roberson self.skipnext = 1 505dcee3bd3SJeff Roberson self.prio = prio 506dcee3bd3SJeff Roberson self.textadd(("prio:", self.prio, 0)) 507dcee3bd3SJeff Roberson 508dcee3bd3SJeff Robersonconfigtypes.append(Yielding) 509dcee3bd3SJeff Roberson 510dcee3bd3SJeff Robersonclass Swapped(StateEvent): 511dcee3bd3SJeff Roberson name = "swapped" 512dcee3bd3SJeff Roberson color = "violet" 513dcee3bd3SJeff Roberson enabled = 1 514dcee3bd3SJeff Roberson def __init__(self, thread, cpu, timestamp, prio): 515dcee3bd3SJeff Roberson StateEvent.__init__(self, thread, cpu, timestamp) 516dcee3bd3SJeff Roberson self.prio = prio 517dcee3bd3SJeff Roberson self.textadd(("prio:", self.prio, 0)) 518dcee3bd3SJeff Roberson 519dcee3bd3SJeff Robersonconfigtypes.append(Swapped) 520dcee3bd3SJeff Roberson 521dcee3bd3SJeff Robersonclass Suspended(StateEvent): 522dcee3bd3SJeff Roberson name = "suspended" 523dcee3bd3SJeff Roberson color = "purple" 524dcee3bd3SJeff Roberson enabled = 1 525dcee3bd3SJeff Roberson def __init__(self, thread, cpu, timestamp, prio): 526dcee3bd3SJeff Roberson StateEvent.__init__(self, thread, cpu, timestamp) 527dcee3bd3SJeff Roberson self.prio = prio 528dcee3bd3SJeff Roberson self.textadd(("prio:", self.prio, 0)) 529dcee3bd3SJeff Roberson 530dcee3bd3SJeff Robersonconfigtypes.append(Suspended) 531dcee3bd3SJeff Roberson 532dcee3bd3SJeff Robersonclass Iwait(StateEvent): 533dcee3bd3SJeff Roberson name = "iwait" 534dcee3bd3SJeff Roberson color = "grey" 535dcee3bd3SJeff Roberson enabled = 0 536dcee3bd3SJeff Roberson def __init__(self, thread, cpu, timestamp, prio): 537dcee3bd3SJeff Roberson StateEvent.__init__(self, thread, cpu, timestamp) 538dcee3bd3SJeff Roberson self.prio = prio 539dcee3bd3SJeff Roberson self.textadd(("prio:", self.prio, 0)) 540dcee3bd3SJeff Roberson 541dcee3bd3SJeff Robersonconfigtypes.append(Iwait) 542dcee3bd3SJeff Roberson 543dcee3bd3SJeff Robersonclass Preempted(StateEvent): 544dcee3bd3SJeff Roberson name = "preempted" 545dcee3bd3SJeff Roberson color = "red" 546dcee3bd3SJeff Roberson enabled = 1 547dcee3bd3SJeff Roberson def __init__(self, thread, cpu, timestamp, prio, bythread): 548dcee3bd3SJeff Roberson StateEvent.__init__(self, thread, cpu, timestamp) 5494a2e6a08SJeff Roberson self.skipnext = 1 550dcee3bd3SJeff Roberson self.prio = prio 551dcee3bd3SJeff Roberson self.linked = bythread 552dcee3bd3SJeff Roberson self.textadd(("prio:", self.prio, 0)) 553dcee3bd3SJeff Roberson self.textadd(("by thread:", self.linked.name, 1)) 554dcee3bd3SJeff Roberson 555dcee3bd3SJeff Robersonconfigtypes.append(Preempted) 556dcee3bd3SJeff Roberson 557dcee3bd3SJeff Robersonclass Sleep(StateEvent): 558dcee3bd3SJeff Roberson name = "sleep" 559dcee3bd3SJeff Roberson color = "blue" 560dcee3bd3SJeff Roberson enabled = 1 561dcee3bd3SJeff Roberson def __init__(self, thread, cpu, timestamp, prio, wmesg): 562dcee3bd3SJeff Roberson StateEvent.__init__(self, thread, cpu, timestamp) 563dcee3bd3SJeff Roberson self.prio = prio 564dcee3bd3SJeff Roberson self.wmesg = wmesg 565dcee3bd3SJeff Roberson self.textadd(("prio:", self.prio, 0)) 566dcee3bd3SJeff Roberson self.textadd(("wmesg:", self.wmesg, 0)) 567dcee3bd3SJeff Roberson 568dcee3bd3SJeff Roberson def stattxt(self): 569dcee3bd3SJeff Roberson statstr = StateEvent.stattxt(self) 570dcee3bd3SJeff Roberson statstr += " sleeping on: " + self.wmesg 571dcee3bd3SJeff Roberson return (statstr) 572dcee3bd3SJeff Roberson 573dcee3bd3SJeff Robersonconfigtypes.append(Sleep) 574dcee3bd3SJeff Roberson 575dcee3bd3SJeff Robersonclass Blocked(StateEvent): 576dcee3bd3SJeff Roberson name = "blocked" 577dcee3bd3SJeff Roberson color = "dark red" 578dcee3bd3SJeff Roberson enabled = 1 579dcee3bd3SJeff Roberson def __init__(self, thread, cpu, timestamp, prio, lock): 580dcee3bd3SJeff Roberson StateEvent.__init__(self, thread, cpu, timestamp) 581dcee3bd3SJeff Roberson self.prio = prio 582dcee3bd3SJeff Roberson self.lock = lock 583dcee3bd3SJeff Roberson self.textadd(("prio:", self.prio, 0)) 584dcee3bd3SJeff Roberson self.textadd(("lock:", self.lock, 0)) 585dcee3bd3SJeff Roberson 586dcee3bd3SJeff Roberson def stattxt(self): 587dcee3bd3SJeff Roberson statstr = StateEvent.stattxt(self) 588dcee3bd3SJeff Roberson statstr += " blocked on: " + self.lock 589dcee3bd3SJeff Roberson return (statstr) 590dcee3bd3SJeff Roberson 591dcee3bd3SJeff Robersonconfigtypes.append(Blocked) 592dcee3bd3SJeff Roberson 593dcee3bd3SJeff Robersonclass KsegrpRunq(StateEvent): 594dcee3bd3SJeff Roberson name = "KsegrpRunq" 595dcee3bd3SJeff Roberson color = "orange" 596dcee3bd3SJeff Roberson enabled = 1 597dcee3bd3SJeff Roberson def __init__(self, thread, cpu, timestamp, prio, bythread): 598dcee3bd3SJeff Roberson StateEvent.__init__(self, thread, cpu, timestamp) 599dcee3bd3SJeff Roberson self.prio = prio 600dcee3bd3SJeff Roberson self.linked = bythread 601dcee3bd3SJeff Roberson self.textadd(("prio:", self.prio, 0)) 602dcee3bd3SJeff Roberson self.textadd(("by thread:", self.linked.name, 1)) 603dcee3bd3SJeff Roberson 604dcee3bd3SJeff Robersonconfigtypes.append(KsegrpRunq) 605dcee3bd3SJeff Roberson 606dcee3bd3SJeff Robersonclass Runq(StateEvent): 607dcee3bd3SJeff Roberson name = "Runq" 608dcee3bd3SJeff Roberson color = "yellow" 609dcee3bd3SJeff Roberson enabled = 1 610dcee3bd3SJeff Roberson def __init__(self, thread, cpu, timestamp, prio, bythread): 611dcee3bd3SJeff Roberson StateEvent.__init__(self, thread, cpu, timestamp) 612dcee3bd3SJeff Roberson self.prio = prio 613dcee3bd3SJeff Roberson self.linked = bythread 614dcee3bd3SJeff Roberson self.textadd(("prio:", self.prio, 0)) 615dcee3bd3SJeff Roberson self.textadd(("by thread:", self.linked.name, 1)) 616dcee3bd3SJeff Roberson 617dcee3bd3SJeff Robersonconfigtypes.append(Runq) 618dcee3bd3SJeff Roberson 619dcee3bd3SJeff Robersonclass Sched_exit(StateEvent): 620dcee3bd3SJeff Roberson name = "exit" 621dcee3bd3SJeff Roberson color = "grey" 622dcee3bd3SJeff Roberson enabled = 0 623dcee3bd3SJeff Roberson def __init__(self, thread, cpu, timestamp, prio): 624dcee3bd3SJeff Roberson StateEvent.__init__(self, thread, cpu, timestamp) 625dcee3bd3SJeff Roberson self.name = "sched_exit" 626dcee3bd3SJeff Roberson self.prio = prio 627dcee3bd3SJeff Roberson self.textadd(("prio:", self.prio, 0)) 628dcee3bd3SJeff Roberson 629dcee3bd3SJeff Robersonconfigtypes.append(Sched_exit) 630dcee3bd3SJeff Roberson 631dcee3bd3SJeff Robersonclass Padevent(StateEvent): 632dcee3bd3SJeff Roberson def __init__(self, thread, cpu, timestamp, last=0): 633dcee3bd3SJeff Roberson StateEvent.__init__(self, thread, cpu, timestamp, last) 634dcee3bd3SJeff Roberson self.name = "pad" 635dcee3bd3SJeff Roberson self.real = 0 636dcee3bd3SJeff Roberson 637dcee3bd3SJeff Roberson def draw(self, canvas, xpos, ypos): 638dcee3bd3SJeff Roberson next = self.next() 639dcee3bd3SJeff Roberson if (next == None): 640dcee3bd3SJeff Roberson return (xpos) 641dcee3bd3SJeff Roberson self.duration = next.timestamp - self.timestamp 642dcee3bd3SJeff Roberson delta = self.duration / canvas.ratio 643dcee3bd3SJeff Roberson return (xpos + delta) 644dcee3bd3SJeff Roberson 645dcee3bd3SJeff Robersonclass Tick(PointEvent): 646dcee3bd3SJeff Roberson name = "tick" 647dcee3bd3SJeff Roberson color = "black" 648dcee3bd3SJeff Roberson enabled = 0 649dcee3bd3SJeff Roberson def __init__(self, thread, cpu, timestamp, prio, stathz): 650dcee3bd3SJeff Roberson PointEvent.__init__(self, thread, cpu, timestamp) 651dcee3bd3SJeff Roberson self.prio = prio 652dcee3bd3SJeff Roberson self.textadd(("prio:", self.prio, 0)) 653dcee3bd3SJeff Roberson 654dcee3bd3SJeff Robersonconfigtypes.append(Tick) 655dcee3bd3SJeff Roberson 656dcee3bd3SJeff Robersonclass Prio(PointEvent): 657dcee3bd3SJeff Roberson name = "prio" 658dcee3bd3SJeff Roberson color = "black" 659dcee3bd3SJeff Roberson enabled = 0 660dcee3bd3SJeff Roberson def __init__(self, thread, cpu, timestamp, prio, newprio, bythread): 661dcee3bd3SJeff Roberson PointEvent.__init__(self, thread, cpu, timestamp) 662dcee3bd3SJeff Roberson self.prio = prio 663dcee3bd3SJeff Roberson self.newprio = newprio 664dcee3bd3SJeff Roberson self.linked = bythread 665dcee3bd3SJeff Roberson self.textadd(("new prio:", self.newprio, 0)) 666dcee3bd3SJeff Roberson self.textadd(("prio:", self.prio, 0)) 667dcee3bd3SJeff Roberson if (self.linked != self.source): 668dcee3bd3SJeff Roberson self.textadd(("by thread:", self.linked.name, 1)) 669dcee3bd3SJeff Roberson else: 670dcee3bd3SJeff Roberson self.textadd(("by thread:", self.linked.name, 0)) 671dcee3bd3SJeff Roberson 672dcee3bd3SJeff Robersonconfigtypes.append(Prio) 673dcee3bd3SJeff Roberson 674dcee3bd3SJeff Robersonclass Lend(PointEvent): 675dcee3bd3SJeff Roberson name = "lend" 676dcee3bd3SJeff Roberson color = "black" 677dcee3bd3SJeff Roberson enabled = 0 678dcee3bd3SJeff Roberson def __init__(self, thread, cpu, timestamp, prio, tothread): 679dcee3bd3SJeff Roberson PointEvent.__init__(self, thread, cpu, timestamp) 680dcee3bd3SJeff Roberson self.prio = prio 681dcee3bd3SJeff Roberson self.linked = tothread 682dcee3bd3SJeff Roberson self.textadd(("prio:", self.prio, 0)) 683dcee3bd3SJeff Roberson self.textadd(("to thread:", self.linked.name, 1)) 684dcee3bd3SJeff Roberson 685dcee3bd3SJeff Robersonconfigtypes.append(Lend) 686dcee3bd3SJeff Roberson 687dcee3bd3SJeff Robersonclass Wokeup(PointEvent): 688dcee3bd3SJeff Roberson name = "wokeup" 689dcee3bd3SJeff Roberson color = "black" 690dcee3bd3SJeff Roberson enabled = 0 691dcee3bd3SJeff Roberson def __init__(self, thread, cpu, timestamp, ranthread): 692dcee3bd3SJeff Roberson PointEvent.__init__(self, thread, cpu, timestamp) 693dcee3bd3SJeff Roberson self.linked = ranthread 694dcee3bd3SJeff Roberson self.textadd(("ran thread:", self.linked.name, 1)) 695dcee3bd3SJeff Roberson 696dcee3bd3SJeff Robersonconfigtypes.append(Wokeup) 697dcee3bd3SJeff Roberson 698dcee3bd3SJeff Robersonclass EventSource: 699dcee3bd3SJeff Roberson def __init__(self, name): 700dcee3bd3SJeff Roberson self.name = name 701dcee3bd3SJeff Roberson self.events = [] 702dcee3bd3SJeff Roberson self.cpu = 0 703dcee3bd3SJeff Roberson self.cpux = 0 704dcee3bd3SJeff Roberson 705dcee3bd3SJeff Roberson def fixup(self): 706dcee3bd3SJeff Roberson pass 707dcee3bd3SJeff Roberson 708dcee3bd3SJeff Roberson def event(self, event): 709dcee3bd3SJeff Roberson self.events.insert(0, event) 710dcee3bd3SJeff Roberson 711dcee3bd3SJeff Roberson def remove(self, event): 712dcee3bd3SJeff Roberson self.events.remove(event) 713dcee3bd3SJeff Roberson 714dcee3bd3SJeff Roberson def lastevent(self, event): 715dcee3bd3SJeff Roberson self.events.append(event) 716dcee3bd3SJeff Roberson 717dcee3bd3SJeff Roberson def draw(self, canvas, ypos): 718dcee3bd3SJeff Roberson xpos = 10 719dcee3bd3SJeff Roberson self.cpux = 10 720dcee3bd3SJeff Roberson self.cpu = self.events[1].cpu 721dcee3bd3SJeff Roberson for i in range(0, len(self.events)): 722dcee3bd3SJeff Roberson self.events[i].idx = i 723dcee3bd3SJeff Roberson for event in self.events: 724dcee3bd3SJeff Roberson if (event.cpu != self.cpu and event.cpu != -1): 725dcee3bd3SJeff Roberson self.drawcpu(canvas, xpos, ypos) 726dcee3bd3SJeff Roberson self.cpux = xpos 727dcee3bd3SJeff Roberson self.cpu = event.cpu 728dcee3bd3SJeff Roberson xpos = event.draw(canvas, xpos, ypos) 729dcee3bd3SJeff Roberson self.drawcpu(canvas, xpos, ypos) 730dcee3bd3SJeff Roberson 731dcee3bd3SJeff Roberson def drawname(self, canvas, ypos): 732dcee3bd3SJeff Roberson ypos = ypos - (self.ysize() / 2) 733dcee3bd3SJeff Roberson canvas.create_text(10, ypos, anchor="w", text=self.name) 734dcee3bd3SJeff Roberson 735dcee3bd3SJeff Roberson def drawcpu(self, canvas, xpos, ypos): 736dcee3bd3SJeff Roberson cpu = int(self.cpu) 737dcee3bd3SJeff Roberson if (cpu == 0): 738dcee3bd3SJeff Roberson color = 'light grey' 739dcee3bd3SJeff Roberson elif (cpu == 1): 740dcee3bd3SJeff Roberson color = 'dark grey' 741dcee3bd3SJeff Roberson elif (cpu == 2): 742dcee3bd3SJeff Roberson color = 'light blue' 743dcee3bd3SJeff Roberson elif (cpu == 3): 7446030f133SRobert Watson color = 'light green' 74593fb9479SJeff Roberson elif (cpu == 4): 74693fb9479SJeff Roberson color = 'blanched almond' 74793fb9479SJeff Roberson elif (cpu == 5): 74893fb9479SJeff Roberson color = 'slate grey' 74993fb9479SJeff Roberson elif (cpu == 6): 75093fb9479SJeff Roberson color = 'light slate blue' 75193fb9479SJeff Roberson elif (cpu == 7): 75293fb9479SJeff Roberson color = 'thistle' 753dcee3bd3SJeff Roberson else: 7546030f133SRobert Watson color = "white" 755dcee3bd3SJeff Roberson l = canvas.create_rectangle(self.cpux, 756dcee3bd3SJeff Roberson ypos - self.ysize() - canvas.bdheight, 757dcee3bd3SJeff Roberson xpos, ypos + canvas.bdheight, fill=color, width=0, 758dcee3bd3SJeff Roberson tags=("all", "cpuinfo")) 759dcee3bd3SJeff Roberson 760dcee3bd3SJeff Roberson def ysize(self): 761dcee3bd3SJeff Roberson return (None) 762dcee3bd3SJeff Roberson 763dcee3bd3SJeff Roberson def eventat(self, i): 764dcee3bd3SJeff Roberson if (i >= len(self.events)): 765dcee3bd3SJeff Roberson return (None) 766dcee3bd3SJeff Roberson event = self.events[i] 767dcee3bd3SJeff Roberson return (event) 768dcee3bd3SJeff Roberson 769dcee3bd3SJeff Roberson def findevent(self, timestamp): 770dcee3bd3SJeff Roberson for event in self.events: 771dcee3bd3SJeff Roberson if (event.timestamp >= timestamp and event.real): 772dcee3bd3SJeff Roberson return (event) 773dcee3bd3SJeff Roberson return (None) 774dcee3bd3SJeff Roberson 775dcee3bd3SJeff Robersonclass Thread(EventSource): 776dcee3bd3SJeff Roberson names = {} 777dcee3bd3SJeff Roberson def __init__(self, td, pcomm): 778dcee3bd3SJeff Roberson EventSource.__init__(self, pcomm) 779dcee3bd3SJeff Roberson self.str = td 780dcee3bd3SJeff Roberson try: 781dcee3bd3SJeff Roberson cnt = Thread.names[pcomm] 782dcee3bd3SJeff Roberson except: 783dcee3bd3SJeff Roberson Thread.names[pcomm] = 0 784dcee3bd3SJeff Roberson return 785dcee3bd3SJeff Roberson Thread.names[pcomm] = cnt + 1 786dcee3bd3SJeff Roberson 787dcee3bd3SJeff Roberson def fixup(self): 788dcee3bd3SJeff Roberson cnt = Thread.names[self.name] 789dcee3bd3SJeff Roberson if (cnt == 0): 790dcee3bd3SJeff Roberson return 791dcee3bd3SJeff Roberson cnt -= 1 792dcee3bd3SJeff Roberson Thread.names[self.name] = cnt 793dcee3bd3SJeff Roberson self.name += " td" + str(cnt) 794dcee3bd3SJeff Roberson 795dcee3bd3SJeff Roberson def ysize(self): 796dcee3bd3SJeff Roberson return (10) 797dcee3bd3SJeff Roberson 798dcee3bd3SJeff Robersonclass Counter(EventSource): 799dcee3bd3SJeff Roberson max = 0 800dcee3bd3SJeff Roberson def __init__(self, name): 801dcee3bd3SJeff Roberson EventSource.__init__(self, name) 802dcee3bd3SJeff Roberson 803dcee3bd3SJeff Roberson def event(self, event): 804dcee3bd3SJeff Roberson EventSource.event(self, event) 805dcee3bd3SJeff Roberson try: 806dcee3bd3SJeff Roberson count = event.count 807dcee3bd3SJeff Roberson except: 808dcee3bd3SJeff Roberson return 809dcee3bd3SJeff Roberson count = int(count) 810dcee3bd3SJeff Roberson if (count > Counter.max): 811dcee3bd3SJeff Roberson Counter.max = count 812dcee3bd3SJeff Roberson 813dcee3bd3SJeff Roberson def ysize(self): 814dcee3bd3SJeff Roberson return (80) 815dcee3bd3SJeff Roberson 816dcee3bd3SJeff Roberson def yscale(self): 817dcee3bd3SJeff Roberson return (self.ysize() / Counter.max) 818dcee3bd3SJeff Roberson 819dcee3bd3SJeff Roberson 820dcee3bd3SJeff Robersonclass KTRFile: 821dcee3bd3SJeff Roberson def __init__(self, file): 8220482a607SJeff Roberson self.timestamp_first = {} 8230482a607SJeff Roberson self.timestamp_last = {} 8240482a607SJeff Roberson self.timestamp_adjust = {} 8250482a607SJeff Roberson self.timestamp_f = None 8260482a607SJeff Roberson self.timestamp_l = None 827dcee3bd3SJeff Roberson self.lineno = -1 828dcee3bd3SJeff Roberson self.threads = [] 829dcee3bd3SJeff Roberson self.sources = [] 830dcee3bd3SJeff Roberson self.ticks = {} 831dcee3bd3SJeff Roberson self.load = {} 83201e7fb47SScott Long self.crit = {} 8330482a607SJeff Roberson self.stathz = 0 834dcee3bd3SJeff Roberson 835dcee3bd3SJeff Roberson self.parse(file) 836dcee3bd3SJeff Roberson self.fixup() 837dcee3bd3SJeff Roberson global ticksps 8380482a607SJeff Roberson print "first", self.timestamp_f, "last", self.timestamp_l 8390482a607SJeff Roberson print "time span", self.timespan() 8404a2e6a08SJeff Roberson print "stathz", self.stathz 8410482a607SJeff Roberson ticksps = self.ticksps() 8420482a607SJeff Roberson print "Ticks per second", ticksps 843dcee3bd3SJeff Roberson 844dcee3bd3SJeff Roberson def parse(self, file): 845dcee3bd3SJeff Roberson try: 846dcee3bd3SJeff Roberson ifp = open(file) 847dcee3bd3SJeff Roberson except: 848dcee3bd3SJeff Roberson print "Can't open", file 849dcee3bd3SJeff Roberson sys.exit(1) 850dcee3bd3SJeff Roberson 851dcee3bd3SJeff Roberson ktrhdr = "\s+\d+\s+(\d+)\s+(\d+)\s+" 852dcee3bd3SJeff Roberson tdname = "(\S+)\(([^)]*)\)" 85301e7fb47SScott Long crittdname = "(\S+)\s+\(\d+,\s+([^)]*)\)" 854dcee3bd3SJeff Roberson 855dcee3bd3SJeff Roberson ktrstr = "mi_switch: " + tdname 856dcee3bd3SJeff Roberson ktrstr += " prio (\d+) inhibit (\d+) wmesg (\S+) lock (\S+)" 857dcee3bd3SJeff Roberson switchout_re = re.compile(ktrhdr + ktrstr) 858dcee3bd3SJeff Roberson 859dcee3bd3SJeff Roberson ktrstr = "mi_switch: " + tdname + " prio (\d+) idle" 860dcee3bd3SJeff Roberson idled_re = re.compile(ktrhdr + ktrstr) 861dcee3bd3SJeff Roberson 862dcee3bd3SJeff Roberson ktrstr = "mi_switch: " + tdname + " prio (\d+) preempted by " 863dcee3bd3SJeff Roberson ktrstr += tdname 864dcee3bd3SJeff Roberson preempted_re = re.compile(ktrhdr + ktrstr) 865dcee3bd3SJeff Roberson 866dcee3bd3SJeff Roberson ktrstr = "mi_switch: running " + tdname + " prio (\d+)" 867dcee3bd3SJeff Roberson switchin_re = re.compile(ktrhdr + ktrstr) 868dcee3bd3SJeff Roberson 869dcee3bd3SJeff Roberson ktrstr = "sched_add: " + tdname + " prio (\d+) by " + tdname 870dcee3bd3SJeff Roberson sched_add_re = re.compile(ktrhdr + ktrstr) 871dcee3bd3SJeff Roberson 872dcee3bd3SJeff Roberson ktrstr = "setrunqueue: " + tdname + " prio (\d+) by " + tdname 873dcee3bd3SJeff Roberson setrunqueue_re = re.compile(ktrhdr + ktrstr) 874dcee3bd3SJeff Roberson 875dcee3bd3SJeff Roberson ktrstr = "sched_rem: " + tdname + " prio (\d+) by " + tdname 876dcee3bd3SJeff Roberson sched_rem_re = re.compile(ktrhdr + ktrstr) 877dcee3bd3SJeff Roberson 878dcee3bd3SJeff Roberson ktrstr = "sched_exit_thread: " + tdname + " prio (\d+)" 879dcee3bd3SJeff Roberson sched_exit_re = re.compile(ktrhdr + ktrstr) 880dcee3bd3SJeff Roberson 881dcee3bd3SJeff Roberson ktrstr = "statclock: " + tdname + " prio (\d+)" 882dcee3bd3SJeff Roberson ktrstr += " stathz (\d+)" 883dcee3bd3SJeff Roberson sched_clock_re = re.compile(ktrhdr + ktrstr) 884dcee3bd3SJeff Roberson 885dcee3bd3SJeff Roberson ktrstr = "sched_prio: " + tdname + " prio (\d+)" 886dcee3bd3SJeff Roberson ktrstr += " newprio (\d+) by " + tdname 887dcee3bd3SJeff Roberson sched_prio_re = re.compile(ktrhdr + ktrstr) 888dcee3bd3SJeff Roberson 8893e16b3e0SJeff Roberson cpuload_re = re.compile(ktrhdr + "load: (\d+)") 8903e16b3e0SJeff Roberson loadglobal_re = re.compile(ktrhdr + "global load: (\d+)") 891dcee3bd3SJeff Roberson 89201e7fb47SScott Long ktrstr = "critical_\S+ by thread " + crittdname + " to (\d+)" 89301e7fb47SScott Long critsec_re = re.compile(ktrhdr + ktrstr) 89401e7fb47SScott Long 895dcee3bd3SJeff Roberson parsers = [[cpuload_re, self.cpuload], 896dcee3bd3SJeff Roberson [loadglobal_re, self.loadglobal], 897dcee3bd3SJeff Roberson [switchin_re, self.switchin], 898dcee3bd3SJeff Roberson [switchout_re, self.switchout], 899dcee3bd3SJeff Roberson [sched_add_re, self.sched_add], 900dcee3bd3SJeff Roberson [setrunqueue_re, self.sched_rem], 901dcee3bd3SJeff Roberson [sched_prio_re, self.sched_prio], 902dcee3bd3SJeff Roberson [preempted_re, self.preempted], 903dcee3bd3SJeff Roberson [sched_rem_re, self.sched_rem], 904dcee3bd3SJeff Roberson [sched_exit_re, self.sched_exit], 905dcee3bd3SJeff Roberson [sched_clock_re, self.sched_clock], 90601e7fb47SScott Long [critsec_re, self.critsec], 907dcee3bd3SJeff Roberson [idled_re, self.idled]] 908dcee3bd3SJeff Roberson 9090482a607SJeff Roberson lines = ifp.readlines() 9100482a607SJeff Roberson self.synchstamp(lines) 9110482a607SJeff Roberson for line in lines: 912dcee3bd3SJeff Roberson self.lineno += 1 913dcee3bd3SJeff Roberson if ((self.lineno % 1024) == 0): 914dcee3bd3SJeff Roberson status.startup("Parsing line " + 915dcee3bd3SJeff Roberson str(self.lineno)) 916dcee3bd3SJeff Roberson for p in parsers: 917dcee3bd3SJeff Roberson m = p[0].match(line) 918dcee3bd3SJeff Roberson if (m != None): 919dcee3bd3SJeff Roberson p[1](*m.groups()) 920dcee3bd3SJeff Roberson break 921dcee3bd3SJeff Roberson # if (m == None): 922dcee3bd3SJeff Roberson # print line, 923dcee3bd3SJeff Roberson 9240482a607SJeff Roberson def synchstamp(self, lines): 9250482a607SJeff Roberson status.startup("Rationalizing Timestamps") 9260482a607SJeff Roberson tstamp_re = re.compile("\s+\d+\s+(\d+)\s+(\d+)\s+.*") 9270482a607SJeff Roberson for line in lines: 9280482a607SJeff Roberson m = tstamp_re.match(line) 9290482a607SJeff Roberson if (m != None): 9300482a607SJeff Roberson self.addstamp(*m.groups()) 9310482a607SJeff Roberson self.pickstamp() 9320482a607SJeff Roberson self.monostamp(lines) 9330482a607SJeff Roberson 9340482a607SJeff Roberson 9350482a607SJeff Roberson def monostamp(self, lines): 9360482a607SJeff Roberson laststamp = None 9370482a607SJeff Roberson tstamp_re = re.compile("\s+\d+\s+(\d+)\s+(\d+)\s+.*") 9380482a607SJeff Roberson for line in lines: 9390482a607SJeff Roberson m = tstamp_re.match(line) 9400482a607SJeff Roberson if (m == None): 9410482a607SJeff Roberson continue 9420482a607SJeff Roberson (cpu, timestamp) = m.groups() 943dcee3bd3SJeff Roberson timestamp = int(timestamp) 9440482a607SJeff Roberson cpu = int(cpu) 9450482a607SJeff Roberson timestamp -= self.timestamp_adjust[cpu] 9460482a607SJeff Roberson if (laststamp != None and timestamp > laststamp): 9470482a607SJeff Roberson self.timestamp_adjust[cpu] += timestamp - laststamp 9480482a607SJeff Roberson laststamp = timestamp 9490482a607SJeff Roberson 9500482a607SJeff Roberson def addstamp(self, cpu, timestamp): 9510482a607SJeff Roberson timestamp = int(timestamp) 9520482a607SJeff Roberson cpu = int(cpu) 9530482a607SJeff Roberson try: 9540482a607SJeff Roberson if (timestamp > self.timestamp_first[cpu]): 9550482a607SJeff Roberson return 9560482a607SJeff Roberson except: 9570482a607SJeff Roberson self.timestamp_first[cpu] = timestamp 9580482a607SJeff Roberson self.timestamp_last[cpu] = timestamp 9590482a607SJeff Roberson 9600482a607SJeff Roberson def pickstamp(self): 9610482a607SJeff Roberson base = self.timestamp_last[0] 9620482a607SJeff Roberson for i in range(0, len(self.timestamp_last)): 9630482a607SJeff Roberson if (self.timestamp_last[i] < base): 9640482a607SJeff Roberson base = self.timestamp_last[i] 9650482a607SJeff Roberson 9660482a607SJeff Roberson print "Adjusting to base stamp", base 9670482a607SJeff Roberson for i in range(0, len(self.timestamp_last)): 9680482a607SJeff Roberson self.timestamp_adjust[i] = self.timestamp_last[i] - base; 9690482a607SJeff Roberson print "CPU ", i, "adjust by ", self.timestamp_adjust[i] 9700482a607SJeff Roberson 9710482a607SJeff Roberson self.timestamp_f = 0 9720482a607SJeff Roberson for i in range(0, len(self.timestamp_first)): 9730482a607SJeff Roberson first = self.timestamp_first[i] - self.timestamp_adjust[i] 9740482a607SJeff Roberson if (first > self.timestamp_f): 9750482a607SJeff Roberson self.timestamp_f = first 9760482a607SJeff Roberson 9770482a607SJeff Roberson self.timestamp_l = 0 9780482a607SJeff Roberson for i in range(0, len(self.timestamp_last)): 9790482a607SJeff Roberson last = self.timestamp_last[i] - self.timestamp_adjust[i] 9800482a607SJeff Roberson if (last > self.timestamp_l): 9810482a607SJeff Roberson self.timestamp_l = last 9820482a607SJeff Roberson 9830482a607SJeff Roberson 9840482a607SJeff Roberson def checkstamp(self, cpu, timestamp): 9850482a607SJeff Roberson cpu = int(cpu) 9860482a607SJeff Roberson timestamp = int(timestamp) 9870482a607SJeff Roberson if (timestamp > self.timestamp_first[cpu]): 988dcee3bd3SJeff Roberson print "Bad timestamp on line ", self.lineno 989dcee3bd3SJeff Roberson return (0) 9900482a607SJeff Roberson timestamp -= self.timestamp_adjust[cpu] 9910482a607SJeff Roberson return (timestamp) 992dcee3bd3SJeff Roberson 993dcee3bd3SJeff Roberson def timespan(self): 9940482a607SJeff Roberson return (self.timestamp_f - self.timestamp_l); 995dcee3bd3SJeff Roberson 996dcee3bd3SJeff Roberson def ticksps(self): 997dcee3bd3SJeff Roberson return (self.timespan() / self.ticks[0]) * int(self.stathz) 998dcee3bd3SJeff Roberson 999dcee3bd3SJeff Roberson def switchout(self, cpu, timestamp, td, pcomm, prio, inhibit, wmesg, lock): 1000dcee3bd3SJeff Roberson TDI_SUSPENDED = 0x0001 1001dcee3bd3SJeff Roberson TDI_SLEEPING = 0x0002 1002dcee3bd3SJeff Roberson TDI_SWAPPED = 0x0004 1003dcee3bd3SJeff Roberson TDI_LOCK = 0x0008 1004dcee3bd3SJeff Roberson TDI_IWAIT = 0x0010 1005dcee3bd3SJeff Roberson 10060482a607SJeff Roberson timestamp = self.checkstamp(cpu, timestamp) 10070482a607SJeff Roberson if (timestamp == 0): 1008dcee3bd3SJeff Roberson return 1009dcee3bd3SJeff Roberson inhibit = int(inhibit) 1010dcee3bd3SJeff Roberson thread = self.findtd(td, pcomm) 1011dcee3bd3SJeff Roberson if (inhibit & TDI_SWAPPED): 1012dcee3bd3SJeff Roberson Swapped(thread, cpu, timestamp, prio) 1013dcee3bd3SJeff Roberson elif (inhibit & TDI_SLEEPING): 1014dcee3bd3SJeff Roberson Sleep(thread, cpu, timestamp, prio, wmesg) 1015dcee3bd3SJeff Roberson elif (inhibit & TDI_LOCK): 1016dcee3bd3SJeff Roberson Blocked(thread, cpu, timestamp, prio, lock) 1017dcee3bd3SJeff Roberson elif (inhibit & TDI_IWAIT): 1018dcee3bd3SJeff Roberson Iwait(thread, cpu, timestamp, prio) 1019dcee3bd3SJeff Roberson elif (inhibit & TDI_SUSPENDED): 1020dcee3bd3SJeff Roberson Suspended(thread, cpu, timestamp, prio) 1021dcee3bd3SJeff Roberson elif (inhibit == 0): 1022dcee3bd3SJeff Roberson Yielding(thread, cpu, timestamp, prio) 1023dcee3bd3SJeff Roberson else: 1024dcee3bd3SJeff Roberson print "Unknown event", inhibit 1025dcee3bd3SJeff Roberson sys.exit(1) 1026dcee3bd3SJeff Roberson 1027dcee3bd3SJeff Roberson def idled(self, cpu, timestamp, td, pcomm, prio): 10280482a607SJeff Roberson timestamp = self.checkstamp(cpu, timestamp) 10290482a607SJeff Roberson if (timestamp == 0): 1030dcee3bd3SJeff Roberson return 1031dcee3bd3SJeff Roberson thread = self.findtd(td, pcomm) 1032dcee3bd3SJeff Roberson Idle(thread, cpu, timestamp, prio) 1033dcee3bd3SJeff Roberson 1034dcee3bd3SJeff Roberson def preempted(self, cpu, timestamp, td, pcomm, prio, bytd, bypcomm): 10350482a607SJeff Roberson timestamp = self.checkstamp(cpu, timestamp) 10360482a607SJeff Roberson if (timestamp == 0): 1037dcee3bd3SJeff Roberson return 1038dcee3bd3SJeff Roberson thread = self.findtd(td, pcomm) 1039dcee3bd3SJeff Roberson Preempted(thread, cpu, timestamp, prio, 1040dcee3bd3SJeff Roberson self.findtd(bytd, bypcomm)) 1041dcee3bd3SJeff Roberson 1042dcee3bd3SJeff Roberson def switchin(self, cpu, timestamp, td, pcomm, prio): 10430482a607SJeff Roberson timestamp = self.checkstamp(cpu, timestamp) 10440482a607SJeff Roberson if (timestamp == 0): 1045dcee3bd3SJeff Roberson return 1046dcee3bd3SJeff Roberson thread = self.findtd(td, pcomm) 1047dcee3bd3SJeff Roberson Running(thread, cpu, timestamp, prio) 1048dcee3bd3SJeff Roberson 1049dcee3bd3SJeff Roberson def sched_add(self, cpu, timestamp, td, pcomm, prio, bytd, bypcomm): 10500482a607SJeff Roberson timestamp = self.checkstamp(cpu, timestamp) 10510482a607SJeff Roberson if (timestamp == 0): 1052dcee3bd3SJeff Roberson return 1053dcee3bd3SJeff Roberson thread = self.findtd(td, pcomm) 1054dcee3bd3SJeff Roberson bythread = self.findtd(bytd, bypcomm) 1055dcee3bd3SJeff Roberson Runq(thread, cpu, timestamp, prio, bythread) 1056dcee3bd3SJeff Roberson Wokeup(bythread, cpu, timestamp, thread) 1057dcee3bd3SJeff Roberson 1058dcee3bd3SJeff Roberson def sched_rem(self, cpu, timestamp, td, pcomm, prio, bytd, bypcomm): 10590482a607SJeff Roberson timestamp = self.checkstamp(cpu, timestamp) 10600482a607SJeff Roberson if (timestamp == 0): 1061dcee3bd3SJeff Roberson return 1062dcee3bd3SJeff Roberson thread = self.findtd(td, pcomm) 1063dcee3bd3SJeff Roberson KsegrpRunq(thread, cpu, timestamp, prio, 1064dcee3bd3SJeff Roberson self.findtd(bytd, bypcomm)) 1065dcee3bd3SJeff Roberson 1066dcee3bd3SJeff Roberson def sched_exit(self, cpu, timestamp, td, pcomm, prio): 10670482a607SJeff Roberson timestamp = self.checkstamp(cpu, timestamp) 10680482a607SJeff Roberson if (timestamp == 0): 1069dcee3bd3SJeff Roberson return 1070dcee3bd3SJeff Roberson thread = self.findtd(td, pcomm) 1071dcee3bd3SJeff Roberson Sched_exit(thread, cpu, timestamp, prio) 1072dcee3bd3SJeff Roberson 1073dcee3bd3SJeff Roberson def sched_clock(self, cpu, timestamp, td, pcomm, prio, stathz): 10740482a607SJeff Roberson timestamp = self.checkstamp(cpu, timestamp) 10750482a607SJeff Roberson if (timestamp == 0): 1076dcee3bd3SJeff Roberson return 1077dcee3bd3SJeff Roberson self.stathz = stathz 1078dcee3bd3SJeff Roberson cpu = int(cpu) 1079dcee3bd3SJeff Roberson try: 1080dcee3bd3SJeff Roberson ticks = self.ticks[cpu] 1081dcee3bd3SJeff Roberson except: 1082dcee3bd3SJeff Roberson self.ticks[cpu] = 0 1083dcee3bd3SJeff Roberson self.ticks[cpu] += 1 1084dcee3bd3SJeff Roberson thread = self.findtd(td, pcomm) 1085dcee3bd3SJeff Roberson Tick(thread, cpu, timestamp, prio, stathz) 1086dcee3bd3SJeff Roberson 1087dcee3bd3SJeff Roberson def sched_prio(self, cpu, timestamp, td, pcomm, prio, newprio, bytd, bypcomm): 1088dcee3bd3SJeff Roberson if (prio == newprio): 1089dcee3bd3SJeff Roberson return 10900482a607SJeff Roberson timestamp = self.checkstamp(cpu, timestamp) 10910482a607SJeff Roberson if (timestamp == 0): 1092dcee3bd3SJeff Roberson return 1093dcee3bd3SJeff Roberson thread = self.findtd(td, pcomm) 1094dcee3bd3SJeff Roberson bythread = self.findtd(bytd, bypcomm) 1095dcee3bd3SJeff Roberson Prio(thread, cpu, timestamp, prio, newprio, bythread) 1096dcee3bd3SJeff Roberson Lend(bythread, cpu, timestamp, newprio, thread) 1097dcee3bd3SJeff Roberson 1098dcee3bd3SJeff Roberson def cpuload(self, cpu, timestamp, count): 10990482a607SJeff Roberson timestamp = self.checkstamp(cpu, timestamp) 11000482a607SJeff Roberson if (timestamp == 0): 1101b0e48518SJeff Roberson return 1102dcee3bd3SJeff Roberson cpu = int(cpu) 1103dcee3bd3SJeff Roberson try: 1104dcee3bd3SJeff Roberson load = self.load[cpu] 1105dcee3bd3SJeff Roberson except: 1106dcee3bd3SJeff Roberson load = Counter("cpu" + str(cpu) + " load") 1107dcee3bd3SJeff Roberson self.load[cpu] = load 1108dcee3bd3SJeff Roberson self.sources.insert(0, load) 1109dcee3bd3SJeff Roberson Count(load, cpu, timestamp, count) 1110dcee3bd3SJeff Roberson 1111dcee3bd3SJeff Roberson def loadglobal(self, cpu, timestamp, count): 11120482a607SJeff Roberson timestamp = self.checkstamp(cpu, timestamp) 11130482a607SJeff Roberson if (timestamp == 0): 1114b0e48518SJeff Roberson return 1115dcee3bd3SJeff Roberson cpu = 0 1116dcee3bd3SJeff Roberson try: 1117dcee3bd3SJeff Roberson load = self.load[cpu] 1118dcee3bd3SJeff Roberson except: 1119dcee3bd3SJeff Roberson load = Counter("CPU load") 1120dcee3bd3SJeff Roberson self.load[cpu] = load 1121dcee3bd3SJeff Roberson self.sources.insert(0, load) 1122dcee3bd3SJeff Roberson Count(load, cpu, timestamp, count) 1123dcee3bd3SJeff Roberson 112401e7fb47SScott Long def critsec(self, cpu, timestamp, td, pcomm, to): 11250482a607SJeff Roberson timestamp = self.checkstamp(cpu, timestamp) 11260482a607SJeff Roberson if (timestamp == 0): 112701e7fb47SScott Long return 112801e7fb47SScott Long cpu = int(cpu) 112901e7fb47SScott Long try: 113001e7fb47SScott Long crit = self.crit[cpu] 113101e7fb47SScott Long except: 113201e7fb47SScott Long crit = Counter("Critical Section") 113301e7fb47SScott Long self.crit[cpu] = crit 113401e7fb47SScott Long self.sources.insert(0, crit) 113501e7fb47SScott Long Count(crit, cpu, timestamp, to) 113601e7fb47SScott Long 1137dcee3bd3SJeff Roberson def findtd(self, td, pcomm): 1138dcee3bd3SJeff Roberson for thread in self.threads: 1139dcee3bd3SJeff Roberson if (thread.str == td and thread.name == pcomm): 1140dcee3bd3SJeff Roberson return thread 1141dcee3bd3SJeff Roberson thread = Thread(td, pcomm) 1142dcee3bd3SJeff Roberson self.threads.append(thread) 1143dcee3bd3SJeff Roberson self.sources.append(thread) 1144dcee3bd3SJeff Roberson return (thread) 1145dcee3bd3SJeff Roberson 1146dcee3bd3SJeff Roberson def fixup(self): 1147dcee3bd3SJeff Roberson for source in self.sources: 11480482a607SJeff Roberson Padevent(source, -1, self.timestamp_l) 11490482a607SJeff Roberson Padevent(source, -1, self.timestamp_f, last=1) 1150dcee3bd3SJeff Roberson source.fixup() 1151dcee3bd3SJeff Roberson 1152dcee3bd3SJeff Robersonclass SchedDisplay(Canvas): 1153dcee3bd3SJeff Roberson def __init__(self, master): 1154dcee3bd3SJeff Roberson self.ratio = 1 1155dcee3bd3SJeff Roberson self.ktrfile = None 1156dcee3bd3SJeff Roberson self.sources = None 1157dcee3bd3SJeff Roberson self.bdheight = 10 1158dcee3bd3SJeff Roberson self.events = {} 1159dcee3bd3SJeff Roberson 1160dcee3bd3SJeff Roberson Canvas.__init__(self, master, width=800, height=500, bg='grey', 1161dcee3bd3SJeff Roberson scrollregion=(0, 0, 800, 500)) 1162dcee3bd3SJeff Roberson 1163dcee3bd3SJeff Roberson def setfile(self, ktrfile): 1164dcee3bd3SJeff Roberson self.ktrfile = ktrfile 1165dcee3bd3SJeff Roberson self.sources = ktrfile.sources 1166dcee3bd3SJeff Roberson 1167dcee3bd3SJeff Roberson def draw(self): 1168dcee3bd3SJeff Roberson ypos = 0 1169dcee3bd3SJeff Roberson xsize = self.xsize() 1170dcee3bd3SJeff Roberson for source in self.sources: 1171dcee3bd3SJeff Roberson status.startup("Drawing " + source.name) 1172dcee3bd3SJeff Roberson self.create_line(0, ypos, xsize, ypos, 1173dcee3bd3SJeff Roberson width=1, fill="black", tags=("all",)) 1174dcee3bd3SJeff Roberson ypos += self.bdheight 1175dcee3bd3SJeff Roberson ypos += source.ysize() 1176dcee3bd3SJeff Roberson source.draw(self, ypos) 1177dcee3bd3SJeff Roberson ypos += self.bdheight 1178dcee3bd3SJeff Roberson try: 1179dcee3bd3SJeff Roberson self.tag_raise("point", "state") 1180dcee3bd3SJeff Roberson self.tag_lower("cpuinfo", "all") 1181dcee3bd3SJeff Roberson except: 1182dcee3bd3SJeff Roberson pass 1183dcee3bd3SJeff Roberson self.create_line(0, ypos, xsize, ypos, 1184dcee3bd3SJeff Roberson width=1, fill="black", tags=("all",)) 1185dcee3bd3SJeff Roberson self.tag_bind("event", "<Enter>", self.mouseenter) 1186dcee3bd3SJeff Roberson self.tag_bind("event", "<Leave>", self.mouseexit) 1187dcee3bd3SJeff Roberson self.tag_bind("event", "<Button-1>", self.mousepress) 1188dcee3bd3SJeff Roberson 1189dcee3bd3SJeff Roberson def mouseenter(self, event): 1190dcee3bd3SJeff Roberson item, = self.find_withtag(CURRENT) 1191dcee3bd3SJeff Roberson event = self.events[item] 1192dcee3bd3SJeff Roberson event.mouseenter(self, item) 1193dcee3bd3SJeff Roberson 1194dcee3bd3SJeff Roberson def mouseexit(self, event): 1195dcee3bd3SJeff Roberson item, = self.find_withtag(CURRENT) 1196dcee3bd3SJeff Roberson event = self.events[item] 1197dcee3bd3SJeff Roberson event.mouseexit(self, item) 1198dcee3bd3SJeff Roberson 1199dcee3bd3SJeff Roberson def mousepress(self, event): 1200dcee3bd3SJeff Roberson item, = self.find_withtag(CURRENT) 1201dcee3bd3SJeff Roberson event = self.events[item] 1202dcee3bd3SJeff Roberson event.mousepress(self, item) 1203dcee3bd3SJeff Roberson 1204dcee3bd3SJeff Roberson def drawnames(self, canvas): 1205dcee3bd3SJeff Roberson status.startup("Drawing names") 1206dcee3bd3SJeff Roberson ypos = 0 1207dcee3bd3SJeff Roberson canvas.configure(scrollregion=(0, 0, 1208dcee3bd3SJeff Roberson canvas["width"], self.ysize())) 1209dcee3bd3SJeff Roberson for source in self.sources: 1210dcee3bd3SJeff Roberson canvas.create_line(0, ypos, canvas["width"], ypos, 1211dcee3bd3SJeff Roberson width=1, fill="black", tags=("all",)) 1212dcee3bd3SJeff Roberson ypos += self.bdheight 1213dcee3bd3SJeff Roberson ypos += source.ysize() 1214dcee3bd3SJeff Roberson source.drawname(canvas, ypos) 1215dcee3bd3SJeff Roberson ypos += self.bdheight 1216dcee3bd3SJeff Roberson canvas.create_line(0, ypos, canvas["width"], ypos, 1217dcee3bd3SJeff Roberson width=1, fill="black", tags=("all",)) 1218dcee3bd3SJeff Roberson 1219dcee3bd3SJeff Roberson def xsize(self): 1220dcee3bd3SJeff Roberson return ((self.ktrfile.timespan() / self.ratio) + 20) 1221dcee3bd3SJeff Roberson 1222dcee3bd3SJeff Roberson def ysize(self): 1223dcee3bd3SJeff Roberson ysize = 0 1224dcee3bd3SJeff Roberson for source in self.sources: 1225dcee3bd3SJeff Roberson ysize += source.ysize() + (self.bdheight * 2) 1226dcee3bd3SJeff Roberson return (ysize) 1227dcee3bd3SJeff Roberson 1228dcee3bd3SJeff Roberson def scaleset(self, ratio): 1229dcee3bd3SJeff Roberson if (self.ktrfile == None): 1230dcee3bd3SJeff Roberson return 1231dcee3bd3SJeff Roberson oldratio = self.ratio 1232dcee3bd3SJeff Roberson xstart, ystart = self.xview() 1233dcee3bd3SJeff Roberson length = (float(self["width"]) / self.xsize()) 1234dcee3bd3SJeff Roberson middle = xstart + (length / 2) 1235dcee3bd3SJeff Roberson 1236dcee3bd3SJeff Roberson self.ratio = ratio 1237dcee3bd3SJeff Roberson self.configure(scrollregion=(0, 0, self.xsize(), self.ysize())) 1238dcee3bd3SJeff Roberson self.scale("all", 0, 0, float(oldratio) / ratio, 1) 1239dcee3bd3SJeff Roberson 1240dcee3bd3SJeff Roberson length = (float(self["width"]) / self.xsize()) 1241dcee3bd3SJeff Roberson xstart = middle - (length / 2) 1242dcee3bd3SJeff Roberson self.xview_moveto(xstart) 1243dcee3bd3SJeff Roberson 1244dcee3bd3SJeff Roberson def scaleget(self): 1245dcee3bd3SJeff Roberson return self.ratio 1246dcee3bd3SJeff Roberson 1247dcee3bd3SJeff Roberson def setcolor(self, tag, color): 1248dcee3bd3SJeff Roberson self.itemconfigure(tag, state="normal", fill=color) 1249dcee3bd3SJeff Roberson 1250dcee3bd3SJeff Roberson def hide(self, tag): 1251dcee3bd3SJeff Roberson self.itemconfigure(tag, state="hidden") 1252dcee3bd3SJeff Roberson 1253dcee3bd3SJeff Robersonclass GraphMenu(Frame): 1254dcee3bd3SJeff Roberson def __init__(self, master): 1255dcee3bd3SJeff Roberson Frame.__init__(self, master, bd=2, relief=RAISED) 1256dcee3bd3SJeff Roberson self.view = Menubutton(self, text="Configure") 1257dcee3bd3SJeff Roberson self.viewmenu = Menu(self.view, tearoff=0) 1258dcee3bd3SJeff Roberson self.viewmenu.add_command(label="Events", 1259dcee3bd3SJeff Roberson command=self.econf) 1260dcee3bd3SJeff Roberson self.view["menu"] = self.viewmenu 1261dcee3bd3SJeff Roberson self.view.pack(side=LEFT) 1262dcee3bd3SJeff Roberson 1263dcee3bd3SJeff Roberson def econf(self): 1264dcee3bd3SJeff Roberson EventConfigure() 1265dcee3bd3SJeff Roberson 1266dcee3bd3SJeff Roberson 1267dcee3bd3SJeff Robersonclass SchedGraph(Frame): 1268dcee3bd3SJeff Roberson def __init__(self, master): 1269dcee3bd3SJeff Roberson Frame.__init__(self, master) 1270dcee3bd3SJeff Roberson self.menu = None 1271dcee3bd3SJeff Roberson self.names = None 1272dcee3bd3SJeff Roberson self.display = None 1273dcee3bd3SJeff Roberson self.scale = None 1274dcee3bd3SJeff Roberson self.status = None 1275dcee3bd3SJeff Roberson self.pack(expand=1, fill="both") 1276dcee3bd3SJeff Roberson self.buildwidgets() 1277dcee3bd3SJeff Roberson self.layout() 1278dcee3bd3SJeff Roberson self.draw(sys.argv[1]) 1279dcee3bd3SJeff Roberson 1280dcee3bd3SJeff Roberson def buildwidgets(self): 1281dcee3bd3SJeff Roberson global status 1282dcee3bd3SJeff Roberson self.menu = GraphMenu(self) 1283dcee3bd3SJeff Roberson self.display = SchedDisplay(self) 1284dcee3bd3SJeff Roberson self.names = Canvas(self, 1285dcee3bd3SJeff Roberson width=100, height=self.display["height"], 1286dcee3bd3SJeff Roberson bg='grey', scrollregion=(0, 0, 50, 100)) 1287dcee3bd3SJeff Roberson self.scale = Scaler(self, self.display) 1288dcee3bd3SJeff Roberson status = self.status = Status(self) 1289dcee3bd3SJeff Roberson self.scrollY = Scrollbar(self, orient="vertical", 1290dcee3bd3SJeff Roberson command=self.display_yview) 1291dcee3bd3SJeff Roberson self.display.scrollX = Scrollbar(self, orient="horizontal", 1292dcee3bd3SJeff Roberson command=self.display.xview) 1293dcee3bd3SJeff Roberson self.display["xscrollcommand"] = self.display.scrollX.set 1294dcee3bd3SJeff Roberson self.display["yscrollcommand"] = self.scrollY.set 1295dcee3bd3SJeff Roberson self.names["yscrollcommand"] = self.scrollY.set 1296dcee3bd3SJeff Roberson 1297dcee3bd3SJeff Roberson def layout(self): 1298dcee3bd3SJeff Roberson self.columnconfigure(1, weight=1) 1299dcee3bd3SJeff Roberson self.rowconfigure(1, weight=1) 1300dcee3bd3SJeff Roberson self.menu.grid(row=0, column=0, columnspan=3, sticky=E+W) 1301dcee3bd3SJeff Roberson self.names.grid(row=1, column=0, sticky=N+S) 1302dcee3bd3SJeff Roberson self.display.grid(row=1, column=1, sticky=W+E+N+S) 1303dcee3bd3SJeff Roberson self.scrollY.grid(row=1, column=2, sticky=N+S) 1304dcee3bd3SJeff Roberson self.display.scrollX.grid(row=2, column=0, columnspan=2, 1305dcee3bd3SJeff Roberson sticky=E+W) 1306dcee3bd3SJeff Roberson self.scale.grid(row=3, column=0, columnspan=3, sticky=E+W) 1307dcee3bd3SJeff Roberson self.status.grid(row=4, column=0, columnspan=3, sticky=E+W) 1308dcee3bd3SJeff Roberson 1309dcee3bd3SJeff Roberson def draw(self, file): 1310dcee3bd3SJeff Roberson self.master.update() 1311dcee3bd3SJeff Roberson ktrfile = KTRFile(file) 1312dcee3bd3SJeff Roberson self.display.setfile(ktrfile) 1313dcee3bd3SJeff Roberson self.display.drawnames(self.names) 1314dcee3bd3SJeff Roberson self.display.draw() 1315dcee3bd3SJeff Roberson self.scale.set(250000) 1316dcee3bd3SJeff Roberson self.display.xview_moveto(0) 1317dcee3bd3SJeff Roberson 1318dcee3bd3SJeff Roberson def display_yview(self, *args): 1319dcee3bd3SJeff Roberson self.names.yview(*args) 1320dcee3bd3SJeff Roberson self.display.yview(*args) 1321dcee3bd3SJeff Roberson 1322dcee3bd3SJeff Roberson def setcolor(self, tag, color): 1323dcee3bd3SJeff Roberson self.display.setcolor(tag, color) 1324dcee3bd3SJeff Roberson 1325dcee3bd3SJeff Roberson def hide(self, tag): 1326dcee3bd3SJeff Roberson self.display.hide(tag) 1327dcee3bd3SJeff Roberson 1328dcee3bd3SJeff Robersonif (len(sys.argv) != 2): 1329dcee3bd3SJeff Roberson print "usage:", sys.argv[0], "<ktr file>" 1330dcee3bd3SJeff Roberson sys.exit(1) 1331dcee3bd3SJeff Roberson 1332dcee3bd3SJeff Robersonroot = Tk() 1333dcee3bd3SJeff Robersonroot.title("Scheduler Graph") 1334dcee3bd3SJeff Robersongraph = SchedGraph(root) 1335dcee3bd3SJeff Robersonroot.mainloop() 1336