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