diff options
author | Mac Mollison <mollison@cs.unc.edu> | 2009-03-03 00:40:46 -0500 |
---|---|---|
committer | Mac Mollison <mollison@cs.unc.edu> | 2009-03-03 00:40:46 -0500 |
commit | 59aeaf7b558b930dfa625456d3e52c80a1f7f0bc (patch) | |
tree | 14bf00fd880d8aee2e4196d22b9e2a11f9c5b692 | |
parent | ca2c782e205b13b101f8589d761f607348b04c83 (diff) |
Created highly revamped EDF test
-rwxr-xr-x | sta.py | 203 |
1 files changed, 119 insertions, 84 deletions
@@ -131,6 +131,13 @@ class Trace: | |||
131 | else: | 131 | else: |
132 | return "({0},{1})".format(record['pid'],record['job']) | 132 | return "({0},{1})".format(record['pid'],record['job']) |
133 | 133 | ||
134 | def getTime(record): | ||
135 | """Return the time value from a record -- when, or release-time""" | ||
136 | if 'when' in record.keys(): | ||
137 | return record['when'] | ||
138 | else: | ||
139 | return record['release_time'] | ||
140 | |||
134 | 141 | ||
135 | ################## | 142 | ################## |
136 | # EDF class # | 143 | # EDF class # |
@@ -139,77 +146,133 @@ class Trace: | |||
139 | class EDF: | 146 | class EDF: |
140 | """Object representing an EDF test""" | 147 | """Object representing an EDF test""" |
141 | 148 | ||
142 | def __init__(self,trace_files, fudge_factor=0): | 149 | def __init__(self,trace_files, tick_size=1000000, tolerance=1000000): |
143 | """Create an EDF test""" | 150 | """Create an EDF test""" |
144 | self.trace_files = trace_files | 151 | self.trace_files = trace_files |
145 | self.fudge_factor = fudge_factor | ||
146 | self.errors = 0 | 152 | self.errors = 0 |
147 | self.corrects = 0 | 153 | self.corrects = 0 |
154 | self.runnables = [] | ||
155 | self.runnings = [] | ||
156 | self.time = None | ||
157 | self.tick_size = tick_size | ||
158 | self.tolerance = tolerance | ||
148 | 159 | ||
149 | def run_test(self): | 160 | def run_test(self): |
150 | 161 | ||
151 | #Make the trace, in order | 162 | #Make the trace, in order |
152 | trace = Trace(self.trace_files) | 163 | trace = Trace(self.trace_files) |
153 | trace.sort('when',alt='release_time') | 164 | trace.sort('when',alt='release_time') |
165 | trace.iter = trace.iter.__iter__() | ||
154 | 166 | ||
155 | #Runnables list holds released jobs that are not executing | 167 | #Find the start time from the SysRelease record |
156 | self.runnables = [] | 168 | while True: |
169 | record = trace.iter.__next__() | ||
170 | if record['type']==10: | ||
171 | self.time = record['when'] | ||
172 | print("Starting time: " + str(self.time)) | ||
173 | break | ||
157 | 174 | ||
158 | #Runnings list holds jobs that are executing | 175 | #Initialize last_record |
159 | self.runnings = [] | 176 | last_record = trace.iter.__next__() |
160 | 177 | ||
161 | #Iterate over records | 178 | #Initialize finished flag |
162 | for record in trace.iter: | 179 | finished = False |
163 | 180 | ||
164 | #Releases | 181 | while not finished: |
165 | if record['type'] == 3: | 182 | |
166 | if not self.check_duplicate_release(record): | 183 | #Increment the time |
167 | self.runnables.append(record) | 184 | self.time += self.tick_size |
168 | print("{0} became runnable" | 185 | print("-"*50) |
169 | .format(Trace.getStr(record))) | 186 | |
170 | 187 | #Update the model with records that have passed the time | |
171 | #Switch Tos | 188 | while Trace.getTime(last_record) < self.time: |
172 | elif record['type'] == 5: | 189 | last_record['overtime'] = 0 |
173 | release_record = EDF.pop_job(record, self.runnables) | 190 | self.update_model(last_record) |
174 | self.runnings.append(release_record) | 191 | try: |
175 | check_tuple = self.check_deadline(release_record) | 192 | last_record = trace.iter.__next__() |
176 | if check_tuple[0] == True: | 193 | except StopIteration: |
177 | print("{0} became running (VALID)" | 194 | finished = True |
178 | .format(Trace.getStr(record))) | 195 | break |
179 | self.corrects += 1 | 196 | |
180 | else: | 197 | #Check to see if our invariant is met |
181 | print('='*50) | 198 | #1) Find the max deadline in runnings |
182 | print("{0} became running (INVALID)" | 199 | #2) Check against the deadlines in runnables |
183 | .format(Trace.getStr(record))) | 200 | |
184 | print('Deadline of {0} greater than deadline of {1}' + | 201 | #1) Find the max deadline in runnings |
185 | 'in the following record:' | 202 | max_deadline = None |
186 | .format(release_record['deadline'], | 203 | for record in self.runnings: |
187 | check_tuple[1]['deadline'])) | 204 | if max_deadline==None: |
188 | print(check_tuple[1]) | 205 | max_deadline = record['deadline'] |
189 | self.print_runnables() | 206 | continue |
190 | self.print_runnings() | 207 | elif record['deadline'] > max_deadline: |
191 | print('='*50) | 208 | max_deadline = record['deadline'] |
192 | self.errors += 1 | 209 | |
193 | 210 | #2) Check against the deadlines in runnables | |
194 | #Switch Aways | 211 | if max_deadline: |
195 | elif record['type'] == 6: | 212 | for record in self.runnables: |
196 | release_record = EDF.pop_job(record, self.runnings) | 213 | if record['deadline'] < max_deadline: |
197 | if release_record: | 214 | record['overtime'] += self.tick_size |
198 | self.runnables.append(release_record) | 215 | if record['overtime'] > self.tolerance: |
199 | print('{0} went from running to runnable' | 216 | print("INVALID!") |
200 | .format(Trace.getStr(record))) | 217 | self.print_runnables() |
201 | 218 | self.print_runnings() | |
202 | #Completions | 219 | record['overtime'] = -99999999999999999 |
203 | elif record['type'] == 7: | 220 | self.errors += 1 |
204 | release_record = EDF.pop_job(record,self.runnings) | 221 | |
205 | if not release_record: | 222 | |
206 | release_record = EDF.pop_job(record,self.runnables) | ||
207 | print('{0} completed' | ||
208 | .format(Trace.getStr(record))) | ||
209 | |||
210 | print('Corrects: {0}'.format(self.corrects)) | ||
211 | print('Errors : {0}'.format(self.errors)) | 223 | print('Errors : {0}'.format(self.errors)) |
212 | 224 | ||
225 | |||
226 | def update_model(self, record): | ||
227 | |||
228 | #Releases | ||
229 | if record['type'] == 3: | ||
230 | if not self.check_duplicate_release(record): | ||
231 | self.runnables.append(record) | ||
232 | print("{0} became runnable" | ||
233 | .format(Trace.getStr(record))) | ||
234 | |||
235 | #Switch Tos | ||
236 | elif record['type'] == 5: | ||
237 | release_record = EDF.pop_job(record, self.runnables) | ||
238 | self.runnings.append(release_record) | ||
239 | print("{0} became running".format(Trace.getStr(record))) | ||
240 | #check_tuple = self.check_deadline(release_record) | ||
241 | #if check_tuple[0] == True: | ||
242 | # print("{0} became running (VALID)" | ||
243 | # .format(Trace.getStr(record))) | ||
244 | # self.corrects += 1 | ||
245 | #else: | ||
246 | # print('='*50) | ||
247 | # print("{0} became running (INVALID)" | ||
248 | # .format(Trace.getStr(record))) | ||
249 | # print('Deadline of {0} greater than deadline of {1}' + | ||
250 | # 'in the following record:' | ||
251 | # .format(release_record['deadline'], | ||
252 | # check_tuple[1]['deadline'])) | ||
253 | # print(check_tuple[1]) | ||
254 | # self.print_runnables() | ||
255 | # self.print_runnings() | ||
256 | # print('='*50) | ||
257 | # self.errors += 1 | ||
258 | |||
259 | #Switch Aways | ||
260 | elif record['type'] == 6: | ||
261 | release_record = EDF.pop_job(record, self.runnings) | ||
262 | if release_record: | ||
263 | self.runnables.append(release_record) | ||
264 | print('{0} went from running to runnable' | ||
265 | .format(Trace.getStr(record))) | ||
266 | |||
267 | #Completions | ||
268 | elif record['type'] == 7: | ||
269 | release_record = EDF.pop_job(record,self.runnings) | ||
270 | if not release_record: | ||
271 | release_record = EDF.pop_job(record,self.runnables) | ||
272 | print('{0} completed' | ||
273 | .format(Trace.getStr(record))) | ||
274 | |||
275 | |||
213 | def pop_job(record, record_list): | 276 | def pop_job(record, record_list): |
214 | """Pop a job from a list of jobs""" | 277 | """Pop a job from a list of jobs""" |
215 | job = record['job'] | 278 | job = record['job'] |
@@ -221,34 +284,6 @@ class EDF: | |||
221 | return record_copy | 284 | return record_copy |
222 | return None | 285 | return None |
223 | 286 | ||
224 | def check_deadline(self, record): | ||
225 | """Check to see if a release record has an equal or earlier deadline | ||
226 | than all those that are runnable""" | ||
227 | |||
228 | #Set up the variables we will need | ||
229 | minDeadline = None | ||
230 | lowest_deadline_record = None | ||
231 | diff = None | ||
232 | |||
233 | #Find the minimum deadline in runnables and the associated record | ||
234 | for record2 in self.runnables: | ||
235 | if minDeadline == None or record2['deadline'] < minDeadline: | ||
236 | minDeadline = record2['deadline'] | ||
237 | lowest_deadline_record = record2 | ||
238 | |||
239 | #Compute the difference btw. the one we sheduled and the minimum | ||
240 | # in runnables | ||
241 | if minDeadline == None: | ||
242 | diff = 0 | ||
243 | else: | ||
244 | diff = record['deadline'] - minDeadline | ||
245 | |||
246 | #Determine if the difference is acceptable | ||
247 | if diff <= self.fudge_factor: | ||
248 | return (True,lowest_deadline_record) | ||
249 | else: | ||
250 | return (False,lowest_deadline_record) | ||
251 | |||
252 | def check_duplicate_release(self, record): | 287 | def check_duplicate_release(self, record): |
253 | """Make sure we don't get duplicate releases""" | 288 | """Make sure we don't get duplicate releases""" |
254 | job = record['job'] | 289 | job = record['job'] |