- Add some rudimentary support for sorting the list of event sources
(threads, CPU load counters, etc.). Each source is tagged with a group and an order similar to the SYSINIT SI_SUB_* and SI_ORDER_*. After the file is parsed, all the sources are then sorted. Currently, the only affects of this are that the CPU loads are now sorted by CPU ID (so CPU 0 is always first). However, this makes it easier to add new types of event sources in the future and have them all clustered together instead of intertwined with threads. - Python lists perform insertions at the tail much faster than insertions at the head. For a trace that had a lot of events for a single event source, the constant insertions of new events to the head of the per-source event list caused a noticable slow down. To compensate, append new events to the end of the list during parsing and then reverse the list prior to drawing. - Somewhere in the tkinter internals the coordinates of a canvas are stored in a signed 32-bit integer. As a result, if an the box for an event spans 2^31, it would actually end up having a negative X offset at one end. The result was a single box that covered the entire event source. Kris worked around this for some traces by bumping up the initial ticks/pixel ratio from 1 to 10. However, a divisor of 10 can still be too small for large tracefiles (e.g. with 4 million entries). Instead of hardcoding the initial scaling ratio, calculate it from the time span of the trace file. - Add support for using the mouse wheel to scroll the graph window up and down.
This commit is contained in:
parent
89bdd3962a
commit
d89e3d19c0
@ -739,24 +739,36 @@ def __init__(self, thread, cpu, timestamp, ranthread):
|
||||
|
||||
configtypes.append(Wokeup)
|
||||
|
||||
(DEFAULT, LOAD, COUNT, THREAD) = range(4)
|
||||
|
||||
class EventSource:
|
||||
def __init__(self, name):
|
||||
def __init__(self, name, group=DEFAULT, order=0):
|
||||
self.name = name
|
||||
self.events = []
|
||||
self.cpu = 0
|
||||
self.cpux = 0
|
||||
self.group = group
|
||||
self.order = order
|
||||
|
||||
def __cmp__(self, other):
|
||||
if (self.group == other.group):
|
||||
return cmp(self.order, other.order)
|
||||
return cmp(self.group, other.group)
|
||||
|
||||
# It is much faster to append items to a list then to insert them
|
||||
# at the beginning. As a result, we add events in reverse order
|
||||
# and then swap the list during fixup.
|
||||
def fixup(self):
|
||||
pass
|
||||
self.events.reverse()
|
||||
|
||||
def event(self, event):
|
||||
self.events.insert(0, event)
|
||||
self.events.append(event)
|
||||
|
||||
def remove(self, event):
|
||||
self.events.remove(event)
|
||||
|
||||
def lastevent(self, event):
|
||||
self.events.append(event)
|
||||
self.events.insert(0, event)
|
||||
|
||||
def draw(self, canvas, ypos):
|
||||
xpos = 10
|
||||
@ -819,7 +831,7 @@ def findevent(self, timestamp):
|
||||
class Thread(EventSource):
|
||||
names = {}
|
||||
def __init__(self, td, pcomm):
|
||||
EventSource.__init__(self, pcomm)
|
||||
EventSource.__init__(self, pcomm, THREAD)
|
||||
self.str = td
|
||||
try:
|
||||
cnt = Thread.names[pcomm]
|
||||
@ -829,6 +841,7 @@ def __init__(self, td, pcomm):
|
||||
Thread.names[pcomm] = cnt + 1
|
||||
|
||||
def fixup(self):
|
||||
EventSource.fixup(self)
|
||||
cnt = Thread.names[self.name]
|
||||
if (cnt == 0):
|
||||
return
|
||||
@ -842,7 +855,7 @@ def ysize(self):
|
||||
class Counter(EventSource):
|
||||
max = 0
|
||||
def __init__(self, name):
|
||||
EventSource.__init__(self, name)
|
||||
EventSource.__init__(self, name, COUNT)
|
||||
|
||||
def event(self, event):
|
||||
EventSource.event(self, event)
|
||||
@ -863,6 +876,11 @@ def ysize(self):
|
||||
def yscale(self):
|
||||
return (self.ysize() / Counter.max)
|
||||
|
||||
class CPULoad(Counter):
|
||||
def __init__(self, cpu):
|
||||
Counter.__init__(self, "cpu" + str(cpu) + " load")
|
||||
self.group = LOAD
|
||||
self.order = cpu
|
||||
|
||||
class KTRFile:
|
||||
def __init__(self, file):
|
||||
@ -1100,9 +1118,9 @@ def cpuload(self, cpu, timestamp, count):
|
||||
try:
|
||||
load = self.load[cpu]
|
||||
except:
|
||||
load = Counter("cpu" + str(cpu) + " load")
|
||||
load = CPULoad(cpu)
|
||||
self.load[cpu] = load
|
||||
self.sources.insert(0, load)
|
||||
self.sources.append(load)
|
||||
Count(load, cpu, timestamp, count)
|
||||
|
||||
def cpuload2(self, cpu, timestamp, ncpu, count):
|
||||
@ -1113,9 +1131,9 @@ def cpuload2(self, cpu, timestamp, ncpu, count):
|
||||
try:
|
||||
load = self.load[cpu]
|
||||
except:
|
||||
load = Counter("cpu" + str(cpu) + " load")
|
||||
load = CPULoad(cpu)
|
||||
self.load[cpu] = load
|
||||
self.sources.insert(0, load)
|
||||
self.sources.append(load)
|
||||
Count(load, cpu, timestamp, count)
|
||||
|
||||
def loadglobal(self, cpu, timestamp, count):
|
||||
@ -1128,7 +1146,7 @@ def loadglobal(self, cpu, timestamp, count):
|
||||
except:
|
||||
load = Counter("CPU load")
|
||||
self.load[cpu] = load
|
||||
self.sources.insert(0, load)
|
||||
self.sources.append(load)
|
||||
Count(load, cpu, timestamp, count)
|
||||
|
||||
def critsec(self, cpu, timestamp, td, pcomm, to):
|
||||
@ -1141,7 +1159,7 @@ def critsec(self, cpu, timestamp, td, pcomm, to):
|
||||
except:
|
||||
crit = Counter("Critical Section")
|
||||
self.crit[cpu] = crit
|
||||
self.sources.insert(0, crit)
|
||||
self.sources.append(crit)
|
||||
Count(crit, cpu, timestamp, to)
|
||||
|
||||
def findtd(self, td, pcomm):
|
||||
@ -1158,12 +1176,14 @@ def fixup(self):
|
||||
Padevent(source, -1, self.timestamp_l)
|
||||
Padevent(source, -1, self.timestamp_f, last=1)
|
||||
source.fixup()
|
||||
self.sources.sort()
|
||||
|
||||
class SchedDisplay(Canvas):
|
||||
def __init__(self, master):
|
||||
self.ratio = 10
|
||||
self.ratio = 1
|
||||
self.ktrfile = None
|
||||
self.sources = None
|
||||
self.parent = master
|
||||
self.bdheight = 10
|
||||
self.events = {}
|
||||
|
||||
@ -1174,6 +1194,11 @@ def setfile(self, ktrfile):
|
||||
self.ktrfile = ktrfile
|
||||
self.sources = ktrfile.sources
|
||||
|
||||
# Compute a ratio to ensure that the file's timespan fits into
|
||||
# 2^31. Although python may handle larger values for X
|
||||
# values, the Tk internals do not.
|
||||
self.ratio = (ktrfile.timespan() - 1) / 2**31 + 1
|
||||
|
||||
def draw(self):
|
||||
ypos = 0
|
||||
xsize = self.xsize()
|
||||
@ -1195,6 +1220,8 @@ def draw(self):
|
||||
self.tag_bind("event", "<Enter>", self.mouseenter)
|
||||
self.tag_bind("event", "<Leave>", self.mouseexit)
|
||||
self.tag_bind("event", "<Button-1>", self.mousepress)
|
||||
self.bind("<Button-4>", self.wheelup)
|
||||
self.bind("<Button-5>", self.wheeldown)
|
||||
|
||||
def mouseenter(self, event):
|
||||
item, = self.find_withtag(CURRENT)
|
||||
@ -1211,6 +1238,12 @@ def mousepress(self, event):
|
||||
event = self.events[item]
|
||||
event.mousepress(self, item)
|
||||
|
||||
def wheeldown(self, event):
|
||||
self.parent.display_yview("scroll", 1, "units")
|
||||
|
||||
def wheelup(self, event):
|
||||
self.parent.display_yview("scroll", -1, "units")
|
||||
|
||||
def drawnames(self, canvas):
|
||||
status.startup("Drawing names")
|
||||
ypos = 0
|
||||
|
Loading…
Reference in New Issue
Block a user