summaryrefslogtreecommitdiffstats
path: root/unit_trace
diff options
context:
space:
mode:
authorchsun <chsun@mid-campus-02989.wireless.unc.edu>2011-04-17 16:57:04 -0400
committerchsun <chsun@mid-campus-02989.wireless.unc.edu>2011-04-17 16:57:04 -0400
commitce153b063854e9cca8ebc042f0cc08c411c8d5a1 (patch)
tree0f2aad096b43749760fff266ac07ea545166c8f8 /unit_trace
parentc364f1d807eeb246ca67184246fd2c8d7933b8b6 (diff)
Supprot C-EDF Task Priorty Inversion, Tasklet Priorty Inversion, and Work Priorty Inversion.
Support New Feather Trace Event: ST_TASKLET_RELEASE, ST_TASKLET_BEGIN, ST_TASKLET_END, ST_WORK_RELEASE, ST_WORK_BEGIN, ST_WORK_END, and, ST_EFF_PRIO_CHANGE
Diffstat (limited to 'unit_trace')
-rw-r--r--unit_trace/gedf_inversion_stat_printer.py14
-rw-r--r--unit_trace/gedf_test.py345
-rw-r--r--unit_trace/stdout_printer.py24
-rw-r--r--unit_trace/trace_reader.py53
4 files changed, 406 insertions, 30 deletions
diff --git a/unit_trace/gedf_inversion_stat_printer.py b/unit_trace/gedf_inversion_stat_printer.py
index c35632a..5ea7916 100644
--- a/unit_trace/gedf_inversion_stat_printer.py
+++ b/unit_trace/gedf_inversion_stat_printer.py
@@ -8,7 +8,7 @@
8# Public Functions 8# Public Functions
9############################################################################### 9###############################################################################
10 10
11def gedf_inversion_stat_printer(stream,num): 11def gedf_inversion_stat_printer(stream,num,pi_type):
12 12
13 # State 13 # State
14 min_inversion = -1 14 min_inversion = -1
@@ -19,7 +19,7 @@ def gedf_inversion_stat_printer(stream,num):
19 19
20 # Iterate over records, updating state 20 # Iterate over records, updating state
21 for record in stream: 21 for record in stream:
22 if record.type_name == 'inversion_end': 22 if record.type_name == pi_type+'_inversion_end':
23 length = record.job.inversion_end - record.job.inversion_start 23 length = record.job.inversion_end - record.job.inversion_start
24 if length > 0: 24 if length > 0:
25 num_inversions += 1 25 num_inversions += 1
@@ -53,13 +53,13 @@ def gedf_inversion_stat_printer(stream,num):
53 # Print out our information 53 # Print out our information
54 # NOTE: Here, we assume nanoseconds as the time unit. 54 # NOTE: Here, we assume nanoseconds as the time unit.
55 # May have to be changed in the future. 55 # May have to be changed in the future.
56 print "Num inversions: %d" % (num_inversions) 56 print "Num "+pi_type+ "_inversions: %d" % (num_inversions)
57 print "Min inversion: %f ms" % (float(min_inversion) / 1000000) 57 print "Min "+pi_type+ "_inversion: %f ms" % (float(min_inversion) / 1000000)
58 print "Max inversion: %f ms" % (float(max_inversion) / 1000000) 58 print "Max "+pi_type+ "_inversion: %f ms" % (float(max_inversion) / 1000000)
59 print "Avg inversion: %f ms" % (float(avg_inversion) / 1000000) 59 print "Avg "+pi_type+ "_inversion: %f ms" % (float(avg_inversion) / 1000000)
60 for inv in longest_inversions: 60 for inv in longest_inversions:
61 print "" 61 print ""
62 print "Inversion record IDs: (%d, %d)" % (inv.inversion_start_id, 62 print pi_type+"_Inversion record IDs: (%d, %d)" % (inv.inversion_start_id,
63 inv.id) 63 inv.id)
64 print("Triggering Event IDs: (%d, %d)" % 64 print("Triggering Event IDs: (%d, %d)" %
65 (inv.inversion_start_triggering_event_id, 65 (inv.inversion_start_triggering_event_id,
diff --git a/unit_trace/gedf_test.py b/unit_trace/gedf_test.py
index 478a852..7c2ed14 100644
--- a/unit_trace/gedf_test.py
+++ b/unit_trace/gedf_test.py
@@ -21,6 +21,13 @@ def gedf_test(stream):
21 # System model 21 # System model
22 on_cpu = [] # Tasks on a CPU 22 on_cpu = [] # Tasks on a CPU
23 off_cpu = [] # Tasks not on a CPU 23 off_cpu = [] # Tasks not on a CPU
24
25 tasklet_off_cpu = [] # Tasklets on a CPU
26 tasklet_on_cpu = [] # Tasklets on a CPU
27
28 work_off_cpu = [] # Work items on a CPU
29 work_on_cpu = [] # Work items on a CPU
30
24 m = None # CPUs 31 m = None # CPUs
25 32
26 # Time of the last record we saw. Only run the G-EDF test when the time 33 # Time of the last record we saw. Only run the G-EDF test when the time
@@ -45,16 +52,23 @@ def gedf_test(stream):
45 # so we only check when the time has moved forward) 52 # so we only check when the time has moved forward)
46 # Also, need to update the first_event_this_timestamp variable 53 # Also, need to update the first_event_this_timestamp variable
47 if last_time is not None and last_time != record.when: 54 if last_time is not None and last_time != record.when:
48 errors = _gedf_check(off_cpu,on_cpu,last_time,m, 55 errors = _gedf_check(off_cpu,on_cpu,last_time,m,
49 first_event_this_timestamp) 56 first_event_this_timestamp)
50 first_event_this_timestamp = record.id 57 errors += _gedf_check_tasklet(off_cpu,on_cpu,
51 for error in errors: 58 tasklet_off_cpu,tasklet_on_cpu,last_time,m,
52 yield error 59 first_event_this_timestamp)
60 errors += _gedf_check_work(off_cpu,on_cpu,
61 work_off_cpu,work_on_cpu,last_time,m,
62 first_event_this_timestamp)
63
64 first_event_this_timestamp = record.id
65 for error in errors:
66 yield error
53 67
54 # Add a newly-released Job to the off_cpu queue 68 # Add a newly-released Job to the off_cpu queue
55 if record.type_name == 'release': 69 if record.type_name == 'release':
56 off_cpu.append(Job(record)) 70 off_cpu.append(Job(record))
57 71
58 # Move a Job from the off_cpu queue to on_cpu 72 # Move a Job from the off_cpu queue to on_cpu
59 elif record.type_name == 'switch_to': 73 elif record.type_name == 'switch_to':
60 pos = _find_job(record,off_cpu) 74 pos = _find_job(record,off_cpu)
@@ -93,6 +107,8 @@ def gedf_test(stream):
93 del on_cpu[pos] 107 del on_cpu[pos]
94 if job.is_complete == False: 108 if job.is_complete == False:
95 off_cpu.append(job) 109 off_cpu.append(job)
110
111
96 112
97 # A job has been blocked. 113 # A job has been blocked.
98 elif record.type_name == 'block': 114 elif record.type_name == 'block':
@@ -114,6 +130,94 @@ def gedf_test(stream):
114 130
115 last_time = record.when 131 last_time = record.when
116 yield record 132 yield record
133
134 # Add a newly-released Takslet to the tasklet_off_cpu queue
135 if record.type_name == 'tasklet_release':
136 tasklet_off_cpu.append(Job(record))
137
138 # Move a Takslet from the tasklet_off_cpu queue to tasklet_on_cpu
139 elif record.type_name == 'tasklet_begin':
140 pos = _find_job(record,tasklet_off_cpu)
141 if pos is None:
142 msg = "Event %d tried to begin to a tasklet that was not on the"
143 msg += " tasklet_off_cpu queue\n"
144 msg = msg % (record.id)
145 sys.stderr.write(msg)
146 exit()
147 job = tasklet_off_cpu[pos]
148 del tasklet_off_cpu[pos]
149 tasklet_on_cpu.append(job)
150
151
152 # A Takslet is end from a CPU.
153 elif record.type_name == 'tasklet_end':
154 pos = _find_job(record,tasklet_on_cpu)
155 if pos is None:
156 msg = ("Event %d tried to end a tasklet" +
157 " that was not running\n")
158 msg = msg % (record.id)
159 sys.stderr.write(msg)
160 exit()
161 job = tasklet_on_cpu[pos]
162 del tasklet_on_cpu[pos]
163
164 # Add a newly-released Work item to the work_off_cpu queue
165 if record.type_name == 'work_release':
166 work_off_cpu.append(Job(record))
167
168 # Register a klitirqd threadto a Work item in the work_off_cpu
169 elif record.type_name == 'work_begin':
170 pos = _find_job(record,work_off_cpu)
171 if pos is None:
172 msg = "Event %d tried to begin to a work item that was not on the"
173 msg += " work_off_cpu queue\n"
174 msg = msg % (record.id)
175 sys.stderr.write(msg)
176 exit()
177 job = work_off_cpu[pos]
178 job.exe_pid = record.exe_pid
179 del work_off_cpu[pos]
180 work_on_cpu.append(job)
181
182 # A Work item is end from a CPU.
183 elif record.type_name == 'work_end':
184 pos = _find_job(record,work_on_cpu)
185 if pos is not None:
186 del work_on_cpu[pos]
187 else:
188 pos = _find_job(record,work_off_cpu)
189 if pos is not None:
190 msg = ("Event %d tried to end a work item" +
191 " that hasn't not executed\n")
192 msg = msg % (record.id)
193 sys.stderr.write(msg)
194 exit()
195
196 # a Tasklet has Priority inheritance
197 elif record.type_name == 'eff_prio_change':
198 pos = _find_job(record,on_cpu)
199
200 if pos is None:
201 msg = ("Event %d tried to change a jobs priority " +
202 " that was not running\n")
203 msg = msg % (record.id)
204 sys.stderr.write(msg)
205 exit()
206
207 inh_pos = _find_inh_job(record,off_cpu)
208 if inh_pos is None:
209 inh_pos = _find_inh_job(record,on_cpu)
210 inh_job = on_cpu[pos]
211 else:
212 inh_job = off_cpu[pos]
213
214 if inh_pos is not None:
215 on_cpu[pos].is_prio_inh=True
216 on_cpu[pos].inh_deadline = inh_job.deadline
217 else:
218 on_cpu[pos].is_prio_inh=False
219 on_cpu[pos].inh_deadline =job.deadline
220
117 221
118############################################################################### 222###############################################################################
119# Private Functions 223# Private Functions
@@ -125,6 +229,9 @@ class Job(object):
125 self.pid = record.pid 229 self.pid = record.pid
126 self.job = record.job 230 self.job = record.job
127 self.deadline = record.deadline 231 self.deadline = record.deadline
232 self.inh_deadline = record.deadline
233 self.exe_pid = None
234 self.is_prio_inh = False
128 self.is_complete = False 235 self.is_complete = False
129 self.is_blocked = False 236 self.is_blocked = False
130 self.inversion_start = None 237 self.inversion_start = None
@@ -137,7 +244,7 @@ class Job(object):
137# G-EDF errors: the start or end of an inversion 244# G-EDF errors: the start or end of an inversion
138class Error(object): 245class Error(object):
139 id = 0 246 id = 0
140 def __init__(self, job, off_cpu, on_cpu,first_event_this_timestamp): 247 def __init__(self, job, off_cpu, on_cpu,first_event_this_timestamp,pi_type):
141 Error.id += 1 248 Error.id += 1
142 self.id = Error.id 249 self.id = Error.id
143 self.job = copy.copy(job) 250 self.job = copy.copy(job)
@@ -146,13 +253,15 @@ class Error(object):
146 self.record_type = 'error' 253 self.record_type = 'error'
147 self.triggering_event_id = first_event_this_timestamp 254 self.triggering_event_id = first_event_this_timestamp
148 if job.inversion_end is None: 255 if job.inversion_end is None:
149 self.type_name = 'inversion_start' 256 self.type_name = pi_type+'_inversion_start'
150 job.inversion_start_id = self.id 257 job.inversion_start_id = self.id
151 job.inversion_start_triggering_event_id = self.triggering_event_id 258 job.inversion_start_triggering_event_id = self.triggering_event_id
152 else: 259 else:
153 self.type_name = 'inversion_end' 260 self.type_name = pi_type+'_inversion_end'
154 self.inversion_start_id = job.inversion_start_id 261 self.inversion_start_id = job.inversion_start_id
155 self.inversion_start_triggering_event_id = job.inversion_start_triggering_event_id 262 self.inversion_start_triggering_event_id = job.inversion_start_triggering_event_id
263
264
156 265
157# Returns the position of a Job in a list, or None 266# Returns the position of a Job in a list, or None
158def _find_job(record,list): 267def _find_job(record,list):
@@ -161,6 +270,20 @@ def _find_job(record,list):
161 return i 270 return i
162 return None 271 return None
163 272
273# Returns the position of a Job in a list, or None
274def _find_work_carrier(record,list):
275 for i in range(0,len(list)):
276 if list[i].pid == exe_pid:
277 return i
278 return None
279
280# Returns the position of a inheritanced Job in a list, or None
281def _find_inh_job(record,list):
282 for i in range(0,len(list)):
283 if list[i].pid == record.inh_pid:
284 return i
285 return None
286
164# Return records for any inversion_starts and inversion_ends 287# Return records for any inversion_starts and inversion_ends
165def _gedf_check(off_cpu,on_cpu,when,m,first_event_this_timestamp): 288def _gedf_check(off_cpu,on_cpu,when,m,first_event_this_timestamp):
166 289
@@ -192,14 +315,14 @@ def _gedf_check(off_cpu,on_cpu,when,m,first_event_this_timestamp):
192 if job not in on_cpu and job.inversion_start is None: 315 if job not in on_cpu and job.inversion_start is None:
193 job.inversion_start = when 316 job.inversion_start = when
194 errors.append(Error(job, off_cpu, on_cpu, 317 errors.append(Error(job, off_cpu, on_cpu,
195 first_event_this_timestamp)) 318 first_event_this_timestamp,"Task"))
196 319
197 # It is running and an inversion_start exists (i.e. it it still 320 # It is running and an inversion_start exists (i.e. it it still
198 # marked as being inverted) 321 # marked as being inverted)
199 elif job in on_cpu and job.inversion_start is not None: 322 elif job in on_cpu and job.inversion_start is not None:
200 job.inversion_end = when 323 job.inversion_end = when
201 errors.append(Error(job, off_cpu, on_cpu, 324 errors.append(Error(job, off_cpu, on_cpu,
202 first_event_this_timestamp)) 325 first_event_this_timestamp,"Task"))
203 job.inversion_start = None 326 job.inversion_start = None
204 job.inversion_end = None 327 job.inversion_end = None
205 328
@@ -210,7 +333,7 @@ def _gedf_check(off_cpu,on_cpu,when,m,first_event_this_timestamp):
210 if job not in on_cpu and job.inversion_start is not None: 333 if job not in on_cpu and job.inversion_start is not None:
211 job.inversion_end = when 334 job.inversion_end = when
212 errors.append(Error(job, off_cpu, on_cpu, 335 errors.append(Error(job, off_cpu, on_cpu,
213 first_event_this_timestamp)) 336 first_event_this_timestamp,"Task"))
214 job.inversion_start = None 337 job.inversion_start = None
215 job.inversion_end = None 338 job.inversion_end = None
216 339
@@ -220,8 +343,204 @@ def _gedf_check(off_cpu,on_cpu,when,m,first_event_this_timestamp):
220 for job in all: 343 for job in all:
221 job.inversion_end = when 344 job.inversion_end = when
222 errors.append(Error(job, off_cpu, on_cpu, 345 errors.append(Error(job, off_cpu, on_cpu,
223 first_event_this_timestamp)) 346 first_event_this_timestamp,"Task"))
224 job.inversion_start = None 347 job.inversion_start = None
225 job.inversion_end = None 348 job.inversion_end = None
226 349
227 return errors 350 return errors
351
352# Return records for any inversion_starts and inversion_ends
353def _gedf_check_work(off_cpu,on_cpu,
354 work_off_cpu,work_on_cpu,
355 when,m,first_event_this_timestamp):
356
357 # List of error records to be returned
358 errors = []
359
360 # List of all jobs
361 all_prio = []
362 for x in on_cpu:
363 all_prio.append(x)
364 for x in off_cpu:
365 all_prio.append(x)
366
367 # Sort all task by then by deadline (inh_deadline).
368 all_prio.sort(key=lambda x: x.inh_deadline)
369
370 #Look for all tasklet is tasklet_off_cpu (not running)
371 for work in work_off_cpu:
372 _on = _find_job(work,on_cpu)
373 pos = _find_job(work,all_prio)
374 # owner task must be completed!! weird
375 if pos is None:
376 continue
377 # if the owner task is running
378 if _on is not None:
379 # if the owner task is not blocked
380 if on_cpu[_on].is_blocked==False and work.inversion_start is not None:
381 work.inversion_end = when
382 errors.append(Error(work, work_off_cpu, work_on_cpu,
383 first_event_this_timestamp,"Work_Item"))
384 work.inversion_start = None
385 work.inversion_end = None
386 # if the owner task is blocked
387 elif on_cpu[_on].is_blocked==True:
388 # if the owner task prioirty is smaller than m
389 if pos<m and work.inversion_start is None:
390 work.inversion_start = when
391 errors.append(Error(work, work_off_cpu, work_on_cpu,
392 first_event_this_timestamp,"Work_Item"))
393 # if the owner task prioirty is bigger than m
394 elif pos>=m and work.inversion_start is not None:
395 work.inversion_end = when
396 errors.append(Error(work, work_off_cpu, work_on_cpu,
397 first_event_this_timestamp,"Work_Item"))
398 work.inversion_start = None
399 work.inversion_end = None
400 # if the owner task is not running
401 else:
402 # if the owner task prioirty is smaller than m
403 if pos<m and work.inversion_start is None:
404 work.inversion_start = when
405 errors.append(Error(work, work_off_cpu, work_on_cpu,
406 first_event_this_timestamp,"Work_Item"))
407 # if the owner task prioirty is bigger than m
408 elif pos >= m and work.inversion_start is not None:
409 work.inversion_end = when
410 errors.append(Error(work, work_off_cpu, work_on_cpu,
411 first_event_this_timestamp,"Work_Item"))
412 work.inversion_start = None
413 work.inversion_end = None
414
415 # have klitirqd take care of
416 for work in work_on_cpu:
417 _on = _find_job(work,on_cpu)
418 pos = _find_job(work,all_prio)
419 # owner task must be completed!! weird
420 if pos is None:
421 continue
422 klit_pos = _find_work_carrier(work,on_cpu)
423 # if the klitirqd task is running and is not blocked
424 if klit_pos is not None and on_cpu[klit_pos].is_blocked == False and work.inversion_start is not None:
425 work.inversion_end = when
426 errors.append(Error(work, work_off_cpu, work_on_cpu,
427 first_event_this_timestamp,"Work_Item"))
428 work.inversion_start = None
429 work.inversion_end = None
430 else:
431 # if the owner task is running
432 if _on is not None:
433 # if the owner task is not blocked
434 if on_cpu[_on].is_blocked==False and work.inversion_start is not None:
435 work.inversion_end = when
436 errors.append(Error(work, work_off_cpu, work_on_cpu,
437 first_event_this_timestamp,"Work_Item"))
438 work.inversion_start = None
439 work.inversion_end = None
440 # if the owner task is blocked
441 elif on_cpu[_on].is_blocked==True :
442 # if the owner task prioirty is smaller than m
443 if pos<m and work.inversion_start is None:
444 work.inversion_start = when
445 errors.append(Error(work, work_off_cpu, work_on_cpu,
446 first_event_this_timestamp,"Work_Item"))
447 # if the owner task prioirty is bigger than m
448 elif pos>=m and work.inversion_start is not None:
449 work.inversion_end = when
450 errors.append(Error(work, work_off_cpu, work_on_cpu,
451 first_event_this_timestamp,"Work_Item"))
452 work.inversion_start = None
453 work.inversion_end = None
454 # if the owner task is not running
455 else:
456 # if the owner task prioirty is smaller than m
457 if pos<m and work.inversion_start is None:
458 work.inversion_start = when
459 errors.append(Error(work, work_off_cpu, work_on_cpu,
460 first_event_this_timestamp,"Work_Item"))
461 # if the owner task prioirty is bigger than m
462 elif pos>=m and work.inversion_start is not None:
463 work.inversion_end = when
464 errors.append(Error(work, work_off_cpu, work_on_cpu,
465 first_event_this_timestamp,"Work_Item"))
466 work.inversion_start = None
467 work.inversion_end = None
468
469
470 return errors
471
472
473
474# Return records for any inversion_starts and inversion_ends
475def _gedf_check_tasklet(off_cpu,on_cpu,
476 tasklet_off_cpu, tasklet_on_cpu,
477 when,m,first_event_this_timestamp):
478
479 # List of error records to be returned
480 errors = []
481
482 # List of all jobs
483 all = []
484 for x in on_cpu:
485 all.append(x)
486 for x in off_cpu:
487 all.append(x)
488
489 # Sort all task by then by deadline (inh_deadline).
490 all.sort(key=lambda x: x.inh_deadline)
491
492 #Look for all tasklet is tasklet_off_cpu (not running)
493 for tasklet in tasklet_off_cpu:
494 _on = _find_job(tasklet,on_cpu)
495 pos = _find_job(tasklet,all)
496 # owner task must be completed!! weird
497 if pos is None:
498 continue
499 # if the owner task is running
500 if _on is not None:
501 # if the owner task is not blocked
502 if on_cpu[_on].is_blocked==False and tasklet.inversion_start is not None:
503 tasklet.inversion_end = when
504 errors.append(Error(tasklet, tasklet_off_cpu, tasklet_on_cpu,
505 first_event_this_timestamp,"Tasklet"))
506 tasklet.inversion_start = None
507 tasklet.inversion_end = None
508 # if the owner task is blocked
509 elif on_cpu[_on].is_blocked==True :
510 # if the owner task prioirty is smaller than m
511 if pos<m and tasklet.inversion_start is None:
512 tasklet.inversion_start = when
513 errors.append(Error(tasklet, tasklet_off_cpu, tasklet_on_cpu,
514 first_event_this_timestamp,"Tasklet"))
515 # if the owner task prioirty is bigger than m
516 elif pos>=m and tasklet.inversion_start is not None:
517 tasklet.inversion_end = when
518 errors.append(Error(tasklet, tasklet_off_cpu, tasklet_on_cpu,
519 first_event_this_timestamp,"Tasklet"))
520 tasklet.inversion_start = None
521 tasklet.inversion_end = None
522 # if the owner task is not running
523 else:
524 # if the owner task prioirty is smaller than m
525 if pos<m and tasklet.inversion_start is None:
526 tasklet.inversion_start = when
527 errors.append(Error(tasklet, tasklet_off_cpu, tasklet_on_cpu,
528 first_event_this_timestamp,"Tasklet"))
529 # if the owner task prioirty is bigger than m
530 elif pos>=m and tasklet.inversion_start is not None:
531 tasklet.inversion_end = when
532 errors.append(Error(tasklet, tasklet_off_cpu, tasklet_on_cpu,
533 first_event_this_timestamp,"Tasklet"))
534 tasklet.inversion_start = None
535 tasklet.inversion_end = None
536
537 #Look for all tasklet is tasklet_on_cpu (running)
538 for tasklet in tasklet_on_cpu:
539 if tasklet.inversion_start is not None:
540 tasklet.inversion_end = when
541 errors.append(Error(tasklet, tasklet_off_cpu, tasklet_on_cpu,
542 first_event_this_timestamp,"Tasklet"))
543 tasklet.inversion_start = None
544 tasklet.inversion_end = None
545
546 return errors
diff --git a/unit_trace/stdout_printer.py b/unit_trace/stdout_printer.py
index b70b31a..c8fba1f 100644
--- a/unit_trace/stdout_printer.py
+++ b/unit_trace/stdout_printer.py
@@ -14,10 +14,18 @@ def stdout_printer(stream):
14 _print_event(record) 14 _print_event(record)
15 elif record.record_type == "meta" and record.type_name == "stats": 15 elif record.record_type == "meta" and record.type_name == "stats":
16 _print_stats(record) 16 _print_stats(record)
17 elif record.record_type == "error" and record.type_name == 'inversion_start': 17 elif record.record_type == "error" and record.type_name == 'Task_inversion_start':
18 _print_inversion_start(record) 18 _print_inversion_start(record,"Task_")
19 elif record.record_type == "error" and record.type_name == 'inversion_end': 19 elif record.record_type == "error" and record.type_name == 'Task_inversion_end':
20 _print_inversion_end(record) 20 _print_inversion_end(record,"Task_")
21 elif record.record_type == "error" and record.type_name == 'Tasklet_inversion_start':
22 _print_inversion_start(record,"Tasklet_")
23 elif record.record_type == "error" and record.type_name == 'Tasklet_inversion_end':
24 _print_inversion_end(record,"Tasklet_")
25 elif record.record_type == "error" and record.type_name == 'Work_Item_inversion_start':
26 _print_inversion_start(record,"Work_Item_")
27 elif record.record_type == "error" and record.type_name == 'Work_Item_inversion_end':
28 _print_inversion_end(record,"Work_Item_")
21 else: 29 else:
22 continue 30 continue
23 print "" 31 print ""
@@ -32,8 +40,8 @@ def _print_event(record):
32 print "Type: %s" % (record.type_name) 40 print "Type: %s" % (record.type_name)
33 print "Time: %d" % (record.when) 41 print "Time: %d" % (record.when)
34 42
35def _print_inversion_start(record): 43def _print_inversion_start(record,pi_type):
36 print "Type: %s" % ("Inversion start") 44 print "Type: %s" % (pi_type+"Inversion start")
37 print "Inversion Record IDs: (%d, U)" % (record.id) 45 print "Inversion Record IDs: (%d, U)" % (record.id)
38 print "Triggering Event IDs: (%d, U)" % (record.triggering_event_id) 46 print "Triggering Event IDs: (%d, U)" % (record.triggering_event_id)
39 print "Time: %d" % (record.job.inversion_start) 47 print "Time: %d" % (record.job.inversion_start)
@@ -48,8 +56,8 @@ def _print_inversion_start(record):
48 print str(job) + " ", 56 print str(job) + " ",
49 print #newline 57 print #newline
50 58
51def _print_inversion_end(record): 59def _print_inversion_end(record,pi_type):
52 print "Type: %s" % ("Inversion end") 60 print "Type: %s" % (pi_type+"Inversion end")
53 print "Inversion record IDs: (%d, %d)" % (record.inversion_start_id, 61 print "Inversion record IDs: (%d, %d)" % (record.inversion_start_id,
54 record.id) 62 record.id)
55 print("Triggering Event IDs: (%d, %d)" % 63 print("Triggering Event IDs: (%d, %d)" %
diff --git a/unit_trace/trace_reader.py b/unit_trace/trace_reader.py
index db36c13..45b29e1 100644
--- a/unit_trace/trace_reader.py
+++ b/unit_trace/trace_reader.py
@@ -266,12 +266,58 @@ class StSysReleaseData:
266 formatStr = struct.Struct(StHeader.format + format) 266 formatStr = struct.Struct(StHeader.format + format)
267 keys = StHeader.keys + ['when','release'] 267 keys = StHeader.keys + ['when','release']
268 message = 'All tasks have checked in, task system released by user' 268 message = 'All tasks have checked in, task system released by user'
269
270class StTaskletReleaseData:
271 format = 'Q'
272 formatStr = struct.Struct(StHeader.format + format)
273 keys = StHeader.keys + ['when']
274 message = 'A tasklet is queued'
275
276class StTaskletBeginData:
277 format = 'Q'
278 formatStr = struct.Struct(StHeader.format + format)
279 keys = StHeader.keys + ['when']
280 message = 'A tasklet begins execution'
281
282class StTaskletEndData:
283 format = 'Qc'
284 formatStr = struct.Struct(StHeader.format + format)
285 keys = StHeader.keys + ['when','flushed']
286 message = 'A tasklet completes execution'
287
288class StWorkReleaseData:
289 format = 'Q'
290 formatStr = struct.Struct(StHeader.format + format)
291 keys = StHeader.keys + ['when']
292 message = 'A work item is queued'
293
294class StWorkBeginData:
295 format = 'Qh'
296 formatStr = struct.Struct(StHeader.format + format)
297 keys = StHeader.keys + ['when','exe_pid']
298 message = 'A work item begins execution'
299
300class StWorkEndData:
301 format = 'Qhc'
302 formatStr = struct.Struct(StHeader.format + format)
303 keys = StHeader.keys + ['when','exe_pid','flushed']
304 message = 'A work item completes execution'
305
306
307class StEffPrioChangeData:
308 format = 'Qh'
309 formatStr = struct.Struct(StHeader.format + format)
310 keys = StHeader.keys + ['when','inh_pid']
311 message = 'A tasklet priorty gets changed by inheritance'
269 312
270# Return the binary data type, given the type_num 313# Return the binary data type, given the type_num
271def _get_type(type_num): 314def _get_type(type_num):
272 types = [None,StNameData,StParamData,StReleaseData,StAssignedData, 315 types = [None,StNameData,StParamData,StReleaseData,StAssignedData,
273 StSwitchToData,StSwitchAwayData,StCompletionData,StBlockData, 316 StSwitchToData,StSwitchAwayData,StCompletionData,StBlockData,
274 StResumeData,StSysReleaseData] 317 StResumeData,StSysReleaseData,
318 StTaskletReleaseData,StTaskletBeginData,StTaskletEndData,
319 StWorkReleaseData,StWorkBeginData,StWorkEndData,
320 StEffPrioChangeData]
275 if type_num > len(types)-1 or type_num < 1: 321 if type_num > len(types)-1 or type_num < 1:
276 raise Exception 322 raise Exception
277 return types[type_num] 323 return types[type_num]
@@ -280,5 +326,8 @@ def _get_type(type_num):
280# programmers of other modules) 326# programmers of other modules)
281def _get_type_name(type_num): 327def _get_type_name(type_num):
282 type_names = [None,"name","params","release","assign","switch_to", 328 type_names = [None,"name","params","release","assign","switch_to",
283 "switch_away","completion","block","resume","sys_release"] 329 "switch_away","completion","block","resume","sys_release",
330 "tasklet_release","tasklet_begin","tasklet_end",
331 "work_release","work_begin","work_end",
332 "eff_prio_change"]
284 return type_names[type_num] 333 return type_names[type_num]