aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern Brandenburg <bbb@mpi-sws.org>2016-03-22 15:53:55 -0400
committerBjoern Brandenburg <bbb@mpi-sws.org>2016-03-22 16:00:36 -0400
commit27474dfff59e40e1abf33e0b5dfe7a16dc73f4b1 (patch)
treeead56b3783117e666d008498120f8de7f6627bfe
parent17fedde91157d9e57a3c98c00c11ca03b0afcc78 (diff)
add st-draw: a pycairo based drawing tool for st_trace schedules
-rw-r--r--.gitignore3
-rw-r--r--sched_trace/__init__.py202
-rw-r--r--sched_trace/draw.py231
-rw-r--r--sched_trace/file.py58
-rw-r--r--sched_trace/format.py118
-rwxr-xr-xst-draw142
6 files changed, 754 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 2f993ac..8cdbb63 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,9 @@
1.sconsign.dblite 1.sconsign.dblite
2*.o 2*.o
3*.d 3*.d
4*.pyc
5*.pdf
6*.bin
4~* 7~*
5*~ 8*~
6ftcat 9ftcat
diff --git a/sched_trace/__init__.py b/sched_trace/__init__.py
new file mode 100644
index 0000000..5db2c2d
--- /dev/null
+++ b/sched_trace/__init__.py
@@ -0,0 +1,202 @@
1from __future__ import division
2
3from collections import defaultdict
4from itertools import imap
5
6import heapq
7
8from .format import event, EVENTS_WITHOUT_TIMESTAMP, EVENTS
9from .file import SchedTraceFile
10
11def event_id(unpacked_record):
12 "Given a tuple from format.unpack(), return the ID of the event"
13 return unpacked_record[0]
14
15def event_cpu(unpacked_record):
16 "Given a tuple from format.unpack(), return the CPU that recorded the event"
17 return unpacked_record[1]
18
19def event_pid(unpacked_record):
20 "Given a tuple from format.unpack(), return the process ID of the event"
21 return unpacked_record[2]
22
23def event_job_id(unpacked_record):
24 "Given a tuple from format.unpack(), return the job ID of the event"
25 return unpacked_record[3]
26
27def event_name(unpacked_record):
28 "Given a tuple from format.unpack(), return the name of the event"
29 # first element of tuple from format.unpack() is event type
30 return event(unpacked_record[0])
31
32def event_time(unpacked_record):
33 "Given a tuple from format.unpack(), return the time of the event"
34 if unpacked_record[0] in EVENTS_WITHOUT_TIMESTAMP:
35 return 0
36 else:
37 return unpacked_record[4]
38
39def lookup_ids(events):
40 wanted = set()
41 for e in events:
42 if type(e) == int:
43 # directly add numeric IDs
44 wanted.add(e)
45 else:
46 # translate strings
47 wanted.add(EVENTS[e])
48 return wanted
49
50
51def cached(trace_attr):
52 cached_val = []
53 def check_cache(*args, **kargs):
54 if not cached_val:
55 cached_val.append(trace_attr(*args, **kargs))
56 return cached_val[0]
57 return check_cache
58
59class SchedTrace(object):
60 def __init__(self, trace_files):
61 self.traces = [SchedTraceFile(f) for f in trace_files]
62
63 self._names = None
64 self._wcets = None
65 self._periods = None
66 self._phases = None
67 self._partitions = None
68 self._sys_rels = None
69
70 def __len__(self):
71 return sum((len(t) for t in self.traces))
72
73 def __iter__(self):
74 for t in self.traces:
75 for rec in t:
76 yield rec
77
78 def events_of_type(self, *events):
79 wanted = lookup_ids(events)
80 for t in self.traces:
81 for rec in t.events_of_type(wanted):
82 yield rec
83
84 def events_of_type_chrono(self, *events):
85 wanted = lookup_ids(events)
86
87 def by_event_time(rec):
88 return (event_time(rec), rec)
89
90 trace_iters = [imap(by_event_time, t.events_of_type(wanted))
91 for t in self.traces]
92
93 for (when, rec) in heapq.merge(*trace_iters):
94 yield rec
95
96 def events_in_range_of_type(self, start=0, end=0, *events, **kargs):
97 if 'sorted' in kargs and kargs['sorted']:
98 all = self.events_of_type_chrono(*events)
99 else:
100 all = self.events_of_type(*events)
101
102 for rec in all:
103 if start <= event_time(rec) <= end:
104 yield rec
105
106 def active_in_interval(self, start=0, end=0):
107 tasks = set()
108 cores = set()
109 for rec in self.events_of_type('ST_SWITCH_TO', 'ST_SWITCH_AWAY', 'ST_RELEASE'):
110 if start <= event_time(rec) <= end:
111 tasks.add(event_pid(rec))
112 cores.add(event_cpu(rec))
113 return tasks, cores
114
115 def scheduling_intervals(self):
116 for t in self.traces:
117 for interval in t.scheduling_intervals():
118 yield interval
119
120 def scheduling_intervals_in_range(self, start=0, end=0):
121 for t in self.traces:
122 for (to, away) in t.scheduling_intervals():
123 if not (end < event_time(to) or event_time(away) < start):
124 yield (to, away)
125
126 def identify_tasks(self):
127 self._names = defaultdict(str)
128 self._wcets = defaultdict(int)
129 self._periods = defaultdict(int)
130 self._phases = defaultdict(int)
131 self._partitions = defaultdict(int)
132 param_id = EVENTS['ST_PARAM']
133 name_id = EVENTS['ST_NAME']
134 for rec in self.events_of_type(param_id, name_id):
135 pid = rec[2]
136 if rec[0] == param_id:
137 wcet, period, phase, partition = rec[-4:]
138 self._wcets[pid] = wcet
139 self._periods[pid] = period
140 self._phases[pid] = phase
141 self._partitions[pid] = partition
142 elif rec[0] == name_id:
143 self._names[pid] = rec[-1]
144
145 @property
146 def task_wcets(self):
147 if self._wcets is None:
148 self.identify_tasks()
149 return self._wcets
150
151 @property
152 def task_periods(self):
153 if self._periods is None:
154 self.identify_tasks()
155 return self._periods
156
157 @property
158 def task_phases(self):
159 if self._phases is None:
160 self.identify_tasks()
161 return self._phases
162
163 @property
164 def task_partitions(self):
165 if self._partitions is None:
166 self.identify_tasks()
167 return self._partitions
168
169 @property
170 def task_names(self):
171 if self._names is None:
172 self.identify_tasks()
173 return self._names
174
175 @property
176 @cached
177 def system_releases(self):
178 return [rec[-1] for rec in self.events_of_type('ST_SYS_RELEASE')]
179
180 @property
181 @cached
182 def earliest_event_time(self):
183 earliest = None
184 for t in self.traces:
185 for rec in t:
186 if event_time(rec) > 0:
187 if earliest is None or event_time(rec) < earliest:
188 earliest = event_time(rec)
189 break
190 return earliest
191
192 @property
193 @cached
194 def latest_event_time(self):
195 latest = None
196 for t in self.traces: