svn commit: r187155 - head/tools/sched

John Baldwin jhb at FreeBSD.org
Tue Jan 13 08:33:11 PST 2009


Author: jhb
Date: Tue Jan 13 16:33:10 2009
New Revision: 187155
URL: http://svn.freebsd.org/changeset/base/187155

Log:
  - 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.

Modified:
  head/tools/sched/schedgraph.py

Modified: head/tools/sched/schedgraph.py
==============================================================================
--- head/tools/sched/schedgraph.py	Tue Jan 13 16:27:04 2009	(r187154)
+++ head/tools/sched/schedgraph.py	Tue Jan 13 16:33:10 2009	(r187155)
@@ -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


More information about the svn-src-head mailing list