summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2009-01-13 16:33:10 +0000
committerjhb <jhb@FreeBSD.org>2009-01-13 16:33:10 +0000
commitd89e3d19c08270f18a9c04329f2f9ec0868e688f (patch)
treeb9ed144024d49ed09a5b5126c1441100da4653ba /tools
parent89bdd3962a2a8f71b2d7e6e86409a2f9f87c040c (diff)
downloadFreeBSD-src-d89e3d19c08270f18a9c04329f2f9ec0868e688f.zip
FreeBSD-src-d89e3d19c08270f18a9c04329f2f9ec0868e688f.tar.gz
- 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.
Diffstat (limited to 'tools')
-rw-r--r--tools/sched/schedgraph.py59
1 files changed, 46 insertions, 13 deletions
diff --git a/tools/sched/schedgraph.py b/tools/sched/schedgraph.py
index c0eafe2..87a1c89 100644
--- a/tools/sched/schedgraph.py
+++ b/tools/sched/schedgraph.py
@@ -739,24 +739,36 @@ class Wokeup(PointEvent):
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 @@ class EventSource:
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 @@ class Thread(EventSource):
Thread.names[pcomm] = cnt + 1
def fixup(self):
+ EventSource.fixup(self)
cnt = Thread.names[self.name]
if (cnt == 0):
return
@@ -842,7 +855,7 @@ class Thread(EventSource):
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 @@ class Counter(EventSource):
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 @@ class KTRFile:
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 @@ class KTRFile:
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 @@ class KTRFile:
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 @@ class KTRFile:
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 @@ class KTRFile:
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 @@ class SchedDisplay(Canvas):
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 @@ class SchedDisplay(Canvas):
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 @@ class SchedDisplay(Canvas):
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
OpenPOWER on IntegriCloud