aboutsummaryrefslogtreecommitdiffstats
path: root/rt-plot-task.c
diff options
context:
space:
mode:
Diffstat (limited to 'rt-plot-task.c')
-rw-r--r--rt-plot-task.c438
1 files changed, 273 insertions, 165 deletions
diff --git a/rt-plot-task.c b/rt-plot-task.c
index f28b7b1..9e8ffe7 100644
--- a/rt-plot-task.c
+++ b/rt-plot-task.c
@@ -2,8 +2,9 @@
2#include "trace-filter.h" 2#include "trace-filter.h"
3 3
4#define LLABEL 30 4#define LLABEL 30
5#define SEARCH_PERIODS 3
5 6
6#define DEBUG_LEVEL 4 7#define DEBUG_LEVEL 3
7#if DEBUG_LEVEL > 0 8#if DEBUG_LEVEL > 0
8#define dprintf(l, x...) \ 9#define dprintf(l, x...) \
9 do { \ 10 do { \
@@ -14,35 +15,87 @@
14#define dprintf(l, x...) do { if (0) printf(x); } while (0) 15#define dprintf(l, x...) do { if (0) printf(x); } while (0)
15#endif 16#endif
16 17
18/*
19 * Return 1 if @record is relevant to @match_pid.
20 */
17static gboolean record_matches_pid(struct graph_info *ginfo, 21static gboolean record_matches_pid(struct graph_info *ginfo,
18 struct record *record, 22 struct record *record,
19 int match_pid) 23 int match_pid)
20{ 24{
21 gint dint, pid = 0, match; 25 gint dint, pid = 0, match;
22 unsigned long long dull; 26 unsigned long long dull;
23 struct rt_graph_info *rtg_info = &ginfo->rtinfo; 27 struct rt_graph_info *rtg_info = &ginfo->rtg_info;
24 28
25 /* Must use check_* in case record has not been found yet, 29 /* Must use check_* in case record has not been found yet,
26 * this macro was the best of many terrible options 30 * this macro was the best of many terrible options.
27 */ 31 */
28#define MARGS rtg_info, ginfo->pevent, record, &pid 32#define ARG rtg_info, ginfo->pevent, record, &pid
29 match = rt_graph_check_switch_to(MARGS, &dint, &dull) || 33 match = rt_graph_check_switch_to(ARG, &dint, &dull) ||
30 rt_graph_check_switch_away(MARGS, &dint, &dull) || 34 rt_graph_check_switch_away(ARG, &dint, &dull) ||
31 rt_graph_check_task_release(MARGS, &dint, &dull, &dull) || 35 rt_graph_check_task_release(ARG, &dint, &dull, &dull) ||
32 rt_graph_check_task_completion(MARGS, &dint, &dull) || 36 rt_graph_check_task_completion(ARG, &dint, &dull) ||
33 rt_graph_check_task_block(MARGS, &dull) || 37 rt_graph_check_task_block(ARG, &dull) ||
34 rt_graph_check_task_resume(MARGS, &dull) || 38 rt_graph_check_task_resume(ARG, &dull) ||
35 rt_graph_check_any(MARGS, &dint, &dull); 39 rt_graph_check_any(ARG, &dint, &dull);
36#undef MARGS 40#undef ARG
37 return pid == match_pid; 41 return pid == match_pid;
38} 42}
39 43
44/*
45 * Return the first record after @time (within a range) which draws a box.
46 */
47static struct record*
48next_box_record(struct graph_info *ginfo, struct rt_task_info *rtt_info,
49 unsigned long long time, int *out_eid)
50{
51 struct record *record = NULL, *ret = NULL;
52 struct pevent *pevent;
53 struct rt_graph_info *rtg_info = &ginfo->rtg_info;
54 unsigned long long dull, max_ts;
55 int match, pid, eid, dint, cpu;
56
57 *out_eid = 0;
58 pevent = ginfo->pevent;
59 max_ts = ginfo->view_end_time +
60 SEARCH_PERIODS * rtg_info->max_period;
61 set_cpus_to_rts(ginfo, time);
62 do {
63 free_record(record);
64 record = tracecmd_read_next_data(ginfo->handle, &cpu);
65 if (!record || get_rts(ginfo, record) > max_ts) {
66 free_record(record);
67 goto out;
68 }
69
70 /* Sorry mother */
71#define ARG rtg_info, pevent, record, &pid
72 match = rt_graph_check_switch_to(ARG, &dint, &dull) ||
73 rt_graph_check_switch_away(ARG, &dint, &dull) ||
74 rt_graph_check_task_block(ARG, &dull) ||
75 rt_graph_check_task_resume(ARG, &dull);
76#undef ARG
77 eid = (match) ? pevent_data_type(pevent, record) : 0;
78
79 if (eid && pid == rtt_info->pid) {
80 ret = record;
81 *out_eid = eid;
82 goto out;
83 }
84 } while (get_rts(ginfo, record) < max_ts);
85 out:
86 return ret;
87}
88
89/*
90 * Return first relevant record after @time.
91 * @display: If set, only considers records which are plotted in some way
92 */
40static struct record* 93static struct record*
41__find_record(struct graph_info *ginfo, gint pid, guint64 time, int display) 94__find_record(struct graph_info *ginfo, gint pid, guint64 time, int display)
42{ 95{
43 int next_cpu, match, eid, is_sa = 0; 96 int next_cpu, match, eid, is_sa = 0;
44 struct record *record = NULL; 97 struct record *record = NULL;
45 struct rt_graph_info *rtg_info = &ginfo->rtinfo; 98 struct rt_graph_info *rtg_info = &ginfo->rtg_info;
46 99
47 set_cpus_to_rts(ginfo, time); 100 set_cpus_to_rts(ginfo, time);
48 do { 101 do {
@@ -73,10 +126,11 @@ find_display_record(struct graph_info *ginfo, gint pid, guint64 time)
73} 126}
74 127
75/* 128/*
76 * Update current job in @rtt_info, ensuring monotonic increase 129 * Update current job in @rtt_info, ensuring monotonic increase.
77 */ 130 */
78static int update_job(struct rt_task_info *rtt_info, int job) 131static int update_job(struct rt_task_info *rtt_info, int job)
79{ 132{
133 rtt_info->fresh = FALSE;
80 if (job < rtt_info->last_job) { 134 if (job < rtt_info->last_job) {
81 printf("Inconsistent job state for %d:%d -> %d\n", 135 printf("Inconsistent job state for %d:%d -> %d\n",
82 rtt_info->pid, rtt_info->last_job, job); 136 rtt_info->pid, rtt_info->last_job, job);
@@ -89,6 +143,115 @@ static int update_job(struct rt_task_info *rtt_info, int job)
89 return 1; 143 return 1;
90} 144}
91 145
146
147
148/*
149 * Find the information for the last release of @rtt_info on @cpu before @time.
150 * @min_ts: the minimum time stamp to parse
151 *
152 * Returns release record and @out_job, @out_release, and @out_deadline if a
153 * release was found after @mints matching @time.
154 */
155static struct record*
156get_previous_release(struct graph_info *ginfo, struct rt_task_info *rtt_info,
157 int cpu,
158 unsigned long long min_ts, unsigned long long time,
159 int *out_job,
160 unsigned long long *out_release,
161 unsigned long long *out_deadline)
162{
163 int pid, job, match;
164 unsigned long long release, deadline;
165 struct record *last_record, *record, *ret = NULL;
166 struct rt_graph_info *rtg_info = &ginfo->rtg_info;
167
168 last_record = tracecmd_peek_data(ginfo->handle, cpu);
169 *out_job = *out_release = *out_deadline = 0;
170 if (!last_record)
171 return NULL;
172 last_record->ref_count++;
173
174 while ((record = tracecmd_read_prev(ginfo->handle, last_record))) {
175 if (record->ts < min_ts) {
176 free_record(record);
177 goto out;
178 }
179 match = rt_graph_check_task_release(rtg_info, ginfo->pevent,
180 record, &pid, &job,
181 &release, &deadline);
182 free_record(last_record);
183 last_record = record;
184 if (match && (pid == rtt_info->pid) && release <= time) {
185 ret = record;
186 last_record = NULL;
187 *out_job = job;
188 *out_release = release;
189 *out_deadline = deadline;
190 break;
191 }
192 };
193 out:
194 free_record(last_record);
195 return ret;
196}
197
198/*
199 * Return information for @time, returns @job, @release, @deadline, and @record.
200 * @job: Job number at this time
201 * @release: Job's release time
202 * @deadline: Job's deadline
203 * @record: Matching record
204 */
205static int get_time_info(struct graph_info *ginfo,
206 struct rt_task_info *rtt_info,
207 unsigned long long time,
208 int *out_job,
209 unsigned long long *out_release,
210 unsigned long long *out_deadline,
211 struct record **out_record)
212
213{
214 int cpu, job;
215 unsigned long long release, deadline, min_ts;
216 struct record *record;
217 struct offset_cache *offsets;
218 struct rt_graph_info *rtg_info = &ginfo->rtg_info;
219
220 /* Seek CPUs to first record after this time */
221 *out_job = *out_release = *out_deadline = 0;
222 *out_record = find_record(ginfo, rtt_info->pid, time);
223 if (!*out_record)
224 return 0;
225
226 /* This is not necessarily correct for sporadic, but will do for now */
227 if (time < rtt_info->first_rels[2]) {
228 job = (time >= rtt_info->first_rels[1]) ? 2 : 1;
229 *out_job = job;
230 *out_release = rtt_info->first_rels[job - 1];
231 *out_deadline = rtt_info->first_rels[job];
232 goto out;
233 }
234
235 min_ts = time - SEARCH_PERIODS * rtg_info->max_period;
236 *out_job = *out_release = *out_deadline = 0;
237
238 offsets = save_offsets(ginfo);
239 for (cpu = 0; cpu < ginfo->cpus; cpu++) {
240 record = get_previous_release(ginfo, rtt_info, cpu, min_ts,
241 time, &job, &release, &deadline);
242 if (record && record->ts > min_ts) {
243 *out_job = job;
244 *out_release = release;
245 *out_deadline = deadline;
246 min_ts = record->ts;
247 }
248 free_record(record);
249 }
250 restore_offsets(ginfo, offsets);
251 out:
252 return 1;
253}
254
92static int try_param(struct graph_info *ginfo, struct rt_task_info *rtt_info, 255static int try_param(struct graph_info *ginfo, struct rt_task_info *rtt_info,
93 struct record *record, struct plot_info *info) 256 struct record *record, struct plot_info *info)
94{ 257{
@@ -99,7 +262,7 @@ static int try_param(struct graph_info *ginfo, struct rt_task_info *rtt_info,
99 if (rtt_info->params_found) 262 if (rtt_info->params_found)
100 goto out; 263 goto out;
101 264
102 match = rt_graph_check_task_param(&ginfo->rtinfo, ginfo->pevent, 265 match = rt_graph_check_task_param(&ginfo->rtg_info, ginfo->pevent,
103 record, &pid, &wcet, &period); 266 record, &pid, &wcet, &period);
104 if (match && pid == rtt_info->pid) { 267 if (match && pid == rtt_info->pid) {
105 update_job(rtt_info, 0); 268 update_job(rtt_info, 0);
@@ -108,6 +271,8 @@ static int try_param(struct graph_info *ginfo, struct rt_task_info *rtt_info,
108 rtt_info->params_found = TRUE; 271 rtt_info->params_found = TRUE;
109 ret = 1; 272 ret = 1;
110 rtt_info->first_rels[0] = get_rts(ginfo, record); 273 rtt_info->first_rels[0] = get_rts(ginfo, record);
274 dprintf(3, "Params for %d (%llu, %llu)\n on %d",
275 pid, wcet, period, record->cpu);
111 } 276 }
112 out: 277 out:
113 return ret; 278 return ret;
@@ -120,7 +285,7 @@ static int try_release(struct graph_info *ginfo, struct rt_task_info *rtt_info,
120 int pid, job, match, ret = 0; 285 int pid, job, match, ret = 0;
121 unsigned long long release, deadline; 286 unsigned long long release, deadline;
122 287
123 match = rt_graph_check_task_release(&ginfo->rtinfo, ginfo->pevent, 288 match = rt_graph_check_task_release(&ginfo->rtg_info, ginfo->pevent,
124 record, &pid, &job, 289 record, &pid, &job,
125 &release, &deadline); 290 &release, &deadline);
126 if (match && pid == rtt_info->pid) { 291 if (match && pid == rtt_info->pid) {
@@ -136,6 +301,9 @@ static int try_release(struct graph_info *ginfo, struct rt_task_info *rtt_info,
136 if (job <= 3) 301 if (job <= 3)
137 rtt_info->first_rels[job - 1] = release; 302 rtt_info->first_rels[job - 1] = release;
138 303
304 dprintf(3, "Release for %d:%d on %d, rel: %llu, dead: %llu\n",
305 pid, job, record->cpu, release, deadline);
306
139 ret = 1; 307 ret = 1;
140 } 308 }
141 return ret; 309 return ret;
@@ -148,13 +316,15 @@ static int try_completion(struct graph_info *ginfo,
148 int pid, job, match, ret = 0; 316 int pid, job, match, ret = 0;
149 unsigned long long ts; 317 unsigned long long ts;
150 318
151 match = rt_graph_check_task_completion(&ginfo->rtinfo, ginfo->pevent, 319 match = rt_graph_check_task_completion(&ginfo->rtg_info, ginfo->pevent,
152 record, &pid, &job, &ts); 320 record, &pid, &job, &ts);
153 if (match && pid == rtt_info->pid) { 321 if (match && pid == rtt_info->pid) {
154 update_job(rtt_info, job); 322 update_job(rtt_info, job);
155 info->completion = TRUE; 323 info->completion = TRUE;
156 info->ctime = ts; 324 info->ctime = ts;
157 info->clabel = rtt_info->label; 325 info->clabel = rtt_info->label;
326 dprintf(3, "Completion for %d:%d on %d at %llu\n",
327 pid, job, record->cpu, ts);
158 ret = 1; 328 ret = 1;
159 } 329 }
160 return ret; 330 return ret;
@@ -166,10 +336,14 @@ static int try_block(struct graph_info *ginfo, struct rt_task_info *rtt_info,
166 int pid, match, ret = 0; 336 int pid, match, ret = 0;
167 unsigned long long ts; 337 unsigned long long ts;
168 338
169 match = rt_graph_check_task_block(&ginfo->rtinfo, ginfo->pevent, 339 match = rt_graph_check_task_block(&ginfo->rtg_info, ginfo->pevent,
170 record, &pid, &ts); 340 record, &pid, &ts);
171 if (match && pid == rtt_info->pid) { 341 if (match && pid == rtt_info->pid) {
342 rtt_info->fresh = FALSE;
172 rtt_info->block_time = ts; 343 rtt_info->block_time = ts;
344 rtt_info->block_cpu = NO_CPU;
345 dprintf(3, "Resume for %d on %d at %llu\n",
346 pid, record->cpu, ts);
173 ret = 1; 347 ret = 1;
174 } 348 }
175 return ret; 349 return ret;
@@ -181,7 +355,7 @@ static int try_resume(struct graph_info *ginfo, struct rt_task_info *rtt_info,
181 int pid, match, ret = 0; 355 int pid, match, ret = 0;
182 unsigned long long ts; 356 unsigned long long ts;
183 357
184 match = rt_graph_check_task_resume(&ginfo->rtinfo, ginfo->pevent, 358 match = rt_graph_check_task_resume(&ginfo->rtg_info, ginfo->pevent,
185 record, &pid, &ts); 359 record, &pid, &ts);
186 if (match && pid == rtt_info->pid) { 360 if (match && pid == rtt_info->pid) {
187 /* info->box = TRUE; */ 361 /* info->box = TRUE; */
@@ -190,22 +364,26 @@ static int try_resume(struct graph_info *ginfo, struct rt_task_info *rtt_info,
190 /* info->bthin = TRUE; */ 364 /* info->bthin = TRUE; */
191 /* info->bstart = rtt_info->block_time; */ 365 /* info->bstart = rtt_info->block_time; */
192 /* info->bend = ts; */ 366 /* info->bend = ts; */
367 rtt_info->fresh = FALSE;
193 368
194 rtt_info->block_time = 0ULL; 369 rtt_info->block_time = 0ULL;
370 rtt_info->block_cpu = NO_CPU;
371 dprintf(3, "Resume for %d on %d at %llu\n",
372 pid, record->cpu, ts);
195 373
196 ret = 1; 374 ret = 1;
197 } 375 }
198 return ret; 376 return ret;
199} 377}
200 378
201static unsigned long long 379static int
202try_switch_away(struct graph_info *ginfo, struct rt_task_info *rtt_info, 380try_switch_away(struct graph_info *ginfo, struct rt_task_info *rtt_info,
203 struct record *record, struct plot_info *info) 381 struct record *record, struct plot_info *info)
204{ 382{
205 int job, pid, match, ret = 0; 383 int job, pid, match, ret = 0;
206 unsigned long long ts; 384 unsigned long long ts;
207 385
208 match = rt_graph_check_switch_away(&ginfo->rtinfo, ginfo->pevent, 386 match = rt_graph_check_switch_away(&ginfo->rtg_info, ginfo->pevent,
209 record, &pid, &job, &ts); 387 record, &pid, &job, &ts);
210 if (match && pid == rtt_info->pid) { 388 if (match && pid == rtt_info->pid) {
211 update_job(rtt_info, job); 389 update_job(rtt_info, job);
@@ -213,18 +391,19 @@ try_switch_away(struct graph_info *ginfo, struct rt_task_info *rtt_info,
213 if (rtt_info->run_time && rtt_info->run_time < ts) { 391 if (rtt_info->run_time && rtt_info->run_time < ts) {
214 dprintf(3, "Box for %d:%d, %llu to %llu on CPU %d\n", 392 dprintf(3, "Box for %d:%d, %llu to %llu on CPU %d\n",
215 rtt_info->pid, rtt_info->last_job, 393 rtt_info->pid, rtt_info->last_job,
216 rtt_info->run_time, ts, rtt_info->last_cpu); 394 rtt_info->run_time, ts, record->cpu);
217 info->box = TRUE; 395 info->box = TRUE;
218 info->bcolor = hash_cpu(rtt_info->last_cpu); 396 info->bcolor = hash_cpu(record->cpu);
219 info->bfill = TRUE; 397 info->bfill = TRUE;
220 info->bstart = rtt_info->run_time; 398 info->bstart = rtt_info->run_time;
221 info->bend = ts; 399 info->bend = ts;
222 info->blabel = rtt_info->label; 400 info->blabel = rtt_info->label;
223 } 401 }
224 402
225 dprintf(3, "Switch away at %llu\n", ts); 403 dprintf(3, "Switch away for %d:%d on %d at %llu\n",
404 pid, job, record->cpu, ts);
226 rtt_info->run_time = 0ULL; 405 rtt_info->run_time = 0ULL;
227 rtt_info->last_cpu = -1; 406 rtt_info->run_cpu = NO_CPU;
228 407
229 ret = 1; 408 ret = 1;
230 } 409 }
@@ -237,18 +416,14 @@ static int try_switch_to(struct graph_info *ginfo, struct rt_task_info *rtt_info
237 int job, pid, match, ret = 0; 416 int job, pid, match, ret = 0;
238 unsigned long long ts; 417 unsigned long long ts;
239 418
240 match = rt_graph_check_switch_to(&ginfo->rtinfo, ginfo->pevent, 419 match = rt_graph_check_switch_to(&ginfo->rtg_info, ginfo->pevent,
241 record, &pid, &job, &ts); 420 record, &pid, &job, &ts);
242 if (match && pid == rtt_info->pid) { 421 if (match && pid == rtt_info->pid) {
243 update_job(rtt_info, job); 422 update_job(rtt_info, job);
244
245 rtt_info->run_time = ts; 423 rtt_info->run_time = ts;
246 rtt_info->last_cpu = record->cpu; 424 rtt_info->run_cpu = record->cpu;
247 425 dprintf(3, "Switch to for %d:%d on %d at %llu\n",
248 dprintf(3, "Switching to %d:%d at %llu on CPU %d\n", 426 pid, job, record->cpu, ts);
249 rtt_info->pid, rtt_info->last_job,
250 ts, rtt_info->last_cpu);
251
252 ret = 1; 427 ret = 1;
253 } 428 }
254 return ret; 429 return ret;
@@ -261,12 +436,12 @@ static int try_other(struct graph_info *ginfo, struct rt_task_info *rtt_info,
261 unsigned long long ts; 436 unsigned long long ts;
262 437
263 pid = rtt_info->pid; 438 pid = rtt_info->pid;
264 rt_graph_check_any(&ginfo->rtinfo, ginfo->pevent, record, 439 rt_graph_check_any(&ginfo->rtg_info, ginfo->pevent, record,
265 &epid, &eid, &ts); 440 &epid, &eid, &ts);
266 441
267 my_pid = (pid == epid); 442 my_pid = (pid == epid);
268 my_cpu = (rtt_info->run_time && record->cpu == rtt_info->last_cpu); 443 my_cpu = (rtt_info->run_time && record->cpu == rtt_info->run_cpu);
269 not_sa = (eid != ginfo->rtinfo.switch_away_id); 444 not_sa = (eid != ginfo->rtg_info.switch_away_id);
270 if (not_sa && (my_pid || my_cpu)) { 445 if (not_sa && (my_pid || my_cpu)) {
271 info->line = TRUE; 446 info->line = TRUE;
272 info->lcolor = hash_pid(record->cpu); 447 info->lcolor = hash_pid(record->cpu);
@@ -277,117 +452,42 @@ static int try_other(struct graph_info *ginfo, struct rt_task_info *rtt_info,
277 return ret; 452 return ret;
278} 453}
279 454
280/* 455static void do_plot_end(struct graph_info *ginfo, struct rt_task_info *rtt_info,
281 * Find the information for the last release of @rtt_info on @cpu before @time. 456 struct plot_info *info)
282 * @min_ts: the minimum time stamp to parse
283 *
284 * Returns release record and @out_job, @out_release, and @out_deadline if a
285 * release was found after @mints matching @time.
286 */
287static struct record*
288get_previous_release(struct graph_info *ginfo, struct rt_task_info *rtt_info,
289 int cpu,
290 unsigned long long min_ts, unsigned long long time,
291 int *out_job,
292 unsigned long long *out_release,
293 unsigned long long *out_deadline)
294{
295 int pid, job, match;
296 unsigned long long release, deadline;
297 struct record *last_record, *record, *ret = NULL;
298 struct rt_graph_info *rtg_info = &ginfo->rtinfo;
299
300 last_record = tracecmd_peek_data(ginfo->handle, cpu);
301 *out_job = *out_release = *out_deadline = 0;
302 if (!last_record)
303 return NULL;
304 last_record->ref_count++;
305
306 while ((record = tracecmd_read_prev(ginfo->handle, last_record))) {
307 if (record->ts < min_ts) {
308 free_record(record);
309 goto out;
310 }
311 match = rt_graph_check_task_release(rtg_info, ginfo->pevent,
312 record, &pid, &job,
313 &release, &deadline);
314 free_record(last_record);
315 last_record = record;
316 if (match && (pid == rtt_info->pid) && release <= time) {
317 ret = record;
318 last_record = NULL;
319 *out_job = job;
320 *out_release = release;
321 *out_deadline = deadline;
322 break;
323 }
324 };
325 out:
326 free_record(last_record);
327 return ret;
328}
329
330/*
331 * Return information for @time, returns @job, @release, @deadline, and @record.
332 * @job: Job number at this time
333 * @release: Job's release time
334 * @deadline: Job's deadline
335 * @record: Matching record
336 */
337static int get_time_info(struct graph_info *ginfo,
338 struct rt_task_info *rtt_info,
339 unsigned long long time,
340 int *out_job,
341 unsigned long long *out_release,
342 unsigned long long *out_deadline,
343 struct record **out_record)
344
345{ 457{
346 int cpu, job;
347 unsigned long long release, deadline, min_ts;
348 struct record *record; 458 struct record *record;
349 struct offset_cache *offsets; 459 struct rt_graph_info *rtg_info = &ginfo->rtg_info;
350 460 int eid;
351 /* Seek CPUs to first record after this time */
352 *out_job = *out_release = *out_deadline = 0;
353 *out_record = find_record(ginfo, rtt_info->pid, time);
354 if (!*out_record)
355 return 0;
356
357 /* This is not necessarily correct for sporadic, but will do for now */
358 if (time < rtt_info->first_rels[2]) {
359 job = (time >= rtt_info->first_rels[1]) ? 2 : 1;
360 *out_job = job;
361 *out_release = rtt_info->first_rels[job - 1];
362 *out_deadline = rtt_info->first_rels[job];
363 goto out;
364 }
365
366 min_ts = time - 2*rtt_info->wcet;
367 *out_job = *out_release = *out_deadline = 0;
368 461
369 offsets = save_offsets(ginfo); 462 if (rtt_info->run_time && rtt_info->run_cpu != NO_CPU) {
370 for (cpu = 0; cpu < ginfo->cpus; cpu++) { 463 /* A box was started, finish it */
371 record = get_previous_release(ginfo, rtt_info, cpu, min_ts, 464 info->box = TRUE;
372 time, &job, &release, &deadline); 465 info->bcolor = hash_cpu(rtt_info->run_cpu);
373 if (record && record->ts > min_ts) { 466 info->bfill = TRUE;
374 *out_job = job; 467 info->bstart = rtt_info->run_time;
375 *out_release = release; 468 info->bend = ginfo->view_end_time;
376 *out_deadline = deadline; 469 info->blabel = rtt_info->label;
377 min_ts = record->ts; 470 } else if (rtt_info->block_time && rtt_info->block_cpu != NO_CPU) {
471 /* Blocking happened */
472 } else if (rtt_info->fresh) {
473 /* Nothing happened!*/
474 record = next_box_record(ginfo, rtt_info,
475 ginfo->view_end_time, &eid);
476
477 if (record) {
478 if (eid == rtg_info->switch_away_id) {
479 /* In a run */
480 info->box = TRUE;
481 info->bcolor = hash_cpu(record->cpu);
482 info->bfill = TRUE;
483 info->bstart = ginfo->view_start_time;
484 info->bend = ginfo->view_end_time;
485 } else if (eid == rtg_info->task_resume_id) {
486 /* In a block */
487 }
488 free_record(record);
378 } 489 }
379 free_record(record);
380 } 490 }
381 restore_offsets(ginfo, offsets);
382 out:
383 return 1;
384}
385
386static inline int in_res(struct graph_info *ginfo, unsigned long long time,
387 unsigned long target)
388{
389 return time > target - 2/ginfo->resolution &&
390 time < target + 2/ginfo->resolution;
391} 491}
392 492
393static int rt_task_plot_event(struct graph_info *ginfo, struct graph_plot *plot, 493static int rt_task_plot_event(struct graph_info *ginfo, struct graph_plot *plot,
@@ -396,15 +496,11 @@ static int rt_task_plot_event(struct graph_info *ginfo, struct graph_plot *plot,
396 struct rt_task_info *rtt_info = plot->private; 496 struct rt_task_info *rtt_info = plot->private;
397 int match; 497 int match;
398 498
499 dprintf(4,"%s\n", __FUNCTION__);
500
399 /* No more records, finish what we started */ 501 /* No more records, finish what we started */
400 if (!record) { 502 if (!record) {
401 if (rtt_info->last_cpu >= 0 && 503 do_plot_end(ginfo, rtt_info, info);
402 rtt_info->run_time) {
403 info->box = TRUE;
404 info->bstart = rtt_info->last_time;
405 info->bend = ginfo->view_end_time;
406 info->bcolor = hash_cpu(rtt_info->last_cpu);
407 }
408 return 0; 504 return 0;
409 } 505 }
410 506
@@ -417,11 +513,6 @@ static int rt_task_plot_event(struct graph_info *ginfo, struct graph_plot *plot,
417 try_resume(ginfo, rtt_info, record, info) || 513 try_resume(ginfo, rtt_info, record, info) ||
418 try_other(ginfo, rtt_info, record, info); 514 try_other(ginfo, rtt_info, record, info);
419 515
420 if (match) {
421 rtt_info->last_time = get_rts(ginfo, record);
422 rtt_info->last_cpu = record->cpu;
423 }
424
425 return match; 516 return match;
426} 517}
427 518
@@ -431,22 +522,26 @@ static void rt_task_plot_start(struct graph_info *ginfo, struct graph_plot *plot
431 int i; 522 int i;
432 struct rt_task_info *rtt_info = plot->private; 523 struct rt_task_info *rtt_info = plot->private;
433 524
525 dprintf(4,"%s\n", __FUNCTION__);
526
434 rtt_info->wcet = 0ULL; 527 rtt_info->wcet = 0ULL;
435 rtt_info->period = 0ULL; 528 rtt_info->period = 0ULL;
436 rtt_info->run_time = 0ULL; 529
437 rtt_info->block_time = 0ULL; 530 rtt_info->run_time = time;
438 rtt_info->last_cpu = -1; 531 rtt_info->block_time = time;
439 rtt_info->last_job = -1; 532 rtt_info->run_cpu = NO_CPU;
533 rtt_info->block_cpu = NO_CPU;
440 rtt_info->params_found = FALSE; 534 rtt_info->params_found = FALSE;
535 rtt_info->fresh = TRUE;
441 for (i = 0; i < 3; i++) 536 for (i = 0; i < 3; i++)
442 rtt_info->first_rels[i] = 0ULL; 537 rtt_info->first_rels[i] = 0ULL;
443 update_job(rtt_info, 0); 538 rtt_info->last_job = 0;
444} 539}
445 540
446static void rt_task_plot_destroy(struct graph_info *ginfo, struct graph_plot *plot) 541static void rt_task_plot_destroy(struct graph_info *ginfo, struct graph_plot *plot)
447{ 542{
448 struct rt_task_info *rtt_info = plot->private; 543 struct rt_task_info *rtt_info = plot->private;
449 printf("Destroying plot %d\n", rtt_info->pid); 544 dprintf(4,"%s\n", __FUNCTION__);
450 free(rtt_info->label); 545 free(rtt_info->label);
451 task_plot_destroy(ginfo, plot); 546 task_plot_destroy(ginfo, plot);
452} 547}
@@ -462,6 +557,8 @@ static int rt_task_plot_display_last_event(struct graph_info *ginfo,
462 struct offset_cache *offsets; 557 struct offset_cache *offsets;
463 struct rt_task_info *rtt_info = plot->private; 558 struct rt_task_info *rtt_info = plot->private;
464 559
560 dprintf(4,"%s\n", __FUNCTION__);
561
465 offsets = save_offsets(ginfo); 562 offsets = save_offsets(ginfo);
466 record = find_display_record(ginfo, rtt_info->pid, time); 563 record = find_display_record(ginfo, rtt_info->pid, time);
467 restore_offsets(ginfo, offsets); 564 restore_offsets(ginfo, offsets);
@@ -481,10 +578,17 @@ static int rt_task_plot_display_last_event(struct graph_info *ginfo,
481 return 1; 578 return 1;
482} 579}
483 580
581static inline int in_res(struct graph_info *ginfo, unsigned long long time,
582 unsigned long target)
583{
584 return time > target - 2/ginfo->resolution &&
585 time < target + 2/ginfo->resolution;
586}
587
484static int rt_task_plot_display_info(struct graph_info *ginfo, 588static int rt_task_plot_display_info(struct graph_info *ginfo,
485 struct graph_plot *plot, 589 struct graph_plot *plot,
486 struct trace_seq *s, 590 struct trace_seq *s,
487 unsigned long long time) 591 unsigned long long time)
488{ 592{
489 const char *comm; 593 const char *comm;
490 int pid, job, eid; 594 int pid, job, eid;
@@ -495,6 +599,8 @@ static int rt_task_plot_display_info(struct graph_info *ginfo,
495 struct rt_task_info *rtt_info = plot->private; 599 struct rt_task_info *rtt_info = plot->private;
496 struct offset_cache *offsets; 600 struct offset_cache *offsets;
497 601
602 dprintf(4,"%s\n", __FUNCTION__);
603
498 offsets = save_offsets(ginfo); 604 offsets = save_offsets(ginfo);
499 get_time_info(ginfo, rtt_info, time, 605 get_time_info(ginfo, rtt_info, time,
500 &job, &release, &deadline, &record); 606 &job, &release, &deadline, &record);
@@ -535,6 +641,8 @@ static int rt_task_plot_match_time(struct graph_info *ginfo,
535 struct rt_task_info *rtt_info = plot->private; 641 struct rt_task_info *rtt_info = plot->private;
536 int next_cpu, match, ret; 642 int next_cpu, match, ret;
537 643
644 dprintf(4,"%s\n", __FUNCTION__);
645
538 set_cpus_to_rts(ginfo, time); 646 set_cpus_to_rts(ginfo, time);
539 647
540 do { 648 do {
@@ -600,14 +708,14 @@ void rt_plot_task_plotted(struct graph_info *ginfo, gint **plotted)
600 708
601void rt_plot_task(struct graph_info *ginfo, int pid, int pos) 709void rt_plot_task(struct graph_info *ginfo, int pid, int pos)
602{ 710{
603 struct rt_graph_info *rtinfo = &ginfo->rtinfo; 711 struct rt_graph_info *rtg_info = &ginfo->rtg_info;
604 struct rt_task_info *rtt_info; 712 struct rt_task_info *rtt_info;
605 struct graph_plot *plot; 713 struct graph_plot *plot;
606 const char *comm; 714 const char *comm;
607 char *plot_label; 715 char *plot_label;
608 int len; 716 int len;
609 717
610 if (!find_task_list(rtinfo->tasks, pid)) 718 if (!find_task_list(rtg_info->tasks, pid))
611 die("Cannot create RT plot of non-RT task %d!\n", pid); 719 die("Cannot create RT plot of non-RT task %d!\n", pid);
612 720
613 rtt_info = malloc_or_die(sizeof(*rtt_info)); 721 rtt_info = malloc_or_die(sizeof(*rtt_info));