Deleted Added
full compact
schedgraph.py (166203) schedgraph.py (166209)
1#!/usr/local/bin/python
2
3# Copyright (c) 2002-2003, Jeffrey Roberson <jeff@freebsd.org>
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:

--- 10 unchanged lines hidden (view full) ---

19# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26#
1#!/usr/local/bin/python
2
3# Copyright (c) 2002-2003, Jeffrey Roberson <jeff@freebsd.org>
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:

--- 10 unchanged lines hidden (view full) ---

19# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26#
27# $FreeBSD: head/tools/sched/schedgraph.py 166203 2007-01-23 22:19:27Z jeff $
27# $FreeBSD: head/tools/sched/schedgraph.py 166209 2007-01-24 21:19:56Z jeff $
28
29import sys
30import re
31from Tkinter import *
32
33# To use:
34# - Install the ports/x11-toolkits/py-tkinter package.
35# - Add KTR_SCHED to KTR_COMPILE and KTR_MASK in your KERNCONF

--- 23 unchanged lines hidden (view full) ---

59 return (str(ticks) + "ms")
60 ticks /= 1000
61 return (str(ticks) + "s")
62
63class Scaler(Frame):
64 def __init__(self, master, target):
65 Frame.__init__(self, master)
66 self.scale = Scale(self, command=self.scaleset,
28
29import sys
30import re
31from Tkinter import *
32
33# To use:
34# - Install the ports/x11-toolkits/py-tkinter package.
35# - Add KTR_SCHED to KTR_COMPILE and KTR_MASK in your KERNCONF

--- 23 unchanged lines hidden (view full) ---

59 return (str(ticks) + "ms")
60 ticks /= 1000
61 return (str(ticks) + "s")
62
63class Scaler(Frame):
64 def __init__(self, master, target):
65 Frame.__init__(self, master)
66 self.scale = Scale(self, command=self.scaleset,
67 from_=1000, to_=1000000, orient=HORIZONTAL, resolution=1000)
67 from_=1000, to_=10000000, orient=HORIZONTAL,
68 resolution=1000)
68 self.label = Label(self, text="Ticks per pixel")
69 self.label.pack(side=LEFT)
70 self.scale.pack(fill="both", expand=1)
71 self.target = target
72 self.scale.set(target.scaleget())
73 self.initialized = 1
74
75 def scaleset(self, value):

--- 329 unchanged lines hidden (view full) ---

405 skipped = next
406 next.skipself = 1
407 next.real = 0
408 next = next.nextstate()
409 if (next == None):
410 next = skipped
411 self.skipnext -= 1
412 self.duration = next.timestamp - self.timestamp
69 self.label = Label(self, text="Ticks per pixel")
70 self.label.pack(side=LEFT)
71 self.scale.pack(fill="both", expand=1)
72 self.target = target
73 self.scale.set(target.scaleget())
74 self.initialized = 1
75
76 def scaleset(self, value):

--- 329 unchanged lines hidden (view full) ---

406 skipped = next
407 next.skipself = 1
408 next.real = 0
409 next = next.nextstate()
410 if (next == None):
411 next = skipped
412 self.skipnext -= 1
413 self.duration = next.timestamp - self.timestamp
414 if (self.duration < 0):
415 self.duration = 0
416 print "Unsynchronized timestamp"
417 print self.cpu, self.timestamp
418 print next.cpu, next.timestamp
413 delta = self.duration / canvas.ratio
414 l = canvas.create_rectangle(xpos, ypos,
415 xpos + delta, ypos - 10, fill=self.color, width=0,
416 tags=("all", "state", "event") + (self.name,))
417 canvas.events[l] = self
418 self.item = l
419 if (self.enabled == 0):
420 canvas.itemconfigure(l, state="hidden")

--- 387 unchanged lines hidden (view full) ---

808 return (80)
809
810 def yscale(self):
811 return (self.ysize() / Counter.max)
812
813
814class KTRFile:
815 def __init__(self, file):
419 delta = self.duration / canvas.ratio
420 l = canvas.create_rectangle(xpos, ypos,
421 xpos + delta, ypos - 10, fill=self.color, width=0,
422 tags=("all", "state", "event") + (self.name,))
423 canvas.events[l] = self
424 self.item = l
425 if (self.enabled == 0):
426 canvas.itemconfigure(l, state="hidden")

--- 387 unchanged lines hidden (view full) ---

814 return (80)
815
816 def yscale(self):
817 return (self.ysize() / Counter.max)
818
819
820class KTRFile:
821 def __init__(self, file):
816 self.timestamp_first = None
817 self.timestamp_last = None
822 self.timestamp_first = {}
823 self.timestamp_last = {}
824 self.timestamp_adjust = {}
825 self.timestamp_f = None
826 self.timestamp_l = None
818 self.lineno = -1
819 self.threads = []
820 self.sources = []
821 self.ticks = {}
822 self.load = {}
823 self.crit = {}
827 self.lineno = -1
828 self.threads = []
829 self.sources = []
830 self.ticks = {}
831 self.load = {}
832 self.crit = {}
833 self.stathz = 0
824
825 self.parse(file)
826 self.fixup()
827 global ticksps
834
835 self.parse(file)
836 self.fixup()
837 global ticksps
828 ticksps = self.ticksps()
829 print "Ticks per second", ticksps, "timespan", self.timespan()
838 print "first", self.timestamp_f, "last", self.timestamp_l
839 print "time span", self.timespan()
830 print "stathz", self.stathz
840 print "stathz", self.stathz
831 print "first", self.timestamp_first, "last", self.timestamp_last
841 ticksps = self.ticksps()
842 print "Ticks per second", ticksps
832
833 def parse(self, file):
834 try:
835 ifp = open(file)
836 except:
837 print "Can't open", file
838 sys.exit(1)
839

--- 50 unchanged lines hidden (view full) ---

890 [sched_prio_re, self.sched_prio],
891 [preempted_re, self.preempted],
892 [sched_rem_re, self.sched_rem],
893 [sched_exit_re, self.sched_exit],
894 [sched_clock_re, self.sched_clock],
895 [critsec_re, self.critsec],
896 [idled_re, self.idled]]
897
843
844 def parse(self, file):
845 try:
846 ifp = open(file)
847 except:
848 print "Can't open", file
849 sys.exit(1)
850

--- 50 unchanged lines hidden (view full) ---

901 [sched_prio_re, self.sched_prio],
902 [preempted_re, self.preempted],
903 [sched_rem_re, self.sched_rem],
904 [sched_exit_re, self.sched_exit],
905 [sched_clock_re, self.sched_clock],
906 [critsec_re, self.critsec],
907 [idled_re, self.idled]]
908
898 for line in ifp.readlines():
909 lines = ifp.readlines()
910 self.synchstamp(lines)
911 for line in lines:
899 self.lineno += 1
900 if ((self.lineno % 1024) == 0):
901 status.startup("Parsing line " +
902 str(self.lineno))
903 for p in parsers:
904 m = p[0].match(line)
905 if (m != None):
906 p[1](*m.groups())
907 break
908 # if (m == None):
909 # print line,
910
912 self.lineno += 1
913 if ((self.lineno % 1024) == 0):
914 status.startup("Parsing line " +
915 str(self.lineno))
916 for p in parsers:
917 m = p[0].match(line)
918 if (m != None):
919 p[1](*m.groups())
920 break
921 # if (m == None):
922 # print line,
923
911 def checkstamp(self, timestamp):
924 def synchstamp(self, lines):
925 status.startup("Rationalizing Timestamps")
926 tstamp_re = re.compile("\s+\d+\s+(\d+)\s+(\d+)\s+.*")
927 for line in lines:
928 m = tstamp_re.match(line)
929 if (m != None):
930 self.addstamp(*m.groups())
931 self.pickstamp()
932 self.monostamp(lines)
933
934
935 def monostamp(self, lines):
936 laststamp = None
937 tstamp_re = re.compile("\s+\d+\s+(\d+)\s+(\d+)\s+.*")
938 for line in lines:
939 m = tstamp_re.match(line)
940 if (m == None):
941 continue
942 (cpu, timestamp) = m.groups()
943 timestamp = int(timestamp)
944 cpu = int(cpu)
945 timestamp -= self.timestamp_adjust[cpu]
946 if (laststamp != None and timestamp > laststamp):
947 self.timestamp_adjust[cpu] += timestamp - laststamp
948 laststamp = timestamp
949
950 def addstamp(self, cpu, timestamp):
912 timestamp = int(timestamp)
951 timestamp = int(timestamp)
913 if (self.timestamp_first == None):
914 self.timestamp_first = timestamp
915 if (timestamp > self.timestamp_first):
952 cpu = int(cpu)
953 try:
954 if (timestamp > self.timestamp_first[cpu]):
955 return
956 except:
957 self.timestamp_first[cpu] = timestamp
958 self.timestamp_last[cpu] = timestamp
959
960 def pickstamp(self):
961 base = self.timestamp_last[0]
962 for i in range(0, len(self.timestamp_last)):
963 if (self.timestamp_last[i] < base):
964 base = self.timestamp_last[i]
965
966 print "Adjusting to base stamp", base
967 for i in range(0, len(self.timestamp_last)):
968 self.timestamp_adjust[i] = self.timestamp_last[i] - base;
969 print "CPU ", i, "adjust by ", self.timestamp_adjust[i]
970
971 self.timestamp_f = 0
972 for i in range(0, len(self.timestamp_first)):
973 first = self.timestamp_first[i] - self.timestamp_adjust[i]
974 if (first > self.timestamp_f):
975 self.timestamp_f = first
976
977 self.timestamp_l = 0
978 for i in range(0, len(self.timestamp_last)):
979 last = self.timestamp_last[i] - self.timestamp_adjust[i]
980 if (last > self.timestamp_l):
981 self.timestamp_l = last
982
983
984 def checkstamp(self, cpu, timestamp):
985 cpu = int(cpu)
986 timestamp = int(timestamp)
987 if (timestamp > self.timestamp_first[cpu]):
916 print "Bad timestamp on line ", self.lineno
917 return (0)
988 print "Bad timestamp on line ", self.lineno
989 return (0)
918 self.timestamp_last = timestamp
919 return (1)
990 timestamp -= self.timestamp_adjust[cpu]
991 return (timestamp)
920
921 def timespan(self):
992
993 def timespan(self):
922 return (self.timestamp_first - self.timestamp_last);
994 return (self.timestamp_f - self.timestamp_l);
923
924 def ticksps(self):
925 return (self.timespan() / self.ticks[0]) * int(self.stathz)
926
927 def switchout(self, cpu, timestamp, td, pcomm, prio, inhibit, wmesg, lock):
928 TDI_SUSPENDED = 0x0001
929 TDI_SLEEPING = 0x0002
930 TDI_SWAPPED = 0x0004
931 TDI_LOCK = 0x0008
932 TDI_IWAIT = 0x0010
933
995
996 def ticksps(self):
997 return (self.timespan() / self.ticks[0]) * int(self.stathz)
998
999 def switchout(self, cpu, timestamp, td, pcomm, prio, inhibit, wmesg, lock):
1000 TDI_SUSPENDED = 0x0001
1001 TDI_SLEEPING = 0x0002
1002 TDI_SWAPPED = 0x0004
1003 TDI_LOCK = 0x0008
1004 TDI_IWAIT = 0x0010
1005
934 if (self.checkstamp(timestamp) == 0):
1006 timestamp = self.checkstamp(cpu, timestamp)
1007 if (timestamp == 0):
935 return
936 inhibit = int(inhibit)
937 thread = self.findtd(td, pcomm)
938 if (inhibit & TDI_SWAPPED):
939 Swapped(thread, cpu, timestamp, prio)
940 elif (inhibit & TDI_SLEEPING):
941 Sleep(thread, cpu, timestamp, prio, wmesg)
942 elif (inhibit & TDI_LOCK):

--- 4 unchanged lines hidden (view full) ---

947 Suspended(thread, cpu, timestamp, prio)
948 elif (inhibit == 0):
949 Yielding(thread, cpu, timestamp, prio)
950 else:
951 print "Unknown event", inhibit
952 sys.exit(1)
953
954 def idled(self, cpu, timestamp, td, pcomm, prio):
1008 return
1009 inhibit = int(inhibit)
1010 thread = self.findtd(td, pcomm)
1011 if (inhibit & TDI_SWAPPED):
1012 Swapped(thread, cpu, timestamp, prio)
1013 elif (inhibit & TDI_SLEEPING):
1014 Sleep(thread, cpu, timestamp, prio, wmesg)
1015 elif (inhibit & TDI_LOCK):

--- 4 unchanged lines hidden (view full) ---

1020 Suspended(thread, cpu, timestamp, prio)
1021 elif (inhibit == 0):
1022 Yielding(thread, cpu, timestamp, prio)
1023 else:
1024 print "Unknown event", inhibit
1025 sys.exit(1)
1026
1027 def idled(self, cpu, timestamp, td, pcomm, prio):
955 if (self.checkstamp(timestamp) == 0):
1028 timestamp = self.checkstamp(cpu, timestamp)
1029 if (timestamp == 0):
956 return
957 thread = self.findtd(td, pcomm)
958 Idle(thread, cpu, timestamp, prio)
959
960 def preempted(self, cpu, timestamp, td, pcomm, prio, bytd, bypcomm):
1030 return
1031 thread = self.findtd(td, pcomm)
1032 Idle(thread, cpu, timestamp, prio)
1033
1034 def preempted(self, cpu, timestamp, td, pcomm, prio, bytd, bypcomm):
961 if (self.checkstamp(timestamp) == 0):
1035 timestamp = self.checkstamp(cpu, timestamp)
1036 if (timestamp == 0):
962 return
963 thread = self.findtd(td, pcomm)
964 Preempted(thread, cpu, timestamp, prio,
965 self.findtd(bytd, bypcomm))
966
967 def switchin(self, cpu, timestamp, td, pcomm, prio):
1037 return
1038 thread = self.findtd(td, pcomm)
1039 Preempted(thread, cpu, timestamp, prio,
1040 self.findtd(bytd, bypcomm))
1041
1042 def switchin(self, cpu, timestamp, td, pcomm, prio):
968 if (self.checkstamp(timestamp) == 0):
1043 timestamp = self.checkstamp(cpu, timestamp)
1044 if (timestamp == 0):
969 return
970 thread = self.findtd(td, pcomm)
971 Running(thread, cpu, timestamp, prio)
972
973 def sched_add(self, cpu, timestamp, td, pcomm, prio, bytd, bypcomm):
1045 return
1046 thread = self.findtd(td, pcomm)
1047 Running(thread, cpu, timestamp, prio)
1048
1049 def sched_add(self, cpu, timestamp, td, pcomm, prio, bytd, bypcomm):
974 if (self.checkstamp(timestamp) == 0):
1050 timestamp = self.checkstamp(cpu, timestamp)
1051 if (timestamp == 0):
975 return
976 thread = self.findtd(td, pcomm)
977 bythread = self.findtd(bytd, bypcomm)
978 Runq(thread, cpu, timestamp, prio, bythread)
979 Wokeup(bythread, cpu, timestamp, thread)
980
981 def sched_rem(self, cpu, timestamp, td, pcomm, prio, bytd, bypcomm):
1052 return
1053 thread = self.findtd(td, pcomm)
1054 bythread = self.findtd(bytd, bypcomm)
1055 Runq(thread, cpu, timestamp, prio, bythread)
1056 Wokeup(bythread, cpu, timestamp, thread)
1057
1058 def sched_rem(self, cpu, timestamp, td, pcomm, prio, bytd, bypcomm):
982 if (self.checkstamp(timestamp) == 0):
1059 timestamp = self.checkstamp(cpu, timestamp)
1060 if (timestamp == 0):
983 return
984 thread = self.findtd(td, pcomm)
985 KsegrpRunq(thread, cpu, timestamp, prio,
986 self.findtd(bytd, bypcomm))
987
988 def sched_exit(self, cpu, timestamp, td, pcomm, prio):
1061 return
1062 thread = self.findtd(td, pcomm)
1063 KsegrpRunq(thread, cpu, timestamp, prio,
1064 self.findtd(bytd, bypcomm))
1065
1066 def sched_exit(self, cpu, timestamp, td, pcomm, prio):
989 if (self.checkstamp(timestamp) == 0):
1067 timestamp = self.checkstamp(cpu, timestamp)
1068 if (timestamp == 0):
990 return
991 thread = self.findtd(td, pcomm)
992 Sched_exit(thread, cpu, timestamp, prio)
993
994 def sched_clock(self, cpu, timestamp, td, pcomm, prio, stathz):
1069 return
1070 thread = self.findtd(td, pcomm)
1071 Sched_exit(thread, cpu, timestamp, prio)
1072
1073 def sched_clock(self, cpu, timestamp, td, pcomm, prio, stathz):
995 if (self.checkstamp(timestamp) == 0):
1074 timestamp = self.checkstamp(cpu, timestamp)
1075 if (timestamp == 0):
996 return
997 self.stathz = stathz
998 cpu = int(cpu)
999 try:
1000 ticks = self.ticks[cpu]
1001 except:
1002 self.ticks[cpu] = 0
1003 self.ticks[cpu] += 1
1004 thread = self.findtd(td, pcomm)
1005 Tick(thread, cpu, timestamp, prio, stathz)
1006
1007 def sched_prio(self, cpu, timestamp, td, pcomm, prio, newprio, bytd, bypcomm):
1008 if (prio == newprio):
1009 return
1076 return
1077 self.stathz = stathz
1078 cpu = int(cpu)
1079 try:
1080 ticks = self.ticks[cpu]
1081 except:
1082 self.ticks[cpu] = 0
1083 self.ticks[cpu] += 1
1084 thread = self.findtd(td, pcomm)
1085 Tick(thread, cpu, timestamp, prio, stathz)
1086
1087 def sched_prio(self, cpu, timestamp, td, pcomm, prio, newprio, bytd, bypcomm):
1088 if (prio == newprio):
1089 return
1010 if (self.checkstamp(timestamp) == 0):
1090 timestamp = self.checkstamp(cpu, timestamp)
1091 if (timestamp == 0):
1011 return
1012 thread = self.findtd(td, pcomm)
1013 bythread = self.findtd(bytd, bypcomm)
1014 Prio(thread, cpu, timestamp, prio, newprio, bythread)
1015 Lend(bythread, cpu, timestamp, newprio, thread)
1016
1017 def cpuload(self, cpu, timestamp, count):
1092 return
1093 thread = self.findtd(td, pcomm)
1094 bythread = self.findtd(bytd, bypcomm)
1095 Prio(thread, cpu, timestamp, prio, newprio, bythread)
1096 Lend(bythread, cpu, timestamp, newprio, thread)
1097
1098 def cpuload(self, cpu, timestamp, count):
1018 if (self.checkstamp(timestamp) == 0):
1099 timestamp = self.checkstamp(cpu, timestamp)
1100 if (timestamp == 0):
1019 return
1020 cpu = int(cpu)
1021 try:
1022 load = self.load[cpu]
1023 except:
1024 load = Counter("cpu" + str(cpu) + " load")
1025 self.load[cpu] = load
1026 self.sources.insert(0, load)
1027 Count(load, cpu, timestamp, count)
1028
1029 def loadglobal(self, cpu, timestamp, count):
1101 return
1102 cpu = int(cpu)
1103 try:
1104 load = self.load[cpu]
1105 except:
1106 load = Counter("cpu" + str(cpu) + " load")
1107 self.load[cpu] = load
1108 self.sources.insert(0, load)
1109 Count(load, cpu, timestamp, count)
1110
1111 def loadglobal(self, cpu, timestamp, count):
1030 if (self.checkstamp(timestamp) == 0):
1112 timestamp = self.checkstamp(cpu, timestamp)
1113 if (timestamp == 0):
1031 return
1032 cpu = 0
1033 try:
1034 load = self.load[cpu]
1035 except:
1036 load = Counter("CPU load")
1037 self.load[cpu] = load
1038 self.sources.insert(0, load)
1039 Count(load, cpu, timestamp, count)
1040
1041 def critsec(self, cpu, timestamp, td, pcomm, to):
1114 return
1115 cpu = 0
1116 try:
1117 load = self.load[cpu]
1118 except:
1119 load = Counter("CPU load")
1120 self.load[cpu] = load
1121 self.sources.insert(0, load)
1122 Count(load, cpu, timestamp, count)
1123
1124 def critsec(self, cpu, timestamp, td, pcomm, to):
1042 if (self.checkstamp(timestamp) == 0):
1125 timestamp = self.checkstamp(cpu, timestamp)
1126 if (timestamp == 0):
1043 return
1044 cpu = int(cpu)
1045 try:
1046 crit = self.crit[cpu]
1047 except:
1048 crit = Counter("Critical Section")
1049 self.crit[cpu] = crit
1050 self.sources.insert(0, crit)

--- 5 unchanged lines hidden (view full) ---

1056 return thread
1057 thread = Thread(td, pcomm)
1058 self.threads.append(thread)
1059 self.sources.append(thread)
1060 return (thread)
1061
1062 def fixup(self):
1063 for source in self.sources:
1127 return
1128 cpu = int(cpu)
1129 try:
1130 crit = self.crit[cpu]
1131 except:
1132 crit = Counter("Critical Section")
1133 self.crit[cpu] = crit
1134 self.sources.insert(0, crit)

--- 5 unchanged lines hidden (view full) ---

1140 return thread
1141 thread = Thread(td, pcomm)
1142 self.threads.append(thread)
1143 self.sources.append(thread)
1144 return (thread)
1145
1146 def fixup(self):
1147 for source in self.sources:
1064 Padevent(source, -1, self.timestamp_last)
1065 Padevent(source, -1, self.timestamp_first, last=1)
1148 Padevent(source, -1, self.timestamp_l)
1149 Padevent(source, -1, self.timestamp_f, last=1)
1066 source.fixup()
1067
1068class SchedDisplay(Canvas):
1069 def __init__(self, master):
1070 self.ratio = 1
1071 self.ktrfile = None
1072 self.sources = None
1073 self.bdheight = 10

--- 178 unchanged lines hidden ---
1150 source.fixup()
1151
1152class SchedDisplay(Canvas):
1153 def __init__(self, master):
1154 self.ratio = 1
1155 self.ktrfile = None
1156 self.sources = None
1157 self.bdheight = 10

--- 178 unchanged lines hidden ---