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 --- |