summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2011-10-11 17:55:39 -0400
committerJonathan Herman <hermanjl@cs.unc.edu>2011-10-11 17:55:39 -0400
commit96ad9cc863138f1de7245a5c1306bf66d2672514 (patch)
treefcbc618b9a05ae5eb0cf493ded397a7191a7f4bf
parentfbe4034d70e09080225d9570a74437c6b94173ad (diff)
Add st_show2 bin
-rw-r--r--src/showst2.cpp391
1 files changed, 391 insertions, 0 deletions
diff --git a/src/showst2.cpp b/src/showst2.cpp
new file mode 100644
index 0000000..e43a589
--- /dev/null
+++ b/src/showst2.cpp
@@ -0,0 +1,391 @@
1#include <iostream>
2#include <sstream>
3#include <fstream>
4#include <set>
5#include <vector>
6#include <map>
7
8#include <blitz/array.h>
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <unistd.h>
13
14extern "C"
15{
16#include "load.h"
17#include "sched_trace.h"
18#include "eheap.h"
19}
20
21using namespace std;
22using namespace blitz;
23
24double SCALE = 1000000.0; // ms
25//double SCALE = 1000.0; // us
26
27static void usage(const char *str)
28{
29 fprintf(stderr,
30 "\n USAGE\n"
31 "\n"
32 " st_show [opts] <file.st>+\n"
33 "\n"
34 " OPTIONS\n"
35 " -r -- find task system release and exit\n"
36 " -f -- use first non-zero event as system release\n"
37 " if no system release event is found\n"
38 " -c -- display a count of the number of events\n"
39 "\n\n"
40 );
41 fprintf(stderr, "Aborted: %s\n", str);
42 exit(1);
43}
44
45struct Job
46{
47 u32 jid;
48
49 mutable u32 actual_exe;
50 mutable u32 estimated_exe;
51 mutable s32 accum_err;
52
53 mutable u64 release;
54 mutable u64 deadline;
55 mutable u64 completion;
56
57 bool operator<(const Job& rhs) const
58 {
59 return(jid < rhs.jid);
60 }
61};
62
63struct Task
64{
65 u16 pid;
66
67 mutable u32 wcet;
68 mutable u32 period;
69 mutable u8 level;
70 mutable u8 partition;
71
72
73 bool operator<(const Task& rhs) const
74 {
75 return (pid < rhs.pid);
76 }
77};
78
79map<Task, set<Job> > traceData;
80
81template <class T>
82double stddev(const T& arr)
83{
84 double stddev;
85
86 if(arr.size() > 1)
87 {
88 double avg = blitz::mean(arr);
89
90 blitz::Array<double, 1> devs(arr.size());
91 devs = arr - avg;
92 devs *= devs;
93 double devsum = blitz::sum(devs);
94 stddev = sqrt(devsum/(devs.size()-1));
95 }
96 else
97 {
98 stddev = 0.0;
99 }
100
101 return(stddev);
102}
103
104#define OPTSTR "rcf"
105
106int main(int argc, char** argv)
107{
108 unsigned int count;
109 struct heap *h;
110 struct heap_node *hn, *first = NULL;
111 u64 time;
112 struct st_event_record *rec;
113 int show_count = 0;
114 int opt;
115
116 while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
117 switch (opt) {
118 case 'c':
119 show_count = 1;
120 break;
121 case ':':
122 usage("Argument missing.");
123 break;
124 case '?':
125 default:
126 usage("Bad argument.");
127 break;
128 }
129 }
130
131 u64 starttime = 0;
132
133 h = load(argv + optind, argc - optind, &count);
134 if (!h)
135 return 1;
136 if (show_count)
137 printf("Loaded %u events.\n", count);
138 while ((hn = heap_take(earlier_event, h))) {
139
140 rec = (st_event_record*)heap_node_value(hn);
141
142 time = event_time(rec);
143 if (time != 0 && !first)
144 first = hn;
145 time /= 1000000; /* convert to milliseconds */
146
147 if(rec->hdr.type == ST_SYS_RELEASE && starttime == 0)
148 {
149 starttime = rec->data.sys_release.when;
150 }
151 else if(rec->hdr.type == ST_PARAM)
152 {
153 Task tsk;
154 tsk.pid = rec->hdr.pid;
155 tsk.level = 'A' + rec->data.param.level;
156 tsk.partition = '0' + rec->data.param.partition;
157 tsk.wcet = rec->data.param.wcet;
158 tsk.period = rec->data.param.period;
159
160 map<Task, set<Job> >::iterator iter = traceData.find(tsk);
161 if(iter == traceData.end())
162 {
163 traceData[tsk] = set<Job>();
164 }
165 else
166 {
167 iter->first.wcet = rec->data.param.wcet;
168 iter->first.period = rec->data.param.period;
169 }
170 }
171 else if(rec->hdr.type == ST_RELEASE)
172 {
173 Task srch;
174 srch.pid = rec->hdr.pid;
175
176 map<Task, set<Job> >::iterator iter = traceData.find(srch);
177
178 // force the task to be there.
179 if(iter == traceData.end())
180 {
181 traceData[srch] = set<Job>();
182 iter = traceData.find(srch);
183 iter->first.period = rec->data.release.release - rec->data.release.deadline;
184 }
185
186 if(iter != traceData.end())
187 {
188 Job jsrch;
189 jsrch.jid = rec->hdr.job;
190
191 set<Job>::iterator jter = iter->second.find(jsrch);
192 if(jter == iter->second.end())
193 {
194 jsrch.release = rec->data.release.release;
195 jsrch.deadline = rec->data.release.deadline;
196 jsrch.completion = 0;
197 jsrch.actual_exe = 0;
198 jsrch.estimated_exe = 0;
199 jsrch.accum_err = 0;
200 iter->second.insert(jsrch);
201 }
202 else
203 {
204 jter->release = rec->data.release.release;
205 jter->deadline = rec->data.release.deadline;
206 }
207 }
208 else
209 {
210 cerr<<"Could not match release to task."<<endl;
211 }
212 }
213 else if(rec->hdr.type == ST_COMPLETION)
214 {
215 Task srch;
216 srch.pid = rec->hdr.pid;
217
218 map<Task, set<Job> >::iterator iter = traceData.find(srch);
219
220 // force the task to be there.
221 if(iter == traceData.end())
222 {
223 traceData[srch] = set<Job>();
224 iter = traceData.find(srch);
225 iter->first.period = 0;
226 }
227
228 if(iter != traceData.end())
229 {
230 Job jsrch;
231 jsrch.jid = rec->hdr.job;
232 set<Job>::iterator j = iter->second.find(jsrch);
233
234
235 if(j == iter->second.end())
236 {
237 jsrch.release = 0;
238 jsrch.deadline = 0;
239 jsrch.actual_exe = 0;
240 jsrch.estimated_exe = 0;
241 jsrch.accum_err = 0;
242 iter->second.insert(jsrch);
243 j = iter->second.find(jsrch);
244 }
245
246 if(j != iter->second.end())
247 {
248 j->completion = rec->data.completion.when;
249 }
250 else
251 {
252 cerr<<"Could not find the job to complete."<<endl;
253 }
254 }
255 else
256 {
257 cerr<<"Could not find the task for which has a job to complete."<<endl;
258 }
259 }
260 }
261
262 // data loaded. discard unfinished jobs. and first and last.
263 for(map<Task, set<Job> >::iterator tsk(traceData.begin()), tskEnd(traceData.end());
264 tsk != tskEnd;
265 ++tsk)
266 {
267 if(!tsk->second.empty())
268 {
269 tsk->second.erase(tsk->second.begin());
270 }
271 if(!tsk->second.empty())
272 {
273 set<Job>::iterator last(tsk->second.end());
274 --last;
275 tsk->second.erase(last);
276 }
277
278 for(set<Job>::iterator job(tsk->second.begin()), jobEnd(tsk->second.end());
279 job != jobEnd;
280 )
281 {
282 if(job->completion == 0 || job->release == 0 || job->deadline == 0)
283 {
284 set<Job>::iterator temp(job);
285 ++job;
286 tsk->second.erase(temp);
287 }
288 else
289 {
290 ++job;
291 }
292 }
293 }
294
295
296 ofstream outs;
297 outs.open("summary.csv");
298 outs<<"level, part, period, wcet, jobs, tard-avg, " <<
299 "tard-max, misses" << endl;
300
301 // print stats.
302 for(map<Task, set<Job> >::iterator tsk(traceData.begin()), tskEnd(traceData.end());
303 tsk != tskEnd;
304 ++tsk)
305 {
306 size_t sz = tsk->second.size();
307 Array<double, 1> releases(sz);
308 Array<double, 1> completions(sz);
309 Array<double, 1> deadlines(sz);
310
311 Array<double, 1> actual_exes(sz);
312 Array<double, 1> est_exes(sz);
313 Array<double, 1> accum_errs(sz);
314
315 int i = 0;
316 for(set<Job>::iterator job(tsk->second.begin()),
317 jobEnd(tsk->second.end());
318 job != jobEnd;
319 ++job, ++i)
320 {
321 releases(i) = (double)job->release;
322 completions(i) = (double)job->completion;
323 deadlines(i) = (double)job->deadline;
324
325 actual_exes(i) = (double)job->actual_exe;
326 est_exes(i) = (double)job->estimated_exe;
327 accum_errs(i) = (double)job->accum_err;
328 }
329
330 Array<double, 1> rt(sz);
331 Array<double, 1> tardy(sz);
332 Array<double, 1> delta_exe(sz);
333 Array<double, 1> misses(sz);
334
335 rt = completions - releases;
336 tardy = where(completions > deadlines, completions - deadlines, 0.0);
337 delta_exe = actual_exes - est_exes;
338 misses = where(completions > deadlines, 1, 0);
339 misses = blitz::sum(misses);
340
341 // done computing data. dump stuff to files.
342
343 // tardiness growth and estimates
344 stringstream filename;
345 double per = ((int)(roundf(tsk->first.period/10000.0)))/100.0;
346 double exe = ((int)(roundf(tsk->first.wcet/10000.0)))/100.0;
347 filename<<"e"<<exe<<"_p"<<per<<"_pid"<<tsk->first.pid;
348 if(stddev(actual_exes)/SCALE > 0.4)
349 {
350 filename<<"+";
351 }
352 filename<<".csv";
353
354 ofstream tardGrowth;
355 tardGrowth.open(filename.str().c_str());
356 tardGrowth<<"#time, tardiness, actual_exe, est_exe, delta_exe, accum_err"<<endl;
357 for(i = 0; i < (int)sz; ++i)
358 {
359 tardGrowth<<(completions(i)-starttime)/SCALE<<", "
360 <<tardy(i)/SCALE<<", "
361 <<actual_exes(i)/SCALE<<", "
362 <<est_exes(i)/SCALE<<", "
363 <<delta_exe(i)/SCALE<<", "
364 <<accum_errs(i)/SCALE<<endl;
365 }
366 tardGrowth.close();
367
368 // task stats
369 outs<<tsk->first.level<<", "
370 <<tsk->first.partition << ", "
371 <<tsk->first.period/SCALE<<", " // id
372 <<tsk->first.wcet/SCALE<<", " // id
373 <<sz<<", "
374 <<blitz::max(tardy)/SCALE<<", "
375 <<blitz::mean(tardy)/SCALE<<", "
376 <<blitz::sum(misses)<<endl;
377 }
378 outs.close();
379
380 return 0;
381}
382
383
384
385
386
387
388
389
390
391