summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMac Mollison <mollison@cs.unc.edu>2010-02-08 00:24:40 -0500
committerMac Mollison <mollison@cs.unc.edu>2010-02-08 00:27:11 -0500
commit1016a3e271faebb899766f5d18468dd88b4d84b7 (patch)
tree387ab36e8ee886d8d6741d5820c178c974f46252
parentcd6e43f37856f7fe6b60e0e2ae45f864a4bd6d64 (diff)
This is the beginning of a very major refactoring of the tool.
Current features: - Create a record stream from trace files - Print the record stream to standard out - TODO file - README file - run.py file to set up and execute the testing pipeline
-rw-r--r--README1
-rw-r--r--TODO3
-rwxr-xr-xrun.py34
-rw-r--r--test_driver/make_devices18
-rw-r--r--test_driver/sample_test_case.py9
-rwxr-xr-xtest_driver/test.py147
-rw-r--r--text_print.py23
-rw-r--r--trace.py138
-rw-r--r--trace_analyzer/README21
-rwxr-xr-xtrace_analyzer/run.py99
-rwxr-xr-xtrace_analyzer/sta.py365
11 files changed, 199 insertions, 659 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..b2da190
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
See the LITMUS Wiki page for an explanation of this tool.
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..41dc878
--- /dev/null
+++ b/TODO
@@ -0,0 +1,3 @@
1- Currently, trace.py reads all records from the first trace file, then all
2 records from the second, etc. Instead it should progress through all
3 files simultaneously, producing records in order based on timestamp.
diff --git a/run.py b/run.py
new file mode 100755
index 0000000..42def18
--- /dev/null
+++ b/run.py
@@ -0,0 +1,34 @@
1#!/usr/bin/env python3
2
3###############################################################################
4# Description
5###############################################################################
6
7# Use this file to set up and execute a testing pipeline
8# Sample pipeline provided
9
10
11###############################################################################
12# Imports
13###############################################################################
14
15import trace
16import text_print
17
18###############################################################################
19# Trace files
20###############################################################################
21
22g4 = [
23'/home/mollison/old/sta/traces/st-g4-0.bin',
24'/home/mollison/old/sta/traces/st-g4-1.bin',
25'/home/mollison/old/sta/traces/st-g4-2.bin',
26'/home/mollison/old/sta/traces/st-g4-3.bin'
27]
28
29###############################################################################
30# Pipeline
31###############################################################################
32
33stream = trace.get_trace_record_stream(g4)
34text_print.print_stream(stream)
diff --git a/test_driver/make_devices b/test_driver/make_devices
deleted file mode 100644
index 4d4554b..0000000
--- a/test_driver/make_devices
+++ /dev/null
@@ -1,18 +0,0 @@
1#!/bin/bash
2
3#Creates device drivers for traces (litmus_log, ft_trace and sched_trace)
4#Taken from http://www.cs.unc.edu/~anderson/litmus-rt/doc/tracing.html
5
6LITMUS_LOG_MAJOR=`grep litmus_log /proc/devices | awk '{print $1}'`
7FT_TRACE_MAJOR=`grep ft_trace /proc/devices | awk '{print $1}'`
8SCHED_TRACE_MAJOR=`grep sched_trace /proc/devices | awk '{print $1}'`
9
10mknod litmus_log c $LITMUS_LOG_MAJOR 0
11mknod ft_trace c $FT_TRACE_MAJOR 0
12
13NUM_PROCS=$((`grep 'processor' /proc/cpuinfo | wc -l` - 1))
14
15for P in `seq 0 $NUM_PROCS`
16do
17 mknod "sched_trace$P" c $SCHED_TRACE_MAJOR $P
18done
diff --git a/test_driver/sample_test_case.py b/test_driver/sample_test_case.py
deleted file mode 100644
index 6cb886e..0000000
--- a/test_driver/sample_test_case.py
+++ /dev/null
@@ -1,9 +0,0 @@
1#Sample test case for the test driver.
2
3#Each element of the test_case list is a real-time executable task, with parameters.
4#For each task, we have a list: [location of executable,wcet,period,duration].
5
6test_case = [
7 ['/root/liblitmus/rtspin',10,100,1000]
8 ['/root/liblitmus/rtspin',10,100,1000]
9]
diff --git a/test_driver/test.py b/test_driver/test.py
deleted file mode 100755
index 87038a0..0000000
--- a/test_driver/test.py
+++ /dev/null
@@ -1,147 +0,0 @@
1#!/usr/bin/env python3
2
3##########
4#Settings#
5##########
6
7#liblitmus directory (You need to put the compiled liblitmus here)
8liblitmus_dir = '/root/liblitmus/'
9
10#ft_tools directory (You need to but the compiled ft_tools here)
11ft_tools_dir = '/root/ft_tools/'
12
13#device files directory (This script will set up the device files here)
14device_dir = '/root/device_files/'
15
16#recorded trace directory (This script will place recorded traces here)
17trace_dir = '/root/traces/'
18
19#desired scheduling policy, to be set by this script
20#options listed in /proc/litmus/plugins
21policy = 'GSN-EDF'
22
23#desired test case
24test_case_file = 'sample_test_case'
25
26#name of traces
27trace_name = 'driver'
28
29#Additional instructions:
30# -Make sure you've chmod +x'd the make_devices file and kept it in the same
31# dir as test.py
32# -Make sure you've set up a test case
33
34###########
35# Imports #
36###########
37
38import subprocess
39import os
40import time
41exec('from ' + test_case_file + ' import test_case')
42
43#################
44# Run the tests #
45#################
46
47def main():
48
49 #Determine directory of test.py
50 test_dir = os.getcwd()
51
52 #Set scheduling policy
53 print("Setting scheduling policy... ",end='')
54 ret = subprocess.getstatusoutput(
55 'echo ' + policy + ' > ' + '/proc/litmus/active_plugin')
56 if ret[0] == 0:
57 print("[SUCCESS]")
58 else:
59 print("[FAILURE], error was:")
60 print(str(ret[0]) + ': ' + ret[1])
61 exit()
62
63 #Check for execute permission on the make_devices script
64 print("Checking for permission to run make_devices... ",end='')
65 if not os.access('./make_devices',os.X_OK):
66 print("\nAttempting to chmod +x make_devices... ",end='')
67 ret = subprocess.getstatusoutput('chmod +x ./make_devices')
68 if ret[0]!=1:
69 print("[FAILURE], error was:")
70 print(str(ret[0]) + ': ' + ret[1])
71 exit()
72 print("[SUCCESS]")
73
74 #Setup the device files for the traces
75 print("Creating device files. OK if they already exist.")
76 subprocess.Popen(test_dir + '/make_devices',cwd=device_dir)
77 time.sleep(1)
78
79 #Set up environment variables needed for st_trace script
80 print("Setting up environment variables... ",end='')
81 os.putenv('FTCAT', ft_tools_dir + 'ftcat')
82 os.putenv('FTDEV',device_dir + 'sched_trace')
83 print("[SUCCESS]")
84
85 #See if we can access and run st_trace
86 print("Checking for permission to run st_trace... ",end='')
87 if not os.access(ft_tools_dir + 'st_trace',os.X_OK):
88 print("\nAttempting to chmod +x st_trace... ",end='')
89 ret = subprocess.getstatusoutput('chmod +x ' +
90 ft_tools_dir + 'st_trace')
91 if ret[0]!=1:
92 print("[FAILURE], error was:")
93 print(str(ret[0]) + ': ' + ret[1])
94 exit()
95 print("[SUCCESS]")
96
97 #Start sched_trace
98 print("Starting st_trace trace recorder... ",end='')
99 st_trace = subprocess.Popen([ft_tools_dir + 'st_trace',trace_name],
100 cwd=trace_dir)
101 print("[SUCCESS]")
102
103 #We will get an error there, if the test.py program terminates.
104 #time.sleep(7)
105
106 #Start tasks in test_case
107 print("Launching tasks... ",end='')
108 for task in test_case:
109 subprocess.Popen([task[0],'-w',str(task[1]),str(task[2]),str(task[3])])
110 print("[SUCCESS]")
111
112 #Wait for tasks to suspend themselves
113 print("Waiting for tasks to suspend... ",end='')
114 time.sleep(3)
115 print("[SUCCESS]")
116
117 #Release the tasks
118 print("Releasing the tasks... ",end='')
119 ret = subprocess.getstatusoutput(liblitmus_dir + 'release_ts')
120 if ret[0] != 0:
121 print("[FAILURE], error was:")
122 print(str(ret[0]) + ': ' + ret[1])
123 exit()
124 print("[SUCCESS]")
125
126 #Wait for the tasks to complete. I still need to implement this.
127
128
129 #Current steps...
130 #Run st_trace (must tell it location of sched_trace device files exactly)
131 #Let it get set up, then suspend
132 #let it run in background with bg <job>
133 #Run rtspin 10 100 1000 twice; suspend, run in background
134 #Bring rtspins to foreground and stop them.
135 #Bring st_trace to foreground, hit enter to complete it.
136
137 #Need to try to do the above with rt_launch and then release_ts
138
139
140
141##############
142# start main #
143##############
144
145if __name__=='__main__':
146 main()
147
diff --git a/text_print.py b/text_print.py
new file mode 100644
index 0000000..7254b51
--- /dev/null
+++ b/text_print.py
@@ -0,0 +1,23 @@
1###############################################################################
2# Description
3###############################################################################
4
5# Prints records to standard out
6
7###############################################################################
8# Public functions
9###############################################################################
10
11def print_stream(stream):
12 for record in stream:
13 if record.record_type == "event":
14 _print_event(record)
15 print("")
16
17###############################################################################
18# Private functions
19###############################################################################
20
21def _print_event(record):
22 print("Job: {}.{}".format(record.pid,record.job))
23 print("Type: {}".format(record.type_name))
diff --git a/trace.py b/trace.py
new file mode 100644
index 0000000..1ceccae
--- /dev/null
+++ b/trace.py
@@ -0,0 +1,138 @@
1###############################################################################
2# Description
3###############################################################################
4
5# get_trace_record_stream(files) returns an iterator which produces records
6# in order from the files given. (the param is a list of files.)
7
8
9###############################################################################
10# Imports
11###############################################################################
12
13import struct
14
15
16###############################################################################
17# Public functions
18###############################################################################
19
20# Generator function returning an iterable over records in a trace file.
21def get_trace_record_stream(files):
22 for file in files:
23 with open(file,'rb') as f:
24 while True:
25 data = f.read(24)
26 try:
27 type_num = struct.unpack_from('b',data)[0]
28 except struct.error:
29 break #We read to the end of the file
30 type = _get_type(type_num)
31 try:
32 values = struct.unpack_from(StHeader.format +
33 type.format,data)
34 record_dict = dict(zip(type.keys,values))
35 except struct.error:
36 f.close()
37 print("Invalid record detected, stopping.")
38 exit()
39 Record = _dict2obj(record_dict)
40 Record.type_name = _get_type_name(type_num)
41 Record.record_type = "event"
42 yield Record
43
44###############################################################################
45# Private functions
46###############################################################################
47
48# Convert a dict into an object
49def _dict2obj(d):
50 class Obj: pass
51 o = Obj()
52 for key in d.keys():
53 o.__dict__[key] = d[key]
54 return o
55
56###############################################################################
57# Trace record data types and accessor functions
58###############################################################################
59
60class StHeader:
61 format = '<bbhi'
62 formatStr = struct.Struct(format)
63 keys = ['type','cpu','pid','job']
64 message = 'The header.'
65
66class StNameData:
67 format = '16s'
68 formatStr = struct.Struct(StHeader.format + format)
69 keys = StHeader.keys + ['name']
70 message = 'The name of the executable of this process.'
71
72class StParamData:
73 format = 'IIIc'
74 formatStr = struct.Struct(StHeader.format + format)
75 keys = StHeader.keys + ['wcet','period','phase','partition']
76 message = 'Regular parameters.'
77
78class StReleaseData:
79 format = 'QQ'
80 formatStr = struct.Struct(StHeader.format + format)
81 keys = StHeader.keys + ['release_time','deadline']
82 message = 'A job was/is going to be released.'
83
84#Not yet used by Sched Trace
85class StAssignedData:
86 format = 'Qc'
87 formatStr = struct.Struct(StHeader.format + format)
88 keys = StHeader.keys + ['when','target']
89 message = 'A job was assigned to a CPU.'
90
91class StSwitchToData:
92 format = 'QI'
93 formatStr = struct.Struct(StHeader.format + format)
94 keys = StHeader.keys + ['when','exec_time']
95 message = 'A process was switched to on a given CPU.'
96
97class StSwitchAwayData:
98 format = 'QI'
99 formatStr = struct.Struct(StHeader.format + format)
100 keys = StHeader.keys + ['when','exec_time']
101 message = 'A process was switched away on a given CPU.'
102
103class StCompletionData:
104 format = 'Q3x?c'
105 formatStr = struct.Struct(StHeader.format + format)
106 keys = StHeader.keys + ['when','forced?','flags']
107 message = 'A job completed.'
108
109class StBlockData:
110 format = 'Q'
111 formatStr = struct.Struct(StHeader.format + format)
112 keys = StHeader.keys + ['when']
113 message = 'A task blocks.'
114
115class StResumeData:
116 format = 'Q'
117 formatStr = struct.Struct(StHeader.format + format)
118 keys = StHeader.keys + ['when']
119 message = 'A task resumes.'
120
121class StSysReleaseData:
122 format = 'QQ'
123 formatStr = struct.Struct(StHeader.format + format)
124 keys = StHeader.keys + ['when','release']
125 message = 'All tasks have checked in, task system released by user'
126
127# Return the binary data type, given the type_num
128def _get_type(type_num):
129 types = [None,StNameData,StParamData,StReleaseData,StAssignedData,
130 StSwitchToData,StSwitchAwayData,StCompletionData,StBlockData,
131 StResumeData,StSysReleaseData]
132 return types[type_num]
133
134# Return the type name, given the type_num
135def _get_type_name(type_num):
136 type_names = [None,"name","params","release","assign","switch_to","switch_away",
137 "completion","block","resume","sys_release"]
138 return type_names[type_num]
diff --git a/trace_analyzer/README b/trace_analyzer/README
deleted file mode 100644
index 16450df..0000000
--- a/trace_analyzer/README
+++ /dev/null
@@ -1,21 +0,0 @@
1Sched Trace Analyzer
2
3############################
4General Information
5############################
6
7Examples of how to use this can be found in run.py.
8
9The general idea it that you use run.py to put in the commands you want to do,
10and then do something like ./run.py > out to write out the records.
11
12
13#############################
14Development Notes
15#############################
16
17Need to account for situation where there is a tie in deadline which spans the
18topN category.
19
20Might think about adding in hooks, so you do the trace, then add in the hook to
21see the state at the place you're curious about.
diff --git a/trace_analyzer/run.py b/trace_analyzer/run.py
deleted file mode 100755
index 80ae257..0000000
--- a/trace_analyzer/run.py
+++ /dev/null
@@ -1,99 +0,0 @@
1#!/usr/bin/env python3
2import sta
3
4######################################
5# Sched Trace Analyzer LaunchPad #
6######################################
7
8def main():
9 #myEDF()
10 macTrace()
11 #myTrace()
12 #switchToTrace()
13 #releaseTrace()
14 #oneCPU()
15
16def oneCPU():
17 trace = sta.Trace(g6_list)
18 trace.filter('cpu==0')
19 trace.sort('when')
20 trace.print_count(True)
21 trace.print_records()
22
23def myEDF():
24 test = sta.EDF(g6_list,hooks=[37917786934190])
25 #test = sta.EDF(g6_list)
26 test.run_test()
27
28def myTrace():
29 trace = sta.Trace(g6_list)
30 trace.sort('when',alt='release_time')
31 trace.filter('type==2')
32 trace.print_count(True)
33 trace.print_records()
34
35def macTrace():
36 trace = sta.Trace(mac2_list)
37 trace.sort('when',alt='release_time')
38 trace.print_count(True)
39 trace.print_records()
40
41def switchToTrace():
42 events_trace = sta.Trace(g6_list)
43 events_trace.filter('type==5')
44 events_trace.sort('when')
45 events_trace.print_count(True)
46 events_trace.print_records()
47
48def releaseTrace():
49 events_trace = sta.Trace(g6_list)
50 events_trace.filter('type==3')
51 events_trace.sort('release_time')
52 events_trace.print_count(True)
53 events_trace.print_records()
54
55def sampleTrace():
56 """A sample trace"""
57 trace.filter('pid==4129')
58 trace.filter('when>1323753839')
59 trace.filter('when<1331677799')
60 trace.sort('when')
61 trace.print_count(True)
62 trace.print_records()
63
64
65######################################
66# Put lists of your trace files here #
67######################################
68
69path = '/home/mollison/sta/traces/'
70
71g6_list = [
72path + 'st-g6-0.bin',
73path + 'st-g6-1.bin',
74path + 'st-g6-2.bin',
75path + 'st-g6-3.bin']
76
77g5_list = [
78path + 'st-g5-0.bin',
79path + 'st-g5-1.bin',
80path + 'st-g5-2.bin',
81path + 'st-g5-3.bin']
82
83x19_list = [
84path + 'st-x19-0.bin',
85path + 'st-x19-1.bin',
86path + 'st-x19-2.bin',
87path + 'st-x19-3.bin']
88
89mac2_list = [
90path + 'st-mac2-0.bin']
91
92
93
94##############
95# start main #
96##############
97
98if __name__=='__main__':
99 main()
diff --git a/trace_analyzer/sta.py b/trace_analyzer/sta.py
deleted file mode 100755
index 4269037..0000000
--- a/trace_analyzer/sta.py
+++ /dev/null
@@ -1,365 +0,0 @@
1#!/usr/bin/env python3
2
3
4##################
5# Imports #
6##################
7
8import sys
9import struct
10import copy
11
12##################
13# Trace class #
14##################
15class Trace:
16 """Object representing a trace (i.e. set of records)"""
17
18 def __init__(self,files):
19 """Initialize the Trace object with an iterator"""
20 self.iter = self.make_iter(files)
21
22 def make_iter(self, files):
23 """Make the iterator for this Trace object"""
24 for file in files:
25 f = open(file,'rb')
26 while True:
27 data = f.read(24)
28 try:
29 typenum = struct.unpack_from('b',data)[0]
30 except struct.error:
31 #We read to the end of the file
32 f.close()
33 break
34 type = get_type(typenum)
35 try:
36 values = struct.unpack_from(StHeader.format +
37 type.format,data)
38 record = dict(zip(type.keys,values))
39 except struct.error:
40 f.close()
41 print("Invalid record detected, stopping.")
42 exit()
43 yield record
44
45 def filter(self, criteria):
46 """Apply a filter to the trace"""
47
48 #Determine if they want to filter by >, <, !=, or ==
49 comp = None
50 seps = ['>','<','==','!=']
51 for sep in seps:
52 if criteria.find(sep) > 0:
53 comp = sep
54 if not comp:
55 print("Your filter is invalid: " + criteria)
56 exit()
57
58 #Apply the filter
59 field, comp, value = criteria.partition(comp)
60 test = "rec['" + field + "']" + comp + "int(" + value + ")"
61 def func(rec):
62 try:
63 if eval(test):
64 return True
65 else:
66 return False
67 except KeyError:
68 return False
69 self.iter = filter(func, self.iter)
70
71 def sort(self, key, key2=None, alt=None):
72 """Return the records in sorted order.
73 key = the key to sort by.
74 key2 = secondary value to sort by, optional
75 alt = alternate key if 'key' does not exist.
76 """
77 def sortfunc(record):
78 score = 0
79 if key in record:
80 score += record[key]
81 if key2 in record:
82 score = float(str(score) + '.' + str(record[key2]))
83 if score==0 and alt in record:
84 score = record[alt]
85 return score
86 self.iter = sorted(self.iter, key=sortfunc)
87
88 def slice(self, start, end):
89 """Slice the trace iterator"""
90 self.iter = list(self.iter)[start:end]
91
92 def remove_side_effects(self, type1, type2):
93 """Remove records of type2 immediately following records of type1"""
94 self.iter = list(self.iter)
95 i = 0
96 while i < len(self.iter) - 1:
97 if self.iter[i]['type'] == type1 and self.iter[i+1]['type']==type2:
98 del self.iter[i+1]
99 i += 1
100
101 def print_records(self):
102 """Prints all records in the trace"""
103 for record in self.iter:
104 print(50*'=')
105 print(get_type(record['type']).message)
106 for k,v in record.items():
107 print(k +":", v)
108
109 def print_count(self,verbose=False):
110 """Prints the number of records in the trace."""
111 self.iter = list(self.iter)
112 print("Total Count: " + str(len(self.iter)))
113 if verbose:
114 counts = {1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0,9:0,10:0}
115 for record in list(self.iter):
116 type = record['type']
117 counts[type] += 1
118 for key in counts.keys():
119 print(get_type(key).__name__ +
120 ': ' + str(counts[key]))
121 print("")
122
123 def getStr(record,omitTime=False):
124 """Return the representation of a record in the format
125 time: (task, job)"""
126 time = None
127 if 'when' in record:
128 time = record['when']
129 else:
130 time = record['release_time']
131 if not omitTime:
132 return "{0}: ({1},{2})".format(time,record['pid'],record['job'])
133 else:
134 return "({0},{1})".format(record['pid'],record['job'])
135
136 def getTime(record):
137 """Return the time value from a record -- when, or release-time"""
138 if 'when' in record.keys():
139 return record['when']
140 else:
141 return record['release_time']
142
143
144##################
145# EDF class #
146##################
147
148class EDF:
149
150 def __init__(self,trace_files, tolerance=150000, N=4, hooks=[]):
151 self.trace_files = trace_files
152 self.tolerance = tolerance
153 self.jobs = []
154 self.N = N #number of cores
155 self.now = 0
156 self.hooks = hooks
157
158 def run_test(self):
159 trace = Trace(self.trace_files)
160 trace.sort('when',alt='release_time')
161
162 for record in trace.iter:
163
164 #Update now
165 if 'when' in record:
166 self.now = record['when']
167 elif 'release_time' in record:
168 self.now = record['release_time']
169
170 if self.now in self.hooks:
171 self.print_jobs()
172
173 #Process record
174 if record['type'] == 3:
175 if self.is_duplicate_release(record): continue
176 job = EDF.Job()
177 job.deadline = record['deadline']
178 job.release_time = record['release_time']
179 job.job = record['job']
180 job.pid = record['pid']
181 self.jobs.append(job)
182 print('{0}: {1} was released'.format(self.now,job.get_name()))
183 elif record['type'] == 5:
184 job = self.get_job(record['pid'],record['job'])
185 if job:
186 job.running = True
187 else:
188 continue
189 print('{0}: {1} was switched to'
190 .format(self.now,job.get_name()))
191 elif record['type'] == 6:
192 job = self.get_job(record['pid'],record['job'])
193 if job:
194 job.running = False
195 else:
196 continue
197 print('{0}: {1} was switched away'
198 .format(self.now,job.get_name()))
199 elif record['type'] == 7:
200 job = self.get_job(record['pid'],record['job'])
201 if job:
202 self.jobs.remove(job)
203 else:
204 continue
205 print('{0}: {1} completed'
206 .format(self.now,job.get_name()))
207 else:
208 continue
209
210 #Sort jobs by deadline
211 self.jobs = sorted(self.jobs,key=lambda job: job.deadline)
212
213 if self.now in self.hooks:
214 self.print_jobs()
215
216 #Check for inversions (and end-of inversions) in the top N jobs
217 for job in self.jobs[0:self.N]:
218 job.topN = True
219 if job.running == False:
220 if job.inversion_start_time==0:
221 job.inversion_start_time=self.now
222 if self.check_tie(job):
223 job.inversion_start_time=0
224 elif job.running == True:
225 if job.inversion_start_time > 0:
226 self.check_error(job)
227 job.inversion_start_time = 0
228
229 #Check for end-of-inversions in the other jobs
230 for job in self.jobs[self.N:]:
231 if job.topN == True:
232 job.topN = False
233 self.check_error(job)
234 job.inversion_start_time = 0
235
236 def check_error(self, job):
237 if job.inversion_start_time == 0: return
238 if self.now - job.inversion_start_time > self.tolerance:
239 print(' ' * 16 + job.get_name() +
240 ' was inverted for {0} time units,'
241 .format(self.now - job.inversion_start_time))
242 print(' '*26 + 'since {0}'.format(job.inversion_start_time))
243
244 def get_job(self, pid, job):
245 for x in self.jobs:
246 if x.pid == pid and x.job == job:
247 return x
248
249 def is_duplicate_release(self, record):
250 """Make sure we don't get duplicate releases"""
251 job = record['job']
252 pid = record['pid']
253 for x in self.jobs:
254 if x.job == job and x.pid == pid:
255 return True
256 return False
257
258 def check_tie(self, job):
259 """Returns True if there is another job with the same deadline that is
260 running"""
261 for x in self.jobs:
262 if x.deadline == job.deadline and x.running == True:
263 return True
264 return False
265
266 class Job:
267 def __init__(self):
268 self.release_time = 0
269 self.deadline = 0
270 self.job = 0
271 self.pid = 0
272 self.running = False
273 self.topN = False
274 self.inversion_start_time = 0
275
276 def get_name(self):
277 return '({0},{1})'.format(self.pid,self.job)
278
279 def print_jobs(self):
280 print('---Jobs---')
281 for job in self.jobs:
282 print(job.get_name() + '{0} {1}'.format(job.running, job.deadline))
283 print('----------')
284
285####################################
286# Types for binary data conversion #
287####################################
288
289import struct
290
291class StHeader:
292 format = '<bbhi'
293 formatStr = struct.Struct(format)
294 keys = ['type','cpu','pid','job']
295 message = 'The header.'
296
297class StNameData:
298 format = '16s'
299 formatStr = struct.Struct(StHeader.format + format)
300 keys = StHeader.keys + ['name']
301 message = 'The name of the executable of this process.'
302
303class StParamData:
304 format = 'IIIc'
305 #format = 'ccccc'
306 formatStr = struct.Struct(StHeader.format + format)
307 keys = StHeader.keys + ['wcet','period','phase','partition']
308 message = 'Regular parameters.'
309
310class StReleaseData:
311 format = 'QQ'
312 formatStr = struct.Struct(StHeader.format + format)
313 keys = StHeader.keys + ['release_time','deadline']
314 message = 'A job was/is going to be released.'
315
316#Not yet used by Sched Trace
317class StAssignedData:
318 format = 'Qc'
319 formatStr = struct.Struct(StHeader.format + format)
320 keys = StHeader.keys + ['when','target']
321 message = 'A job was assigned to a CPU.'
322
323class StSwitchToData:
324 format = 'QI'
325 formatStr = struct.Struct(StHeader.format + format)
326 keys = StHeader.keys + ['when','exec_time']
327 message = 'A process was switched to on a given CPU.'
328
329class StSwitchAwayData:
330 format = 'QI'
331 formatStr = struct.Struct(StHeader.format + format)
332 keys = StHeader.keys + ['when','exec_time']
333 message = 'A process was switched away on a given CPU.'
334
335class StCompletionData:
336 format = 'Q3x?c'
337 formatStr = struct.Struct(StHeader.format + format)
338 keys = StHeader.keys + ['when','forced?','flags']
339 message = 'A job completed.'
340
341class StBlockData:
342 format = 'Q'
343 formatStr = struct.Struct(StHeader.format + format)
344 keys = StHeader.keys + ['when']
345 message = 'A task blocks.'
346
347class StResumeData:
348 format = 'Q'
349 formatStr = struct.Struct(StHeader.format + format)
350 keys = StHeader.keys + ['when']
351 message = 'A task resumes.'
352
353class StSysReleaseData:
354 format = 'QQ'
355 formatStr = struct.Struct(StHeader.format + format)
356 keys = StHeader.keys + ['when','release']
357 message = 'All tasks have checked in, task system released by user'
358
359def get_type(type_num):
360 """Return the binary data type, given the type_num"""
361 types = [None,StNameData,StParamData,StReleaseData,StAssignedData,
362 StSwitchToData,StSwitchAwayData,StCompletionData,StBlockData,
363 StResumeData,StSysReleaseData]
364 return types[type_num]
365