diff options
author | Gary Bressler <garybressler@nc.rr.com> | 2010-03-09 13:33:54 -0500 |
---|---|---|
committer | Gary Bressler <garybressler@nc.rr.com> | 2010-03-09 13:33:54 -0500 |
commit | 883f9dfe38ab081025220aafbf47f722b540d003 (patch) | |
tree | 6ab638add46bfd8e622301c2d704b3d6dfdba9b5 /viz/schedule.py | |
parent | b97f0447b302746ab054aba0fd7417224ba73d86 (diff) |
Preliminary, fairly workable version of unit_trace, including the visualizer.
Diffstat (limited to 'viz/schedule.py')
-rw-r--r-- | viz/schedule.py | 210 |
1 files changed, 137 insertions, 73 deletions
diff --git a/viz/schedule.py b/viz/schedule.py index f842c8d..e525b17 100644 --- a/viz/schedule.py +++ b/viz/schedule.py | |||
@@ -8,6 +8,10 @@ graphic.""" | |||
8 | from draw import * | 8 | from draw import * |
9 | import util | 9 | import util |
10 | 10 | ||
11 | import copy | ||
12 | |||
13 | EVENT_LIST = None | ||
14 | |||
11 | class TimeSlotArray(object): | 15 | class TimeSlotArray(object): |
12 | """Represents another way of organizing the events. This structure organizes events by | 16 | """Represents another way of organizing the events. This structure organizes events by |
13 | the (approximate) time at which they occur. Events that occur at approximately the same | 17 | the (approximate) time at which they occur. Events that occur at approximately the same |
@@ -17,14 +21,28 @@ class TimeSlotArray(object): | |||
17 | TASK_LIST = 0 | 21 | TASK_LIST = 0 |
18 | CPU_LIST = 1 | 22 | CPU_LIST = 1 |
19 | 23 | ||
20 | def __init__(self, start, end, time_per_maj, num_tasks, num_cpus): | 24 | def __init__(self, start=None, end=None, time_per_maj=1, num_tasks=0, num_cpus=0): |
25 | if start is None or end is None: | ||
26 | self.array = None | ||
27 | return | ||
28 | |||
21 | self.start = start | 29 | self.start = start |
22 | self.end = end | 30 | self.end = end |
23 | self.time_per_maj = time_per_maj | 31 | self.time_per_maj = time_per_maj |
24 | self.list_sizes = { TimeSlotArray.TASK_LIST : num_tasks, TimeSlotArray.CPU_LIST : num_cpus } | 32 | self.list_sizes = { TimeSlotArray.TASK_LIST : num_tasks, TimeSlotArray.CPU_LIST : num_cpus } |
25 | self.array = [{TimeSlotArray.TASK_LIST : [{} for i in range(0, num_tasks)], \ | 33 | self.array = {} |
26 | TimeSlotArray.CPU_LIST : [{} for i in range (0, num_cpus)]} \ | 34 | |
27 | for i in range(0, (end - start) // self.time_per_maj + 1)] | 35 | for type in self.list_sizes: |
36 | num = self.list_sizes[type] | ||
37 | self.array[type] = [] | ||
38 | for i in range(0, int((end - start) // self.time_per_maj + 1)): | ||
39 | # for each slot in the array, we need a list of all events under this type | ||
40 | # (for example, a list of all events that occur in this time slot, indexed | ||
41 | # by task). | ||
42 | self.array[type].append([]) | ||
43 | for j in range(0, num): | ||
44 | self.array[type][i].append(dict(zip(EVENT_LIST, \ | ||
45 | [[] for j in range(0, len(EVENT_LIST))]))) | ||
28 | 46 | ||
29 | def get_time_slot(self, time): | 47 | def get_time_slot(self, time): |
30 | return int((time - self.start) // self.time_per_maj) | 48 | return int((time - self.start) // self.time_per_maj) |
@@ -34,29 +52,32 @@ class TimeSlotArray(object): | |||
34 | cpu = event.get_cpu() | 52 | cpu = event.get_cpu() |
35 | time_slot = self.get_time_slot(event.get_time()) | 53 | time_slot = self.get_time_slot(event.get_time()) |
36 | 54 | ||
37 | self.array[time_slot][TimeSlotArray.TASK_LIST][task_no][event.__class__] = event | 55 | self.array[TimeSlotArray.TASK_LIST][time_slot][task_no][event.__class__].append(event) |
38 | self.array[time_slot][TimeSlotArray.CPU_LIST][cpu][event.__class__] = event | 56 | self.array[TimeSlotArray.CPU_LIST][time_slot][cpu][event.__class__].append(event) |
39 | 57 | ||
40 | span_events = { SwitchAwayEvent : IsRunningDummy, InversionEndEvent : InversionDummy} | 58 | span_events = { SwitchAwayEvent : IsRunningDummy, InversionEndEvent : InversionDummy} |
41 | 59 | ||
42 | for span_event in span_events: | 60 | for span_event in span_events: |
43 | if isinstance(event, span_event) and not event.is_erroneous(): | 61 | if isinstance(event, span_event) and event.corresp_start_event is not None: |
44 | start_slot = self.get_time_slot(event.corresp_start_event.get_time()) | 62 | start_slot = self.get_time_slot(event.corresp_start_event.get_time()) |
45 | end_slot = self.get_time_slot(event.get_time()) | 63 | end_slot = time_slot |
46 | for slot in range(start_slot + 1, end_slot): | 64 | for slot in range(start_slot + 1, end_slot): |
47 | dummy = span_events[span_event](task_no, cpu) | 65 | dummy = span_events[span_event](task_no, cpu) |
48 | dummy.corresp_start_event = event.corresp_start_event | 66 | dummy.corresp_start_event = event.corresp_start_event |
49 | self.array[slot][TimeSlotArray.TASK_LIST][task_no][dummy.__class__] = dummy | 67 | self.array[TimeSlotArray.TASK_LIST][slot][task_no][dummy.__class__].append(dummy) |
50 | self.array[slot][TimeSlotArray.CPU_LIST][cpu][dummy.__class__] = dummy | 68 | self.array[TimeSlotArray.CPU_LIST][slot][cpu][dummy.__class__].append(dummy) |
51 | 69 | ||
52 | def iter_over_period(self, start, end, start_no, end_no, list_type, event_types): | 70 | def iter_over_period(self, start, end, start_no, end_no, list_type, event_types): |
71 | if self.array is None: | ||
72 | return # empty schedule | ||
73 | |||
53 | if start > end: | 74 | if start > end: |
54 | raise ValueError('Litmus is not a time machine') | 75 | raise ValueError('Litmus is not a time machine') |
55 | if start_no > end_no: | 76 | if start_no > end_no: |
56 | raise ValueError('start no should be less than end no') | 77 | raise ValueError('start no should be less than end no') |
57 | 78 | ||
58 | start_slot = max(0, self.get_time_slot(start)) | 79 | start_slot = max(0, self.get_time_slot(start)) |
59 | end_slot = min(len(self.array), self.get_time_slot(end) + 2) | 80 | end_slot = min(len(self.array[list_type]), self.get_time_slot(end) + 2) |
60 | 81 | ||
61 | start_no = max(0, start_no) | 82 | start_no = max(0, start_no) |
62 | end_no = min(self.list_sizes[list_type] - 1, end_no) | 83 | end_no = min(self.list_sizes[list_type] - 1, end_no) |
@@ -64,8 +85,8 @@ class TimeSlotArray(object): | |||
64 | for slot in range(start_slot, end_slot): | 85 | for slot in range(start_slot, end_slot): |
65 | for no in range(start_no, end_no + 1): | 86 | for no in range(start_no, end_no + 1): |
66 | for type in event_types: | 87 | for type in event_types: |
67 | if type in self.array[slot][list_type][no]: | 88 | for event in self.array[list_type][slot][no][type]: |
68 | yield self.array[slot][list_type][no][type] | 89 | yield event |
69 | 90 | ||
70 | class Schedule(object): | 91 | class Schedule(object): |
71 | """The total schedule (task system), consisting of a certain number of | 92 | """The total schedule (task system), consisting of a certain number of |
@@ -75,36 +96,47 @@ class Schedule(object): | |||
75 | self.name = name | 96 | self.name = name |
76 | self.tasks = {} | 97 | self.tasks = {} |
77 | self.task_list = [] | 98 | self.task_list = [] |
99 | self.selected = {} | ||
78 | self.time_slot_array = None | 100 | self.time_slot_array = None |
79 | self.cur_task_no = 0 | 101 | self.cur_task_no = 0 |
80 | self.num_cpus = num_cpus | 102 | self.num_cpus = num_cpus |
81 | for task in task_list: | 103 | for task in task_list: |
82 | self.add_task(task) | 104 | self.add_task(task) |
83 | 105 | ||
84 | def set_time_params(self, time_per_maj=None): | 106 | def get_selected(self): |
85 | if self.get_task_list() is None: | 107 | return self.selected |
86 | return (0, 0) | ||
87 | 108 | ||
109 | def set_selected(self, new_selected): | ||
110 | for event in self.selected: | ||
111 | event.selected = False | ||
112 | for event in new_selected: | ||
113 | event.selected = True | ||
114 | self.selected = new_selected | ||
115 | |||
116 | def get_selected(self): | ||
117 | return copy.copy(self.selected) | ||
118 | |||
119 | def set_time_params(self, time_per_maj=None, max_num_slots=None): | ||
88 | def find_extreme_time_sched(sched, cmp): | 120 | def find_extreme_time_sched(sched, cmp): |
89 | def find_extreme_time_task(task, cmp): | 121 | def find_extreme_time_task(task, cmp): |
90 | def find_extreme_time_job(job, cmp): | 122 | def find_extreme_time_job(job, cmp): |
91 | extreme_time = None | 123 | extreme_time = None |
92 | for time in job.get_events(): | 124 | for time in job.get_events(): |
93 | if extreme_time is None or cmp(time, extreme_time) < 0: | 125 | if (extreme_time is None) or cmp(time, extreme_time) < 0: |
94 | extreme_time = time | 126 | extreme_time = time |
95 | return extreme_time | 127 | return extreme_time |
96 | 128 | ||
97 | extreme_time = None | 129 | extreme_time = None |
98 | for job_no in task.get_jobs(): | 130 | for job_no in task.get_jobs(): |
99 | time = find_extreme_time_job(task.get_jobs()[job_no], cmp) | 131 | time = find_extreme_time_job(task.get_jobs()[job_no], cmp) |
100 | if time is not None and (extreme_time is None or cmp(time, extreme_time) < 0): | 132 | if (time is not None) and ((extreme_time is None) or cmp(time, extreme_time) < 0): |
101 | extreme_time = time | 133 | extreme_time = time |
102 | return extreme_time | 134 | return extreme_time |
103 | 135 | ||
104 | extreme_time = None | 136 | extreme_time = None |
105 | for task in sched.get_task_list(): | 137 | for task in sched.get_task_list(): |
106 | time = find_extreme_time_task(task, cmp) | 138 | time = find_extreme_time_task(task, cmp) |
107 | if time is not None and (extreme_time is None or cmp(time, extreme_time) < 0): | 139 | if (time is not None) and ((extreme_time is None) or cmp(time, extreme_time) < 0): |
108 | extreme_time = time | 140 | extreme_time = time |
109 | 141 | ||
110 | return extreme_time | 142 | return extreme_time |
@@ -129,20 +161,32 @@ class Schedule(object): | |||
129 | 161 | ||
130 | self.start = find_extreme_time_sched(self, earliest_cmp) | 162 | self.start = find_extreme_time_sched(self, earliest_cmp) |
131 | self.end = find_extreme_time_sched(self, latest_cmp) | 163 | self.end = find_extreme_time_sched(self, latest_cmp) |
132 | self.time_per_maj = time_per_maj | 164 | if self.start is None or self.end is None: |
165 | self.time_slot_array = TimeSlotArray() | ||
166 | return | ||
167 | |||
168 | min_time_per_maj = (self.end - self.start) * 1.0 / max_num_slots | ||
169 | if max_num_slots is not None and time_per_maj is not None: | ||
170 | if time_per_maj < min_time_per_maj: | ||
171 | self.time_per_maj = min_time_per_maj | ||
172 | else: | ||
173 | self.time_per_maj = time_per_maj | ||
174 | else: | ||
175 | self.time_per_maj = time_per_maj | ||
133 | self.time_slot_array = None | 176 | self.time_slot_array = None |
134 | if self.time_per_maj is not None: | 177 | if self.time_per_maj is not None: |
135 | self.time_slot_array = TimeSlotArray(self.start, self.end, time_per_maj, \ | 178 | self.time_slot_array = TimeSlotArray(self.start, self.end, self.time_per_maj, \ |
136 | len(self.task_list), self.num_cpus) | 179 | len(self.task_list), self.num_cpus) |
137 | 180 | ||
181 | |||
138 | def get_time_slot_array(self): | 182 | def get_time_slot_array(self): |
139 | return self.time_slot_array | 183 | return self.time_slot_array |
140 | 184 | ||
141 | def get_time_bounds(self): | 185 | def get_time_bounds(self): |
142 | return (self.start, self.end) | 186 | return (self.start, self.end) |
143 | 187 | ||
144 | def scan(self, time_per_maj): | 188 | def scan(self, time_per_maj, max_num_slots): |
145 | self.set_time_params(time_per_maj) | 189 | self.set_time_params(time_per_maj, max_num_slots) |
146 | 190 | ||
147 | # we scan the graph task by task, and job by job | 191 | # we scan the graph task by task, and job by job |
148 | switches = {} | 192 | switches = {} |
@@ -261,9 +305,13 @@ class DummyEvent(object): | |||
261 | def get_layer(self): | 305 | def get_layer(self): |
262 | return self.layer | 306 | return self.layer |
263 | 307 | ||
264 | def render(self, graph, layer, prev_events): | 308 | def render(self, graph, layer, prev_events, selectable=False): |
265 | """Method that the visualizer calls to tell the event to render itself | 309 | """Method that the visualizer calls to tell the event to render itself |
266 | Obviously only implemented by subclasses (actual event types)""" | 310 | Obviously only implemented by subclasses (actual event types) |
311 | |||
312 | ``Rendering'' can mean either actually drawing the event or just | ||
313 | adding it as a selectable region. This is controlled by the | ||
314 | ``selectable'' parameter""" | ||
267 | raise NotImplementdError | 315 | raise NotImplementdError |
268 | 316 | ||
269 | class Event(DummyEvent): | 317 | class Event(DummyEvent): |
@@ -295,10 +343,6 @@ class Event(DummyEvent): | |||
295 | def is_selected(self): | 343 | def is_selected(self): |
296 | """Returns whether the event has been selected by the user. (needed for rendering)""" | 344 | """Returns whether the event has been selected by the user. (needed for rendering)""" |
297 | return self.selected | 345 | return self.selected |
298 | |||
299 | def set_selected(self, sel): | ||
300 | """Sets the event's state to selected.""" | ||
301 | self.selected = sel | ||
302 | 346 | ||
303 | def scan(self, cur_cpu, switches): | 347 | def scan(self, cur_cpu, switches): |
304 | """Part of the procedure that walks through all the events and sets | 348 | """Part of the procedure that walks through all the events and sets |
@@ -328,13 +372,16 @@ class SuspendEvent(Event): | |||
328 | print "suspending on a CPU different from the CPU we are on!" | 372 | print "suspending on a CPU different from the CPU we are on!" |
329 | super(SuspendEvent, self).scan(cur_cpu, switches) | 373 | super(SuspendEvent, self).scan(cur_cpu, switches) |
330 | 374 | ||
331 | def render(self, graph, layer, prev_events): | 375 | def render(self, graph, layer, prev_events, selectable=False): |
332 | if layer == self.layer: | 376 | if layer == self.layer: |
333 | prev_events[self] = None | 377 | prev_events[self] = None |
334 | graph.draw_suspend_triangle_at_time(self.get_time(), self.get_job().get_task().get_task_no(), | 378 | if selectable: |
335 | self.get_cpu(), self.is_selected()) | 379 | graph.add_sel_suspend_triangle_at_time(self.get_time(), self.get_job().get_task().get_task_no(), |
336 | graph.add_sel_suspend_triangle_at_time(self.get_time(), self.get_job().get_task().get_task_no(), | ||
337 | self.get_cpu(), self) | 380 | self.get_cpu(), self) |
381 | else: | ||
382 | graph.draw_suspend_triangle_at_time(self.get_time(), self.get_job().get_task().get_task_no(), | ||
383 | self.get_cpu(), self.is_selected()) | ||
384 | |||
338 | 385 | ||
339 | class ResumeEvent(Event): | 386 | class ResumeEvent(Event): |
340 | def __init__(self, time, cpu): | 387 | def __init__(self, time, cpu): |
@@ -350,13 +397,16 @@ class ResumeEvent(Event): | |||
350 | print "Resuming when currently scheduled on a CPU, but on a different CPU from the current CPU!" | 397 | print "Resuming when currently scheduled on a CPU, but on a different CPU from the current CPU!" |
351 | super(ResumeEvent, self).scan(cur_cpu, switches) | 398 | super(ResumeEvent, self).scan(cur_cpu, switches) |
352 | 399 | ||
353 | def render(self, graph, layer, prev_events): | 400 | def render(self, graph, layer, prev_events, selectable=False): |
354 | if layer == self.layer: | 401 | if layer == self.layer: |
355 | prev_events[self] = None | 402 | prev_events[self] = None |
356 | graph.draw_resume_triangle_at_time(self.get_time(), self.get_job().get_task().get_task_no(), | 403 | if selectable: |
357 | self.get_cpu(), self.is_selected()) | 404 | graph.add_sel_resume_triangle_at_time(self.get_time(), self.get_job().get_task().get_task_no(), |
358 | graph.add_sel_resume_triangle_at_time(self.get_time(), self.get_job().get_task().get_task_no(), | ||
359 | self.get_cpu(), self) | 405 | self.get_cpu(), self) |
406 | else: | ||
407 | graph.draw_resume_triangle_at_time(self.get_time(), self.get_job().get_task().get_task_no(), | ||
408 | self.get_cpu(), self.is_selected()) | ||
409 | |||
360 | 410 | ||
361 | class CompleteEvent(Event): | 411 | class CompleteEvent(Event): |
362 | def __init__(self, time, cpu): | 412 | def __init__(self, time, cpu): |
@@ -369,14 +419,15 @@ class CompleteEvent(Event): | |||
369 | def scan(self, cur_cpu, switches): | 419 | def scan(self, cur_cpu, switches): |
370 | super(CompleteEvent, self).scan(cur_cpu, switches) | 420 | super(CompleteEvent, self).scan(cur_cpu, switches) |
371 | 421 | ||
372 | def render(self, graph, layer, prev_events): | 422 | def render(self, graph, layer, prev_events, selectable=False): |
373 | if layer == Canvas.TOP_LAYER: | 423 | if layer == Canvas.TOP_LAYER: |
374 | prev_events[self] = None | 424 | prev_events[self] = None |
375 | graph.draw_completion_marker_at_time(self.get_time(), self.get_job().get_task().get_task_no(), | 425 | if selectable: |
376 | self.get_cpu(), self.is_selected()) | 426 | graph.add_sel_completion_marker_at_time(self.get_time(), self.get_job().get_task().get_task_no(), |
377 | graph.add_sel_completion_marker_at_time(self.get_time(), self.get_job().get_task().get_task_no(), | ||
378 | self.get_cpu(), self) | 427 | self.get_cpu(), self) |
379 | 428 | else: | |
429 | graph.draw_completion_marker_at_time(self.get_time(), self.get_job().get_task().get_task_no(), | ||
430 | self.get_cpu(), self.is_selected()) | ||
380 | 431 | ||
381 | class SwitchAwayEvent(Event): | 432 | class SwitchAwayEvent(Event): |
382 | def __init__(self, time, cpu): | 433 | def __init__(self, time, cpu): |
@@ -412,10 +463,10 @@ class SwitchAwayEvent(Event): | |||
412 | 463 | ||
413 | super(SwitchAwayEvent, self).scan(cur_cpu, switches) | 464 | super(SwitchAwayEvent, self).scan(cur_cpu, switches) |
414 | 465 | ||
415 | def render(self, graph, layer, prev_events): | 466 | def render(self, graph, layer, prev_events, selectable=False): |
416 | if self.corresp_start_event is None or self.corresp_start_event in prev_events: | 467 | if self.corresp_start_event is None or self.corresp_start_event in prev_events: |
417 | return # erroneous switch away or already rendered | 468 | return # erroneous switch away or already rendered |
418 | self.corresp_start_event.render(graph, layer, prev_events) | 469 | self.corresp_start_event.render(graph, layer, prev_events, selectable) |
419 | 470 | ||
420 | class SwitchToEvent(Event): | 471 | class SwitchToEvent(Event): |
421 | def __init__(self, time, cpu): | 472 | def __init__(self, time, cpu): |
@@ -442,17 +493,19 @@ class SwitchToEvent(Event): | |||
442 | 493 | ||
443 | super(SwitchToEvent, self).scan(cur_cpu, switches) | 494 | super(SwitchToEvent, self).scan(cur_cpu, switches) |
444 | 495 | ||
445 | def render(self, graph, layer, prev_events): | 496 | def render(self, graph, layer, prev_events, selectable=False): |
446 | if self.is_erroneous(): | 497 | if self.corresp_end_event is None: |
447 | return # erroneous switch to | 498 | return # fatally erroneous switch to |
448 | if layer == Canvas.BOTTOM_LAYER: | 499 | if layer == Canvas.BOTTOM_LAYER: |
449 | prev_events[self] = None | 500 | prev_events[self] = None |
450 | cpu = self.get_cpu() | 501 | cpu = self.get_cpu() |
451 | task_no = self.get_job().get_task().get_task_no() | 502 | task_no = self.get_job().get_task().get_task_no() |
452 | graph.draw_bar_at_time(self.get_time(), self.corresp_end_event.get_time(), | 503 | if selectable: |
453 | task_no, cpu, self.get_job().get_job_no(), self.is_selected()) | 504 | graph.add_sel_bar_at_time(self.get_time(), self.corresp_end_event.get_time(), |
454 | graph.add_sel_bar_at_time(self.get_time(), self.corresp_end_event.get_time(), | ||
455 | task_no, cpu, self) | 505 | task_no, cpu, self) |
506 | else: | ||
507 | graph.draw_bar_at_time(self.get_time(), self.corresp_end_event.get_time(), | ||
508 | task_no, cpu, self.get_job().get_job_no(), self.is_selected()) | ||
456 | 509 | ||
457 | class ReleaseEvent(Event): | 510 | class ReleaseEvent(Event): |
458 | def __init__(self, time, cpu): | 511 | def __init__(self, time, cpu): |
@@ -465,13 +518,16 @@ class ReleaseEvent(Event): | |||
465 | def scan(self, cur_cpu, switches): | 518 | def scan(self, cur_cpu, switches): |
466 | super(ReleaseEvent, self).scan(cur_cpu, switches) | 519 | super(ReleaseEvent, self).scan(cur_cpu, switches) |
467 | 520 | ||
468 | def render(self, graph, layer, prev_events): | 521 | def render(self, graph, layer, prev_events, selectable=False): |
469 | prev_events[self] = None | 522 | prev_events[self] = None |
470 | if layer == Canvas.TOP_LAYER: | 523 | if layer == Canvas.TOP_LAYER: |
471 | graph.draw_release_arrow_at_time(self.get_time(), self.get_job().get_task().get_task_no(), | 524 | if selectable: |
525 | graph.add_sel_release_arrow_at_time(self.get_time(), self.get_job().get_task().get_task_no(), | ||
526 | self) | ||
527 | else: | ||
528 | graph.draw_release_arrow_at_time(self.get_time(), self.get_job().get_task().get_task_no(), | ||
472 | self.get_job().get_job_no(), self.is_selected()) | 529 | self.get_job().get_job_no(), self.is_selected()) |
473 | graph.add_sel_release_arrow_at_time(self.get_time(), self.get_job().get_task().get_task_no(), | 530 | |
474 | self) | ||
475 | 531 | ||
476 | class DeadlineEvent(Event): | 532 | class DeadlineEvent(Event): |
477 | def __init__(self, time, cpu): | 533 | def __init__(self, time, cpu): |
@@ -484,13 +540,16 @@ class DeadlineEvent(Event): | |||
484 | def scan(self, cur_cpu, switches): | 540 | def scan(self, cur_cpu, switches): |
485 | super(DeadlineEvent, self).scan(cur_cpu, switches) | 541 | super(DeadlineEvent, self).scan(cur_cpu, switches) |
486 | 542 | ||
487 | def render(self, graph, layer, prev_events): | 543 | def render(self, graph, layer, prev_events, selectable=False): |
488 | prev_events[self] = None | 544 | prev_events[self] = None |
489 | if layer == Canvas.TOP_LAYER: | 545 | if layer == Canvas.TOP_LAYER: |
490 | graph.draw_deadline_arrow_at_time(self.get_time(), self.get_job().get_task().get_task_no(), | 546 | if selectable: |
491 | self.get_job().get_job_no(), self.is_selected()) | 547 | graph.add_sel_deadline_arrow_at_time(self.get_time(), self.get_job().get_task().get_task_no(), |
492 | graph.add_sel_deadline_arrow_at_time(self.get_time(), self.get_job().get_task().get_task_no(), | ||
493 | self) | 548 | self) |
549 | else: | ||
550 | graph.draw_deadline_arrow_at_time(self.get_time(), self.get_job().get_task().get_task_no(), | ||
551 | self.get_job().get_job_no(), self.is_selected()) | ||
552 | |||
494 | 553 | ||
495 | class InversionStartEvent(ErrorEvent): | 554 | class InversionStartEvent(ErrorEvent): |
496 | def __init__(self, time): | 555 | def __init__(self, time): |
@@ -512,15 +571,18 @@ class InversionStartEvent(ErrorEvent): | |||
512 | # the corresp_end_event should already be set | 571 | # the corresp_end_event should already be set |
513 | super(InversionStartEvent, self).scan(cur_cpu, switches) | 572 | super(InversionStartEvent, self).scan(cur_cpu, switches) |
514 | 573 | ||
515 | def render(self, graph, layer, prev_events): | 574 | def render(self, graph, layer, prev_events, selectable=False): |
516 | if layer == Canvas.BOTTOM_LAYER: | 575 | if layer == Canvas.BOTTOM_LAYER: |
517 | prev_events[self] = None | 576 | prev_events[self] = None |
518 | cpu = self.get_cpu() | 577 | cpu = self.get_cpu() |
519 | task_no = self.get_job().get_task().get_task_no() | 578 | task_no = self.get_job().get_task().get_task_no() |
520 | graph.draw_mini_bar_at_time(self.get_time(), self.corresp_end_event.get_time(), | 579 | if selectable: |
521 | task_no, cpu, self.get_job().get_job_no(), self.is_selected()) | 580 | graph.add_sel_mini_bar_at_time(self.get_time(), self.corresp_end_event.get_time(), |
522 | graph.add_sel_mini_bar_at_time(self.get_time(), self.corresp_end_event.get_time(), | ||
523 | task_no, cpu, self) | 581 | task_no, cpu, self) |
582 | else: | ||
583 | graph.draw_mini_bar_at_time(self.get_time(), self.corresp_end_event.get_time(), | ||
584 | task_no, cpu, self.get_job().get_job_no(), self.is_selected()) | ||
585 | |||
524 | 586 | ||
525 | class InversionEndEvent(ErrorEvent): | 587 | class InversionEndEvent(ErrorEvent): |
526 | def __init__(self, time): | 588 | def __init__(self, time): |
@@ -549,23 +611,25 @@ class InversionEndEvent(ErrorEvent): | |||
549 | 611 | ||
550 | super(InversionEndEvent, self).scan(cur_cpu, switches) | 612 | super(InversionEndEvent, self).scan(cur_cpu, switches) |
551 | 613 | ||
552 | def render(self, graph, layer, prev_events): | 614 | def render(self, graph, layer, prev_events, selectable=False): |
553 | if self.corresp_start_event is None or self.corresp_start_event in prev_events: | 615 | if self.corresp_start_event is None or self.corresp_start_event in prev_events: |
554 | return # erroneous inversion end or already rendered | 616 | return # erroneous inversion end or already rendered |
555 | self.corresp_start_event.render(graph, layer, prev_events) | 617 | self.corresp_start_event.render(graph, layer, prev_events, selectable) |
556 | 618 | ||
557 | class InversionDummy(DummyEvent): | 619 | class InversionDummy(DummyEvent): |
558 | def render(self, graph, layer, prev_events): | 620 | def render(self, graph, layer, prev_events, selectable=False): |
559 | if self.corresp_start_event in prev_events: | 621 | if self.corresp_start_event in prev_events: |
560 | return # we have already been rendered | 622 | return # we have already been rendered |
561 | self.corresp_start_event.render(graph, layer, prev_events) | 623 | self.corresp_start_event.render(graph, layer, prev_events, selectable) |
562 | 624 | ||
563 | class IsRunningDummy(DummyEvent): | 625 | class IsRunningDummy(DummyEvent): |
564 | def render(self, graph, layer, prev_events): | 626 | def render(self, graph, layer, prev_events, selectable=False): |
565 | if self.corresp_start_event in prev_events: | 627 | if self.corresp_start_event in prev_events: |
566 | return # we have already been rendered | 628 | return # we have already been rendered |
567 | self.corresp_start_event.render(graph, layer, prev_events) | 629 | self.corresp_start_event.render(graph, layer, prev_events, selectable) |
568 | 630 | ||
569 | EVENT_LIST = {SuspendEvent : None, ResumeEvent : None, CompleteEvent : None, SwitchAwayEvent : None, | 631 | EVENT_LIST = {SuspendEvent : None, ResumeEvent : None, CompleteEvent : None, |
570 | SwitchToEvent : None, ReleaseEvent : None, DeadlineEvent : None, IsRunningDummy : None, | 632 | SwitchAwayEvent : None, SwitchToEvent : None, ReleaseEvent : None, |
571 | InversionStartEvent : None, InversionEndEvent : None, InversionDummy : None} | 633 | DeadlineEvent : None, IsRunningDummy : None, |
634 | InversionStartEvent : None, InversionEndEvent : None, | ||
635 | InversionDummy : None} | ||