- Permit timestamps to be as far as 2048 ticks apart before we complain

about invalid timestamps.  Nehalem CPUs seem to be synchronized but only
   within a fraction of a microsecond.
 - Make the Counter code more flexible to poor timestamps.  In general we
   now complain a lot but render as much as we can.
 - Change the scaler behavior so it works better with very long and very
   short traces.  We now set the maximum scale such that it properly
   displays the entire file by default and doesn't permit zooming out
   beyond the file.  This improves other awkward navigation behavior.
   The interval is now set very small which can't be achieved by simply
   dragging the mouse.  Clicking to the left of or right of the scaler bar
   will produce increments of a single, very small, interval now.

Sponsored by:   Nokia
This commit is contained in:
Jeff Roberson 2009-01-20 12:33:04 +00:00
parent 5c0c22e92e
commit 16ef0f3b21
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=187471

View File

@ -162,15 +162,12 @@ def ticks2sec(ticks):
class Scaler(Frame):
def __init__(self, master, target):
Frame.__init__(self, master)
self.scale = Scale(self, command=self.scaleset,
from_=1000, to_=10000000, orient=HORIZONTAL,
resolution=1000)
self.scale = None
self.target = target
self.label = Label(self, text="Ticks per pixel")
self.label.pack(side=LEFT)
self.scale.pack(fill="both", expand=1)
self.target = target
self.scale.set(target.scaleget())
self.initialized = 1
self.resolution = 100
self.setmax(10000)
def scaleset(self, value):
self.target.scaleset(int(value))
@ -178,6 +175,20 @@ def scaleset(self, value):
def set(self, value):
self.scale.set(value)
def setmax(self, value):
#
# We can't reconfigure the to_ value so we delete the old
# window and make a new one when we resize.
#
if (self.scale != None):
self.scale.pack_forget()
self.scale.destroy()
self.scale = Scale(self, command=self.scaleset,
from_=100, to_=value, orient=HORIZONTAL,
resolution=self.resolution)
self.scale.pack(fill="both", expand=1)
self.scale.set(self.target.scaleget())
class Status(Frame):
def __init__(self, master):
Frame.__init__(self, master)
@ -726,6 +737,11 @@ def draw(self, canvas, xpos, ypos):
return (xpos)
color = colormap.lookup("count")
self.duration = duration = next.timestamp - self.timestamp
if (duration < 0):
duration = 0
print "Unsynchronized timestamp"
print self.cpu, self.timestamp
print next.cpu, next.timestamp
self.attrs.insert(0, ("count", self.count))
self.attrs.insert(1, ("duration", ticks2sec(duration)))
delta = duration / canvas.ratio
@ -882,6 +898,7 @@ def __init__(self, file):
self.crit = {}
self.stathz = 0
self.eventcnt = 0
self.taghash = {}
self.parse(file)
self.fixup()
@ -956,7 +973,8 @@ def parse(self, file):
if (dat == None):
dat = dat1
if (self.checkstamp(timestamp) == 0):
print "Bad timestamp at", lineno, ":", line,
print "Bad timestamp at", lineno, ":",
print cpu, timestamp
continue
#
# Build the table of optional attributes
@ -1021,20 +1039,22 @@ def checkstamp(self, timestamp):
timestamp = int(timestamp)
if (self.timestamp_f == None):
self.timestamp_f = timestamp;
if (self.timestamp_l != None and timestamp > self.timestamp_l):
if (self.timestamp_l != None and
timestamp -2048> self.timestamp_l):
return (0)
self.timestamp_l = timestamp;
return (1)
def makeid(self, group, id, type):
for source in sources:
if (source.name == id and source.group == group):
return source
tag = group + id
if (self.taghash.has_key(tag)):
return self.taghash[tag]
if (type == "counter"):
source = Counter(group, id)
else:
source = EventSource(group, id)
sources.append(source)
self.taghash[tag] = source
return (source)
def findid(self, id):
@ -1053,7 +1073,7 @@ def ticksps(self):
return int(clockfreq * oneghz)
# Check for a discovered clock
if (self.stathz != None):
if (self.stathz != 0):
return (self.timespan() / self.ticks[0]) * int(self.stathz)
# Pretend we have a 1ns clock
print "WARNING: No clock discovered and no frequency ",
@ -1313,8 +1333,16 @@ def draw(self):
self.names.draw()
self.display.draw()
self.status.startup("")
self.scale.set(250000)
#
# Configure scale related values
#
scalemax = ktrfile.timespan() / int(self.display["width"])
width = int(root.geometry().split('x')[0])
self.constwidth = width - int(self.display["width"])
self.scale.setmax(scalemax)
self.scale.set(scalemax)
self.display.xview_moveto(0)
self.bind("<Configure>", self.resize)
def mousepress(self, event):
self.clicksource = self.sourceat(event.y)
@ -1452,8 +1480,7 @@ def sourceshowlist(self, srclist):
source.hidden = 0
size += sz
idx += 1
self.names.updatescroll()
self.display.updatescroll()
self.updatescroll()
self.status.set("")
#
@ -1496,8 +1523,7 @@ def sourcehidelist(self, srclist):
if (nstart >= stop):
break;
self.sourceshift(source, -size)
self.names.updatescroll()
self.display.updatescroll()
self.updatescroll()
self.status.set("")
def sourcehide(self, source):
@ -1530,8 +1556,7 @@ def sourceshiftall(self, start, off):
if (nstart < start):
continue;
self.sourceshift(source, off)
self.names.updatescroll()
self.display.updatescroll()
self.updatescroll()
self.status.set("")
def sourceat(self, ypos):
@ -1551,6 +1576,15 @@ def display_yview(self, *args):
self.names.yview(*args)
self.display.yview(*args)
def resize(self, *args):
width = int(root.geometry().split('x')[0])
scalemax = ktrfile.timespan() / (width - self.constwidth)
self.scale.setmax(scalemax)
def updatescroll(self):
self.names.updatescroll()
self.display.updatescroll()
def setcolor(self, tag, color):
self.display.setcolor(tag, color)