diff options
-rw-r--r-- | rt-graph.h | 2 | ||||
-rw-r--r-- | rt-plot-task.c | 37 | ||||
-rw-r--r-- | rt-plot.c | 53 | ||||
-rw-r--r-- | rt-plot.h | 6 |
4 files changed, 61 insertions, 37 deletions
@@ -10,7 +10,7 @@ | |||
10 | #include "rt-plot-container.h" | 10 | #include "rt-plot-container.h" |
11 | 11 | ||
12 | #define LLABEL 30 | 12 | #define LLABEL 30 |
13 | #define SEARCH_PERIODS 1 | 13 | #define SEARCH_PERIODS 5 |
14 | #define NO_CPU -1 | 14 | #define NO_CPU -1 |
15 | #define RT_TS_FIELD "__rt_ts" | 15 | #define RT_TS_FIELD "__rt_ts" |
16 | 16 | ||
diff --git a/rt-plot-task.c b/rt-plot-task.c index c72013f..56c3c28 100644 --- a/rt-plot-task.c +++ b/rt-plot-task.c | |||
@@ -3,7 +3,7 @@ | |||
3 | #include "trace-graph.h" | 3 | #include "trace-graph.h" |
4 | #include "trace-filter.h" | 4 | #include "trace-filter.h" |
5 | 5 | ||
6 | #define DEBUG_LEVEL 0 | 6 | #define DEBUG_LEVEL 1 |
7 | #if DEBUG_LEVEL > 0 | 7 | #if DEBUG_LEVEL > 0 |
8 | #define dprintf(l, x...) \ | 8 | #define dprintf(l, x...) \ |
9 | do { \ | 9 | do { \ |
@@ -75,6 +75,18 @@ static int update_job(struct rt_task_info *rtt_info, int job) | |||
75 | return 1; | 75 | return 1; |
76 | } | 76 | } |
77 | 77 | ||
78 | static int rt_task_plot_is_drawn(struct graph_info *ginfo, int eid) | ||
79 | { | ||
80 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
81 | |||
82 | return (eid == rtg_info->switch_away_id || | ||
83 | eid == rtg_info->switch_to_id || | ||
84 | eid == rtg_info->task_completion_id || | ||
85 | /* eid == rtg_info->task_block_id || */ | ||
86 | /* eid == rtg_info->task_resume_id || */ | ||
87 | eid == rtg_info->task_release_id); | ||
88 | } | ||
89 | |||
78 | /* | 90 | /* |
79 | * Get information about the given @time. | 91 | * Get information about the given @time. |
80 | * @out_job: Job number at this time | 92 | * @out_job: Job number at this time |
@@ -203,8 +215,8 @@ static int try_block(struct graph_info *ginfo, struct rt_task_info *rtt_info, | |||
203 | if (match && pid == rtt_info->pid) { | 215 | if (match && pid == rtt_info->pid) { |
204 | rtt_info->fresh = FALSE; | 216 | rtt_info->fresh = FALSE; |
205 | rtt_info->block_time = ts; | 217 | rtt_info->block_time = ts; |
206 | rtt_info->block_cpu = NO_CPU; | 218 | rtt_info->block_cpu = record->cpu; |
207 | dprintf(3, "Resume for %d on %d at %llu\n", | 219 | dprintf(3, "Block for %d on %d at %llu\n", |
208 | pid, record->cpu, ts); | 220 | pid, record->cpu, ts); |
209 | ret = 1; | 221 | ret = 1; |
210 | } | 222 | } |
@@ -292,7 +304,7 @@ static int try_switch_to(struct graph_info *ginfo, struct rt_task_info *rtt_info | |||
292 | static int try_other(struct graph_info *ginfo, struct rt_task_info *rtt_info, | 304 | static int try_other(struct graph_info *ginfo, struct rt_task_info *rtt_info, |
293 | struct record *record, struct plot_info *info) | 305 | struct record *record, struct plot_info *info) |
294 | { | 306 | { |
295 | int pid, eid, epid, my_pid, my_cpu, not_sa, not_ss, ret = 0; | 307 | int pid, eid, epid, my_pid, my_cpu, not_sa, not_ss, not_drawn, ret = 0; |
296 | unsigned long long ts; | 308 | unsigned long long ts; |
297 | 309 | ||
298 | pid = rtt_info->pid; | 310 | pid = rtt_info->pid; |
@@ -302,8 +314,9 @@ static int try_other(struct graph_info *ginfo, struct rt_task_info *rtt_info, | |||
302 | my_cpu = (rtt_info->run_time && record->cpu == rtt_info->run_cpu); | 314 | my_cpu = (rtt_info->run_time && record->cpu == rtt_info->run_cpu); |
303 | not_sa = (eid != ginfo->rtg_info.switch_away_id); | 315 | not_sa = (eid != ginfo->rtg_info.switch_away_id); |
304 | not_ss = (eid != ginfo->event_sched_switch_id); | 316 | not_ss = (eid != ginfo->event_sched_switch_id); |
317 | not_drawn = (!rt_task_plot_is_drawn(ginfo, eid)); | ||
305 | 318 | ||
306 | if ((my_pid || my_cpu) && not_ss && not_sa) { | 319 | if ((my_pid || my_cpu) && not_ss && not_sa && not_drawn) { |
307 | info->line = TRUE; | 320 | info->line = TRUE; |
308 | info->lcolor = hash_pid(record->cpu); | 321 | info->lcolor = hash_pid(record->cpu); |
309 | info->ltime = ts; | 322 | info->ltime = ts; |
@@ -448,18 +461,6 @@ rt_task_plot_record_matches(struct rt_plot_common *rt, | |||
448 | } | 461 | } |
449 | 462 | ||
450 | 463 | ||
451 | static int rt_task_plot_is_drawn(struct graph_info *ginfo, int eid) | ||
452 | { | ||
453 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
454 | |||
455 | return (eid == rtg_info->switch_away_id || | ||
456 | eid == rtg_info->switch_to_id || | ||
457 | eid == rtg_info->task_completion_id || | ||
458 | eid == rtg_info->task_block_id || | ||
459 | eid == rtg_info->task_resume_id || | ||
460 | eid == rtg_info->task_release_id); | ||
461 | } | ||
462 | |||
463 | static struct record* | 464 | static struct record* |
464 | rt_task_plot_write_header(struct rt_plot_common *rt, | 465 | rt_task_plot_write_header(struct rt_plot_common *rt, |
465 | struct graph_info *ginfo, | 466 | struct graph_info *ginfo, |
@@ -467,7 +468,7 @@ rt_task_plot_write_header(struct rt_plot_common *rt, | |||
467 | unsigned long long time) | 468 | unsigned long long time) |
468 | { | 469 | { |
469 | const char *comm; | 470 | const char *comm; |
470 | int pid, job, found; | 471 | int pid, job = -1, found; |
471 | struct record *record; | 472 | struct record *record; |
472 | unsigned long long release, deadline; | 473 | unsigned long long release, deadline; |
473 | struct rt_task_info *rtt_info = (struct rt_task_info*)rt; | 474 | struct rt_task_info *rtt_info = (struct rt_task_info*)rt; |
@@ -7,13 +7,20 @@ | |||
7 | */ | 7 | */ |
8 | struct record* | 8 | struct record* |
9 | __find_rt_record(struct graph_info *ginfo, struct rt_plot_common *rt_info, | 9 | __find_rt_record(struct graph_info *ginfo, struct rt_plot_common *rt_info, |
10 | guint64 time, int display) | 10 | guint64 time, int display, unsigned long long range) |
11 | { | 11 | { |
12 | int next_cpu, match, eid, ignored; | 12 | int next_cpu, match, eid, ignored; |
13 | struct record *record; | 13 | struct record *record; |
14 | 14 | ||
15 | set_cpus_to_rts(ginfo, time); | 15 | set_cpus_to_rts(ginfo, time); |
16 | while ((record = tracecmd_read_next_data(ginfo->handle, &next_cpu))) { | 16 | while ((record = tracecmd_read_next_data(ginfo->handle, &next_cpu))) { |
17 | |||
18 | if (range && get_rts(ginfo, record) >= time + range) { | ||
19 | free_record(record); | ||
20 | record = NULL; | ||
21 | break; | ||
22 | } | ||
23 | |||
17 | eid = pevent_data_type(ginfo->pevent, record); | 24 | eid = pevent_data_type(ginfo->pevent, record); |
18 | ignored = (eid == ginfo->event_sched_switch_id); | 25 | ignored = (eid == ginfo->event_sched_switch_id); |
19 | if (!ignored && display) { | 26 | if (!ignored && display) { |
@@ -65,14 +72,17 @@ rt_plot_display_last_event(struct graph_info *ginfo, struct graph_plot *plot, | |||
65 | } | 72 | } |
66 | 73 | ||
67 | static struct record* | 74 | static struct record* |
68 | find_prev_record(struct graph_info *ginfo, struct rt_plot_common *rt_info, | 75 | find_prev_display_record(struct graph_info *ginfo, struct rt_plot_common *rt_info, |
69 | unsigned long long time) | 76 | unsigned long long time, unsigned long long range) |
70 | { | 77 | { |
71 | int eid, ignored, match, cpu; | 78 | int eid, ignored, match, cpu; |
72 | struct record *prev, *res = NULL; | 79 | struct record *prev, *res = NULL; |
73 | unsigned long long min_ts; | 80 | unsigned long long min_ts; |
74 | 81 | ||
75 | min_ts = time - max_rt_search(ginfo); | 82 | if (range) |
83 | min_ts = time - range; | ||
84 | else | ||
85 | min_ts = time - max_rt_search(ginfo); | ||
76 | 86 | ||
77 | set_cpus_to_rts(ginfo, time); | 87 | set_cpus_to_rts(ginfo, time); |
78 | 88 | ||
@@ -111,17 +121,25 @@ rt_plot_display_info(struct graph_info *ginfo, struct graph_plot *plot, | |||
111 | struct rt_plot_common *rt_info = plot->private; | 121 | struct rt_plot_common *rt_info = plot->private; |
112 | struct event_format *event; | 122 | struct event_format *event; |
113 | struct record *record, *prev_record; | 123 | struct record *record, *prev_record; |
114 | unsigned long long msec, nsec, rts; | 124 | unsigned long long msec, nsec, rts, ptime, rtime, range; |
125 | long long pdiff, rdiff; | ||
115 | int eid; | 126 | int eid; |
116 | 127 | ||
117 | record = rt_info->write_header(rt_info, ginfo, s, time); | 128 | rt_info->write_header(rt_info, ginfo, s, time); |
118 | prev_record = find_prev_record(ginfo, rt_info, time); | 129 | |
119 | 130 | /* Stupid, fix to use resolution */ | |
120 | if (!record || (prev_record && prev_record != record && | 131 | range = 2 / ginfo->resolution; |
121 | (time - get_rts(ginfo, prev_record)) < | 132 | record = __find_rt_record(ginfo, rt_info, time, 1, range); |
122 | (get_rts(ginfo, record) - time))) { | 133 | prev_record = find_prev_display_record(ginfo, rt_info, time, range); |
123 | free_record(record); | 134 | |
124 | record = prev_record; | 135 | if (!record) { |
136 | record = prev_record; | ||
137 | } else if (prev_record) { | ||
138 | ptime = get_rts(ginfo, prev_record); | ||
139 | rtime = get_rts(ginfo, record); | ||
140 | pdiff = (ptime < time) ? time - ptime : ptime - time; | ||
141 | rdiff = (rtime < time) ? time - rtime : rtime - time; | ||
142 | record = (pdiff < rdiff) ? prev_record : record; | ||
125 | } | 143 | } |
126 | 144 | ||
127 | if (record) { | 145 | if (record) { |
@@ -137,6 +155,8 @@ rt_plot_display_info(struct graph_info *ginfo, struct graph_plot *plot, | |||
137 | pevent_event_info(s, event, record); | 155 | pevent_event_info(s, event, record); |
138 | } else | 156 | } else |
139 | trace_seq_printf(s, "\nUNKNOWN EVENT %d\n", eid); | 157 | trace_seq_printf(s, "\nUNKNOWN EVENT %d\n", eid); |
158 | } else { | ||
159 | trace_seq_printf(s, "Failsauce\n"); | ||
140 | } | 160 | } |
141 | trace_seq_putc(s, '\n'); | 161 | trace_seq_putc(s, '\n'); |
142 | nano_to_milli(time, &msec, &nsec); | 162 | nano_to_milli(time, &msec, &nsec); |
@@ -349,15 +369,19 @@ struct record* get_previous_release(struct graph_info *ginfo, int match_tid, | |||
349 | unsigned long long release, deadline, min_ts; | 369 | unsigned long long release, deadline, min_ts; |
350 | struct record *last_rec = NULL, *rec, *ret = NULL; | 370 | struct record *last_rec = NULL, *rec, *ret = NULL; |
351 | 371 | ||
372 | *out_job = -2; | ||
373 | |||
352 | min_ts = time - max_rt_search(ginfo); | 374 | min_ts = time - max_rt_search(ginfo); |
353 | 375 | ||
354 | /* The release record could have occurred on any CPU. Search all */ | 376 | /* The release record could have occurred on any CPU. Search all */ |
355 | for (cpu = 0; cpu < ginfo->cpus; cpu++) { | 377 | for (cpu = 0; cpu < ginfo->cpus; cpu++) { |
378 | set_cpu_to_rts(ginfo, time, cpu); | ||
356 | last_rec = tracecmd_peek_data(ginfo->handle, cpu); | 379 | last_rec = tracecmd_peek_data(ginfo->handle, cpu); |
357 | 380 | ||
358 | /* Require a record to start with */ | 381 | /* Require a record to start with */ |
359 | if (!last_rec) | 382 | if (!last_rec) { |
360 | goto loop_end; | 383 | goto loop_end; |
384 | } | ||
361 | last_rec->ref_count++; | 385 | last_rec->ref_count++; |
362 | 386 | ||
363 | while ((rec = tracecmd_read_prev(ginfo->handle, last_rec))) { | 387 | while ((rec = tracecmd_read_prev(ginfo->handle, last_rec))) { |
@@ -384,7 +408,6 @@ struct record* get_previous_release(struct graph_info *ginfo, int match_tid, | |||
384 | *out_release = release; | 408 | *out_release = release; |
385 | *out_deadline = deadline; | 409 | *out_deadline = deadline; |
386 | } | 410 | } |
387 | |||
388 | last_rec = NULL; | 411 | last_rec = NULL; |
389 | goto loop_end; | 412 | goto loop_end; |
390 | } | 413 | } |
@@ -36,19 +36,19 @@ rt_plot_match_time(struct graph_info *ginfo, struct graph_plot *plot, | |||
36 | unsigned long long time); | 36 | unsigned long long time); |
37 | struct record* | 37 | struct record* |
38 | __find_rt_record(struct graph_info *ginfo, struct rt_plot_common *rt, | 38 | __find_rt_record(struct graph_info *ginfo, struct rt_plot_common *rt, |
39 | guint64 time, int display); | 39 | guint64 time, int display, unsigned long long range); |
40 | 40 | ||
41 | static inline struct record* | 41 | static inline struct record* |
42 | find_rt_record(struct graph_info *ginfo, struct rt_plot_common *rt, guint64 time) | 42 | find_rt_record(struct graph_info *ginfo, struct rt_plot_common *rt, guint64 time) |
43 | { | 43 | { |
44 | return __find_rt_record(ginfo, rt, time, 0); | 44 | return __find_rt_record(ginfo, rt, time, 0, 0); |
45 | } | 45 | } |
46 | 46 | ||
47 | static inline struct record* | 47 | static inline struct record* |
48 | find_rt_display_record(struct graph_info *ginfo, | 48 | find_rt_display_record(struct graph_info *ginfo, |
49 | struct rt_plot_common *rt, guint64 time) | 49 | struct rt_plot_common *rt, guint64 time) |
50 | { | 50 | { |
51 | return __find_rt_record(ginfo, rt, time, 1); | 51 | return __find_rt_record(ginfo, rt, time, 1, 0); |
52 | } | 52 | } |
53 | 53 | ||
54 | unsigned long long next_rts(struct graph_info *ginfo, int cpu, | 54 | unsigned long long next_rts(struct graph_info *ginfo, int cpu, |