aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2012-10-06 16:45:16 -0400
committerJonathan Herman <hermanjl@cs.unc.edu>2012-10-06 16:45:16 -0400
commitf1b106178638b6155b116ff51f55d49759a28852 (patch)
tree6f823551058c4612c63131d78a391f5648b9fa35
parent93290e83d330653f090b3780e59ea5d2bf1e3bca (diff)
Merged VCPU and VTASK plots.
-rw-r--r--Makefile2
-rw-r--r--rt-plot-container.c29
-rw-r--r--rt-plot-container.h2
-rw-r--r--rt-plot-vcpu.c481
-rw-r--r--rt-plot-vcpu.h53
-rw-r--r--rt-plot-vtask.c201
-rw-r--r--rt-plot-vtask.h4
-rw-r--r--trace-graph.c108
-rw-r--r--trace-graph.h3
-rw-r--r--trace-plot.c11
10 files changed, 341 insertions, 553 deletions
diff --git a/Makefile b/Makefile
index b69552f..655c098 100644
--- a/Makefile
+++ b/Makefile
@@ -300,7 +300,7 @@ TRACE_CMD_OBJS = trace-cmd.o trace-record.o trace-read.o trace-split.o trace-lis
300 trace-stack.o trace-options.o 300 trace-stack.o trace-options.o
301TRACE_VIEW_OBJS = trace-view.o trace-view-store.o 301TRACE_VIEW_OBJS = trace-view.o trace-view-store.o
302RT_GRAPH_OBJS = rt-graph.o rt-plot-task.o rt-plot-cpu.o rt-plot-container.o rt-plot.o \ 302RT_GRAPH_OBJS = rt-graph.o rt-plot-task.o rt-plot-cpu.o rt-plot-container.o rt-plot.o \
303 rt-plot-vcpu.o rt-plot-vtask.o 303 rt-plot-vcpu.o
304TRACE_GRAPH_OBJS = trace-graph.o trace-plot.o \ 304TRACE_GRAPH_OBJS = trace-graph.o trace-plot.o \
305 trace-plot-cpu.o trace-plot-task.o \ 305 trace-plot-cpu.o trace-plot-task.o \
306 $(RT_GRAPH_OBJS) task-list.o 306 $(RT_GRAPH_OBJS) task-list.o
diff --git a/rt-plot-container.c b/rt-plot-container.c
index 6c647fc..136c51d 100644
--- a/rt-plot-container.c
+++ b/rt-plot-container.c
@@ -63,9 +63,15 @@ struct server_iter_args {
63 int is_running; 63 int is_running;
64}; 64};
65 65
66static inline void try_job_update(struct server_iter_args *args, int candidate)
67{
68 if (!(*args->out_job))
69 (*args->out_job) = candidate;
70}
71
66static int server_iterator(struct graph_info *ginfo, struct record *record, void *data) 72static int server_iterator(struct graph_info *ginfo, struct record *record, void *data)
67{ 73{
68 int sid, job, tid, tjob, match; 74 int sid, job, tid, tjob, match, ret;
69 struct server_iter_args *args = data; 75 struct server_iter_args *args = data;
70 unsigned long long when, time = get_rts(ginfo, record); 76 unsigned long long when, time = get_rts(ginfo, record);
71 77
@@ -77,19 +83,26 @@ static int server_iterator(struct graph_info *ginfo, struct record *record, void
77#define ARGS ginfo, record, &sid, &job, &tid, &tjob, &when 83#define ARGS ginfo, record, &sid, &job, &tid, &tjob, &when
78 match = rt_graph_check_server_switch_away(ARGS); 84 match = rt_graph_check_server_switch_away(ARGS);
79 if (match && sid == args->match_sid) { 85 if (match && sid == args->match_sid) {
86 /* We were running something */
80 (*args->out_tid) = tid; 87 (*args->out_tid) = tid;
81 (*args->out_tjob) = tjob; 88 (*args->out_tjob) = tjob;
82 (*args->out_job) = job; 89 try_job_update(args, job);
83 args->is_running = 1; 90 args->is_running = 1;
84 return 0; 91 ret = 0;
85 92
93 } else if (match && tid == args->match_sid) {
94 /* We are being run by someone */
95 try_job_update(args, tjob);
86 } 96 }
87 97
88 match = rt_graph_check_server_switch_to(ARGS); 98 match = rt_graph_check_server_switch_to(ARGS);
89 if (match && sid == args->match_sid) { 99 if (match && sid == args->match_sid) {
90 /* We must not have been running anything */ 100 /* We must not have been running anything */
91 (*args->out_job) = job; 101 try_job_update(args, job);
92 return 0; 102 return 0;
103 } else if (match && tid == args->match_sid) {
104 /* We are being run by someone */
105 try_job_update(args, tjob);
93 } 106 }
94 107
95#undef ARGS 108#undef ARGS
@@ -98,8 +111,6 @@ static int server_iterator(struct graph_info *ginfo, struct record *record, void
98 111
99int get_server_info(struct graph_info *ginfo, struct rt_plot_common *rt, 112int get_server_info(struct graph_info *ginfo, struct rt_plot_common *rt,
100 int match_sid, unsigned long long time, 113 int match_sid, unsigned long long time,
101 unsigned long long *out_release,
102 unsigned long long *out_deadline,
103 int *out_job, int *out_tid, int *out_tjob, 114 int *out_job, int *out_tid, int *out_tjob,
104 struct record **out_record) 115 struct record **out_record)
105{ 116{
@@ -110,7 +121,7 @@ int get_server_info(struct graph_info *ginfo, struct rt_plot_common *rt,
110 if (!*out_record) 121 if (!*out_record)
111 return 0; 122 return 0;
112 123
113 *out_release = *out_deadline = *out_job = *out_tid = 0; 124 *out_tjob = *out_job = *out_tid = 0;
114 125
115 set_cpus_to_rts(ginfo, time); 126 set_cpus_to_rts(ginfo, time);
116 iterate(ginfo, 0, server_iterator, &args); 127 iterate(ginfo, 0, server_iterator, &args);
@@ -136,8 +147,8 @@ void rt_plot_container(struct graph_info *ginfo, int cid)
136 147
137 for (vlist = cont->vcpus; vlist; vlist = vlist->next) { 148 for (vlist = cont->vcpus; vlist; vlist = vlist->next) {
138 insert_vcpu(ginfo, cont, vlist); 149 insert_vcpu(ginfo, cont, vlist);
139 if (vlist->params.wcet && vlist->params.period) 150 /* if (vlist->params.wcet && vlist->params.period) */
140 insert_vtask(ginfo, cont, vlist); 151 /* insert_vtask(ginfo, cont, vlist); */
141 } 152 }
142} 153}
143 154
diff --git a/rt-plot-container.h b/rt-plot-container.h
index c96d6e9..8ff2260 100644
--- a/rt-plot-container.h
+++ b/rt-plot-container.h
@@ -2,7 +2,6 @@
2#define __RT_PLOT_CONTAINER_H 2#define __RT_PLOT_CONTAINER_H
3 3
4#include "rt-plot-vcpu.h" 4#include "rt-plot-vcpu.h"
5#include "rt-plot-vtask.h"
6 5
7typedef void (*cont_dialog_cb_func)(gboolean, gint*, gint*, gpointer); 6typedef void (*cont_dialog_cb_func)(gboolean, gint*, gint*, gpointer);
8 7
@@ -16,7 +15,6 @@ void rt_plot_add_all_containers(struct graph_info *ginfo);
16int get_server_info(struct graph_info *ginfo, 15int get_server_info(struct graph_info *ginfo,
17 struct rt_plot_common *rt, 16 struct rt_plot_common *rt,
18 int match_sid, unsigned long long time, 17 int match_sid, unsigned long long time,
19 unsigned long long *release, unsigned long long *deadline,
20 int *job, int *tid, int *tjob, struct record **record); 18 int *job, int *tid, int *tjob, struct record **record);
21 19
22#endif 20#endif
diff --git a/rt-plot-vcpu.c b/rt-plot-vcpu.c
index e39ae19..4045565 100644
--- a/rt-plot-vcpu.c
+++ b/rt-plot-vcpu.c
@@ -13,12 +13,22 @@
13#define dprintf(l, x...) do { if (0) printf(x); } while (0) 13#define dprintf(l, x...) do { if (0) printf(x); } while (0)
14#endif 14#endif
15 15
16static void update_label(struct vcpu_info *info, int tid, int tjob) 16static void update_task_label(struct vcpu_info *info, int tid, int tjob)
17{ 17{
18 info->fresh = FALSE; 18 info->fresh = FALSE;
19 if (tid != info->run_tid) { 19 if (tid != info->task_tid) {
20 info->run_tid = tid; 20 info->task_tid = tid;
21 snprintf(info->label, LLABEL, "%d:%d", tid, tjob); 21 snprintf(info->task_label, LLABEL, "%d:%d", tid, tjob);
22 }
23}
24
25static void update_server_label(struct vcpu_info *info, int job)
26{
27 info->fresh = FALSE;
28 if (job > info->server_job) {
29 info->server_job = job;
30 snprintf(info->server_label, LLABEL, "%d:%d",
31 info->sid, info->server_job);
22 } 32 }
23} 33}
24 34
@@ -32,26 +42,53 @@ try_server_switch_away(struct graph_info *ginfo, struct vcpu_info *vcpu_info,
32 match = rt_graph_check_server_switch_away(ginfo, record, 42 match = rt_graph_check_server_switch_away(ginfo, record,
33 &sid, &job, 43 &sid, &job,
34 &tid, &tjob, &ts); 44 &tid, &tjob, &ts);
45
35 if (match && sid == vcpu_info->sid) { 46 if (match && sid == vcpu_info->sid) {
36 update_label(vcpu_info, tid, tjob); 47 /* This server is no longer running something */
48 update_task_label(vcpu_info, tid, tjob);
49 update_server_label(vcpu_info, job);
37 50
38 if (vcpu_info->run_time && vcpu_info->run_time < ts) { 51 if (vcpu_info->task_run_time && vcpu_info->task_run_time < ts) {
39 info->box = TRUE; 52 info->box = TRUE;
40 info->bcolor = hash_pid(tid); 53 info->bcolor = hash_pid(tid);
41 info->bfill = vcpu_info->running; 54 info->bfill = vcpu_info->task_running;
42 info->bstart = vcpu_info->run_time; 55 info->bstart = vcpu_info->task_run_time;
56 info->bend = ts;
57 info->blabel = vcpu_info->task_label;
58 info->flip = vcpu_info->show_server;
59 }
60
61 vcpu_info->task_run_time = 0ULL;
62 vcpu_info->task_running = FALSE;
63 vcpu_info->task_cpu = NO_CPU;
64
65 ret = 1;
66 } else if (vcpu_info->show_server && match && tid == vcpu_info->sid) {
67 /* This server is no longer running */
68 update_server_label(vcpu_info, tjob);
69
70 if (vcpu_info->server_run_time && vcpu_info->server_run_time < ts) {
71 info->box = TRUE;
72 info->bcolor = hash_cpu(sid - 1);
73 info->bfill = TRUE;
74 info->bstart = vcpu_info->server_run_time;
43 info->bend = ts; 75 info->bend = ts;
44 info->blabel = vcpu_info->label; 76 info->blabel = vcpu_info->server_label;
45 } 77 }
78 vcpu_info->server_run_time = 0ULL;
79 vcpu_info->server_cpu = NO_CPU;
80
81 ret = 1;
82 }
46 83
84 if (ret) {
47 dprintf(3, "VCPU switch away from %d on %d:%d at %llu\n", 85 dprintf(3, "VCPU switch away from %d on %d:%d at %llu\n",
48 tid, sid, job, ts); 86 tid, sid, job, ts);
49 vcpu_info->run_time = 0ULL;
50 vcpu_info->run_cpu = NO_CPU;
51 vcpu_info->run_tid = -1;
52 vcpu_info->running = FALSE;
53 87
54 ret = 1; 88 vcpu_info->task_run_time = 0ULL;
89 vcpu_info->task_tid = -1;
90 vcpu_info->task_running = FALSE;
91 vcpu_info->task_cpu = NO_CPU;
55 } 92 }
56 93
57 return ret; 94 return ret;
@@ -66,14 +103,28 @@ static int try_server_switch_to(struct graph_info *ginfo, struct vcpu_info *vcpu
66 match = rt_graph_check_server_switch_to(ginfo, record, 103 match = rt_graph_check_server_switch_to(ginfo, record,
67 &sid, &job, &tid, &tjob, &ts); 104 &sid, &job, &tid, &tjob, &ts);
68 if (match && sid == vcpu_info->sid) { 105 if (match && sid == vcpu_info->sid) {
69 update_label(vcpu_info, tid, tjob); 106 /* This server is now running something */
70 vcpu_info->run_time = ts; 107 update_task_label(vcpu_info, tid, tjob);
71 vcpu_info->run_cpu = record->cpu; 108 update_server_label(vcpu_info, job);
72 vcpu_info->run_tid = tid; 109
110 vcpu_info->task_run_time = ts;
111 vcpu_info->task_cpu = sid;
112 vcpu_info->server_cpu = record->cpu;
113 vcpu_info->task_tid = tid;
114 ret = 1;
115 } else if (vcpu_info->show_server && match && tid == vcpu_info->sid) {
116 /* This server is now running */
117 update_server_label(vcpu_info, tjob);
118 vcpu_info->server_run_time = ts;
119 vcpu_info->server_cpu = sid;
120 ret = 1;
121 }
122
123 if (ret) {
73 dprintf(3, "Switch to %d for %d:%d at %llu\n", 124 dprintf(3, "Switch to %d for %d:%d at %llu\n",
74 tid, sid, job, ts); 125 tid, sid, job, ts);
75 ret = 1;
76 } 126 }
127
77 return ret; 128 return ret;
78} 129}
79 130
@@ -84,18 +135,24 @@ static int try_switch_to(struct graph_info *ginfo, struct vcpu_info *vcpu_info,
84 unsigned long long ts; 135 unsigned long long ts;
85 136
86 match = rt_graph_check_switch_to(ginfo, record, &pid, &job, &ts); 137 match = rt_graph_check_switch_to(ginfo, record, &pid, &job, &ts);
87 if (match && pid && (pid == vcpu_info->run_tid || pid == -vcpu_info->run_tid) && vcpu_info->run_time) { 138 if (match && pid && vcpu_info->task_run_time &&
88 vcpu_info->running = TRUE; 139 (pid == vcpu_info->task_tid || pid == -vcpu_info->task_tid)) {
140 /* This server is running a physical task */
141 if (pid == vcpu_info->task_tid)
142 update_task_label(vcpu_info, pid, job);
143
144 vcpu_info->task_running = TRUE;
89 145
90 /* Draw empty box for time spent not running a task */ 146 /* Draw empty box for time spent not running a task */
91 info->box = TRUE; 147 info->box = TRUE;
148 info->flip = vcpu_info->show_server;
92 info->bcolor = hash_pid(pid); 149 info->bcolor = hash_pid(pid);
93 info->bfill = FALSE; 150 info->bfill = FALSE;
94 info->bstart = vcpu_info->run_time; 151 info->bstart = vcpu_info->task_run_time;
95 info->bend = ts; 152 info->bend = ts;
96 info->blabel = vcpu_info->label; 153 info->blabel = vcpu_info->task_label;
97 154
98 vcpu_info->run_time = ts; 155 vcpu_info->task_run_time = ts;
99 ret = 1; 156 ret = 1;
100 } 157 }
101 return ret; 158 return ret;
@@ -108,19 +165,67 @@ static int try_switch_away(struct graph_info *ginfo, struct vcpu_info *vcpu_info
108 unsigned long long ts; 165 unsigned long long ts;
109 166
110 match = rt_graph_check_switch_away(ginfo, record, &pid, &job, &ts); 167 match = rt_graph_check_switch_away(ginfo, record, &pid, &job, &ts);
111 if (match && pid && pid == vcpu_info->run_tid && vcpu_info->running) { 168 if (match && pid && pid == vcpu_info->task_tid && vcpu_info->task_running) {
112 vcpu_info->running = FALSE; 169 update_task_label(vcpu_info, pid, job);
170
171 /* This server is no longer running a real task */
172 vcpu_info->task_running = FALSE;
113 173
114 if (vcpu_info->run_time && vcpu_info->run_time < ts) { 174 if (vcpu_info->task_run_time && vcpu_info->task_run_time < ts) {
115 info->box = TRUE; 175 info->box = TRUE;
176 info->flip = vcpu_info->show_server;
116 info->bcolor = hash_pid(pid); 177 info->bcolor = hash_pid(pid);
117 info->bfill = TRUE; 178 info->bfill = TRUE;
118 info->bstart = vcpu_info->run_time; 179 info->bstart = vcpu_info->task_run_time;
119 info->bend = ts; 180 info->bend = ts;
120 info->blabel = vcpu_info->label; 181 info->blabel = vcpu_info->task_label;
121 } 182 }
122 183
123 vcpu_info->run_time = ts; 184 vcpu_info->task_run_time = ts;
185 ret = 1;
186 }
187 return ret;
188}
189
190static int try_server_release(struct graph_info *ginfo,
191 struct vcpu_info *vcpu_info,
192 struct record *record, struct plot_info *info)
193{
194 int sid, job, match, ret = 0;
195 unsigned long long release, deadline;
196
197 match = rt_graph_check_server_release(ginfo, record, &sid, &job,
198 &release, &deadline);
199 if (match && sid == vcpu_info->sid) {
200 info->release = TRUE;
201 info->rtime = release;
202
203 info->deadline = TRUE;
204 info->dtime = deadline;
205
206 dprintf(3, "VCPU release for %d:%d on %d, rel: %llu, dead: %llu\n",
207 sid, job, record->cpu, release, deadline);
208
209 ret = 1;
210 }
211 return ret;
212}
213
214static int try_server_completion(struct graph_info *ginfo,
215 struct vcpu_info *vcpu_info,
216 struct record *record, struct plot_info *info)
217{
218 int sid, job, match, ret = 0;
219 unsigned long long ts;
220
221 match = rt_graph_check_server_completion(ginfo, record, &sid, &job, &ts);
222 if (match && sid == vcpu_info->sid) {
223
224 info->completion = TRUE;
225 info->ctime = ts;
226
227 dprintf(3, "VCPU completion for %d:%d on %d at %llu\n",
228 sid, job, record->cpu, ts);
124 ret = 1; 229 ret = 1;
125 } 230 }
126 return ret; 231 return ret;
@@ -130,34 +235,58 @@ static void do_plot_end(struct graph_info *ginfo, struct vcpu_info *vcpu_info,
130 struct plot_info *info) 235 struct plot_info *info)
131{ 236{
132 int tid, job, tjob, is_running; 237 int tid, job, tjob, is_running;
133 unsigned long long deadline, release;
134 struct record *record; 238 struct record *record;
135 239
136 if (ginfo->view_end_time == ginfo->end_time) 240 if (ginfo->view_end_time == ginfo->end_time)
137 return; 241 return;
138 242
139 if (vcpu_info->run_time && vcpu_info->run_cpu != NO_CPU) { 243 if (vcpu_info->task_run_time && vcpu_info->task_cpu != NO_CPU) {
244 /* The server was running something */
245 info->box = TRUE;
246 info->flip = vcpu_info->show_server;
247 info->bcolor = hash_pid(vcpu_info->task_tid);
248 info->bfill = vcpu_info->task_running;
249 info->bstart = vcpu_info->task_run_time;
250 info->bend = ginfo->view_end_time;
251 info->blabel = vcpu_info->task_label;
252
253 /* Might need to draw underbox as well */
254 info->repeat = TRUE;
255
256 vcpu_info->task_run_time = 0ULL;
257 return;
258 }
259
260 if (vcpu_info->show_server && vcpu_info->server_run_time &&
261 vcpu_info->server_cpu != NO_CPU) {
262 /* The server was running */
140 info->box = TRUE; 263 info->box = TRUE;
141 info->bcolor = hash_pid(vcpu_info->run_tid); 264 info->bcolor = hash_pid(vcpu_info->sid);
142 info->bfill = vcpu_info->running; 265 info->bfill = TRUE;
143 info->bstart = vcpu_info->run_time; 266 info->bstart = vcpu_info->server_run_time;
144 info->bend = ginfo->view_end_time; 267 info->bend = ginfo->view_end_time;
145 info->blabel = vcpu_info->label; 268 info->blabel = vcpu_info->server_label;
146 } else if (vcpu_info->fresh) { 269 vcpu_info->server_run_time = 0ULL;
270 return;
271 }
272
273 if (vcpu_info->fresh) {
274 /* No records received. Get information about time */
147 is_running = get_server_info(ginfo, 275 is_running = get_server_info(ginfo,
148 (struct rt_plot_common*)vcpu_info, 276 (struct rt_plot_common*)vcpu_info,
149 vcpu_info->sid, 277 vcpu_info->sid,
150 ginfo->view_end_time, 278 ginfo->view_end_time,
151 &release, &deadline,
152 &job, &tid, &tjob, &record); 279 &job, &tid, &tjob, &record);
153 if (is_running) { 280 if (is_running) {
154 update_label(vcpu_info, tid, tjob); 281 update_task_label(vcpu_info, tid, tjob);
155 info->box = TRUE; 282 update_server_label(vcpu_info, job);
156 info->bcolor = hash_pid(vcpu_info->run_tid); 283
157 info->bfill = is_task_running(ginfo, ginfo->view_end_time, tid); 284 vcpu_info->task_tid = tid;
158 info->bstart = vcpu_info->run_time; 285 vcpu_info->task_running =
159 info->bend = ginfo->view_end_time; 286 is_task_running(ginfo, ginfo->view_end_time, tid);
160 info->blabel = vcpu_info->label; 287 vcpu_info->server_run_time = ginfo->view_start_time;
288
289 do_plot_end(ginfo, vcpu_info, info);
161 } 290 }
162 } 291 }
163} 292}
@@ -175,93 +304,38 @@ static int rt_vcpu_plot_event(struct graph_info *ginfo, struct graph_plot *plot,
175 304
176 match = try_server_switch_away(ginfo, vcpu_info, record, info) || 305 match = try_server_switch_away(ginfo, vcpu_info, record, info) ||
177 try_server_switch_to(ginfo, vcpu_info, record, info) || 306 try_server_switch_to(ginfo, vcpu_info, record, info) ||
178 /* vcpu_try_block(ginfo, vcpu_info, record, info) || */ 307 try_server_release(ginfo, vcpu_info, record, info) ||
179 /* vcpu_try_resume(ginfo, vcpu_info, record, info) || */ 308 try_server_completion(ginfo, vcpu_info, record, info) ||
180 /* vcpu_try_release(ginfo, vcpu_info, record, info) || */
181 /* vcpu_try_completion(ginfo, vcpu_info, record, info) || */
182 try_switch_to(ginfo, vcpu_info, record, info) || 309 try_switch_to(ginfo, vcpu_info, record, info) ||
183 try_switch_away(ginfo, vcpu_info, record, info); 310 try_switch_away(ginfo, vcpu_info, record, info);
184 return match; 311 return match;
185} 312}
186 313static void rt_vcpu_plot_start(struct graph_info *ginfo, struct graph_plot *plot,
187
188const struct plot_callbacks rt_vcpu_cb = {
189 .start = rt_vcpu_plot_start,
190 .destroy = rt_vcpu_plot_destroy,
191 .plot_event = rt_vcpu_plot_event,
192 .display_last_event = rt_plot_display_last_event,
193 .display_info = rt_plot_display_info,
194 .match_time = rt_plot_match_time,
195 .find_record = rt_plot_find_record,
196};
197
198void insert_vcpu(struct graph_info *ginfo, struct cont_list *cont,
199 struct vcpu_list *vcpu_info)
200{
201 struct graph_plot *plot;
202 struct vcpu_info *vcpu;
203 char *label;
204 int len;
205
206 vcpu = malloc_or_die(sizeof(*vcpu));
207 vcpu->sid = vcpu_info->sid;
208 vcpu->cont = cont;
209 vcpu->label = malloc_or_die(LLABEL);
210
211 vcpu->common.record_matches = rt_vcpu_plot_record_matches;
212 vcpu->common.is_drawn = rt_vcpu_plot_is_drawn;
213 vcpu->common.write_header = rt_vcpu_plot_write_header;
214
215 g_assert(cont);
216
217
218 len = strlen(cont->name) + 100;
219 label = malloc_or_die(len);
220
221 if (vcpu_info->params.wcet)
222 snprintf(label, len, "%s - %d\nServer %d\n(%1.1f, %1.1f)",
223 cont->name, cont->cid, vcpu_info->sid,
224 nano_as_milli(vcpu_info->params.wcet),
225 nano_as_milli(vcpu_info->params.period));
226 else
227 snprintf(label, len, "%s - %d\nServer %d",
228 cont->name, cont->cid, vcpu_info->sid);
229 plot = trace_graph_plot_append(ginfo, label, PLOT_TYPE_SERVER_CPU,
230 TIME_TYPE_RT, &rt_vcpu_cb, vcpu);
231 trace_graph_plot_add_all_recs(ginfo, plot);
232}
233
234/**
235 *
236 */
237void rt_vcpu_plot_start(struct graph_info *ginfo, struct graph_plot *plot,
238 unsigned long long time) 314 unsigned long long time)
239{ 315{
240 struct vcpu_info *vcpu_info = plot->private; 316 struct vcpu_info *vcpu_info = plot->private;
241 317
242 dprintf(4,"%s\n", __FUNCTION__); 318 vcpu_info->task_tid = -1;
319 vcpu_info->task_run_time = time;
320 vcpu_info->task_running = FALSE;
321 vcpu_info->task_cpu = NO_CPU;
243 322
244 vcpu_info->run_time = time; 323 vcpu_info->server_job = -1;
245 vcpu_info->block_time = time; 324 vcpu_info->server_run_time = time;
246 vcpu_info->run_cpu = NO_CPU; 325 vcpu_info->server_cpu = NO_CPU;
247 vcpu_info->run_tid = -1;
248 vcpu_info->block_cpu = NO_CPU;
249 vcpu_info->fresh = FALSE;
250 326
251 vcpu_info->fresh = TRUE; 327 vcpu_info->fresh = TRUE;
252 vcpu_info->running = FALSE; 328
253 vcpu_info->last_job = -1; 329 update_task_label(vcpu_info, 0, 0);
254 update_label(vcpu_info, 0, 0); 330 update_server_label(vcpu_info, 0);
255} 331}
256 332
257/** 333static void rt_vcpu_plot_destroy(struct graph_info *ginfo, struct graph_plot *plot)
258 *
259 */
260void rt_vcpu_plot_destroy(struct graph_info *ginfo, struct graph_plot *plot)
261{ 334{
262 struct vcpu_info *vcpu_info = plot->private; 335 struct vcpu_info *vcpu_info = plot->private;
263 trace_graph_plot_remove_all_recs(ginfo, plot); 336 trace_graph_plot_remove_all_recs(ginfo, plot);
264 free(vcpu_info->label); 337 free(vcpu_info->task_label);
338 free(vcpu_info->server_label);
265 free(vcpu_info); 339 free(vcpu_info);
266} 340}
267 341
@@ -278,20 +352,16 @@ int rt_vcpu_plot_record_matches(struct rt_plot_common *rt,
278 352
279#define ARG ginfo, record, &sid, &dint 353#define ARG ginfo, record, &sid, &dint
280 match = rt_graph_check_server_switch_to(ARG, &dint, &dint, &dull) || 354 match = rt_graph_check_server_switch_to(ARG, &dint, &dint, &dull) ||
281 rt_graph_check_server_switch_away(ARG,&dint, &dint, &dull); 355 rt_graph_check_server_switch_away(ARG,&dint, &dint, &dull) ||
282 rt_graph_check_server_completion(ARG, &dull) || 356 rt_graph_check_server_completion(ARG, &dull) ||
283 rt_graph_check_server_release(ARG, &dull, &dull); 357 rt_graph_check_server_release(ARG, &dull, &dull) ||
284 rt_graph_check_server_block(ARG, &dull) || 358 rt_graph_check_switch_to(ARG, &dull) ||
285 rt_graph_check_server_resume(ARG, &dull); 359 rt_graph_check_switch_away(ARG, &dull);
286#undef ARG 360#undef ARG
287 return (match && sid == vcpu_info->sid); 361 return (match && (sid == vcpu_info->sid || -sid == vcpu_info->sid));
288} 362}
289 363
290/** 364static int
291 * Return true if the given record type is drawn on screen. This does not
292 * include event line markes.
293 */
294int
295rt_vcpu_plot_is_drawn(struct graph_info *ginfo, int eid) 365rt_vcpu_plot_is_drawn(struct graph_info *ginfo, int eid)
296{ 366{
297 struct rt_graph_info *rtg_info = &ginfo->rtg_info; 367 struct rt_graph_info *rtg_info = &ginfo->rtg_info;
@@ -299,26 +369,21 @@ rt_vcpu_plot_is_drawn(struct graph_info *ginfo, int eid)
299 eid == rtg_info->server_switch_away_id || 369 eid == rtg_info->server_switch_away_id ||
300 eid == rtg_info->server_release_id || 370 eid == rtg_info->server_release_id ||
301 eid == rtg_info->server_completion_id || 371 eid == rtg_info->server_completion_id ||
302 eid == rtg_info->server_block_id || 372 eid == rtg_info->switch_to_id ||
303 eid == rtg_info->server_resume_id); 373 eid == rtg_info->switch_away_id);
304} 374}
305 375
306/** 376static struct record*
307 *
308 */
309struct record*
310rt_vcpu_plot_write_header(struct rt_plot_common *rt, 377rt_vcpu_plot_write_header(struct rt_plot_common *rt,
311 struct graph_info *ginfo, 378 struct graph_info *ginfo,
312 struct trace_seq *s, 379 struct trace_seq *s,
313 unsigned long long time) 380 unsigned long long time)
314{ 381{
315 int is_running, job = 0, tid, tjob; 382 int is_running, job = 0, tid, tjob;
316 unsigned long long release, deadline;
317 struct vcpu_info *vcpu_info = (struct vcpu_info*)rt; 383 struct vcpu_info *vcpu_info = (struct vcpu_info*)rt;
318 struct record *record; 384 struct record *record;
319 385
320 is_running = get_server_info(ginfo, rt, vcpu_info->sid, time, 386 is_running = get_server_info(ginfo, rt, vcpu_info->sid, time,
321 &release, &deadline,
322 &job, &tid, &tjob, &record); 387 &job, &tid, &tjob, &record);
323 388
324 trace_seq_printf(s, "%s\nServer: %d:%d\n", vcpu_info->cont->name, 389 trace_seq_printf(s, "%s\nServer: %d:%d\n", vcpu_info->cont->name,
@@ -328,120 +393,58 @@ rt_vcpu_plot_write_header(struct rt_plot_common *rt,
328 trace_seq_printf(s, "Running: %d:%d", tid, tjob); 393 trace_seq_printf(s, "Running: %d:%d", tid, tjob);
329 } 394 }
330 395
331 if (in_res(ginfo, deadline, time)) {
332 trace_seq_printf(s, "\nlitmus_server_deadline\n"
333 "deadline(job(%d,%d)): %llu\n",
334 vcpu_info->sid, job, deadline);
335 }
336 if (in_res(ginfo, release, time)) {
337 trace_seq_printf(s, "\nlitmus_server_release\n"
338 "release(job(%d,%d)): %llu\n",
339 vcpu_info->sid, job, release);
340 }
341
342
343 trace_seq_putc(s, '\n'); 396 trace_seq_putc(s, '\n');
344 return record; 397 return record;
345} 398}
346 399
347/** 400const struct plot_callbacks rt_vcpu_cb = {
348 * vcpu_try_release - draw release and deadline arrows if record matches 401 .start = rt_vcpu_plot_start,
349 */ 402 .destroy = rt_vcpu_plot_destroy,
350int vcpu_try_release(struct graph_info *ginfo, struct vcpu_info *vcpu_info, 403 .plot_event = rt_vcpu_plot_event,
351 struct record *record, struct plot_info *info) 404 .display_last_event = rt_plot_display_last_event,
352{ 405 .display_info = rt_plot_display_info,
353 int sid, job, match, ret = 0; 406 .match_time = rt_plot_match_time,
354 unsigned long long release, deadline; 407 .find_record = rt_plot_find_record,
355 408};
356 match = rt_graph_check_server_release(ginfo, record, &sid, &job,
357 &release, &deadline);
358 if (match && sid == vcpu_info->sid) {
359 info->release = TRUE;
360 info->rtime = release;
361 409
362 info->deadline = TRUE; 410void insert_vcpu(struct graph_info *ginfo, struct cont_list *cont,
363 info->dtime = deadline; 411 struct vcpu_list *vcpu_info)
412{
413 struct graph_plot *plot;
414 struct vcpu_info *vcpu;
415 char *label;
416 int len;
364 417
365 dprintf(3, "VCPU release for %d:%d on %d, rel: %llu, dead: %llu\n", 418 vcpu = malloc_or_die(sizeof(*vcpu));
366 sid, job, record->cpu, release, deadline); 419 vcpu->sid = vcpu_info->sid;
420 vcpu->cont = cont;
421 vcpu->server_label = malloc_or_die(LLABEL);
422 vcpu->task_label = malloc_or_die(LLABEL);
367 423
368 ret = 1; 424 vcpu->common.record_matches = rt_vcpu_plot_record_matches;
369 } 425 vcpu->common.is_drawn = rt_vcpu_plot_is_drawn;
370 return ret; 426 vcpu->common.write_header = rt_vcpu_plot_write_header;
371}
372 427
373/** 428 g_assert(cont);
374 * vcpu_try_completion - draw completion if record matches
375 */
376int vcpu_try_completion(struct graph_info *ginfo,
377 struct vcpu_info *vcpu_info,
378 struct record *record, struct plot_info *info)
379{
380 int sid, job, match, ret = 0;
381 unsigned long long ts;
382 429
383 match = rt_graph_check_server_completion(ginfo, record, &sid, &job, &ts);
384 if (match && sid == vcpu_info->sid) {
385 430
386 info->completion = TRUE; 431 len = strlen(cont->name) + 100;
387 info->ctime = ts; 432 label = malloc_or_die(len);
388 433
389 dprintf(3, "VCPU completion for %d:%d on %d at %llu\n", 434 if (vcpu_info->params.wcet) {
390 sid, job, record->cpu, ts); 435 vcpu->show_server = TRUE;
391 ret = 1; 436 snprintf(label, len, "%s - %d\nServer %d\n(%1.1f, %1.1f)",
437 cont->name, cont->cid, vcpu_info->sid,
438 nano_as_milli(vcpu_info->params.wcet),
439 nano_as_milli(vcpu_info->params.period));
440 } else {
441 /* Always running, no need to see the server */
442 vcpu->show_server = FALSE;
443 snprintf(label, len, "%s - %d\nServer %d",
444 cont->name, cont->cid, vcpu_info->sid);
392 } 445 }
393 return ret;
394}
395
396/* /\** */
397/* * vcpu_try_block - start block box if record matches */
398/* *\/ */
399/* int vcpu_try_block(struct graph_info *ginfo, struct vcpu_info *vcpu_info, */
400/* struct record *record, struct plot_info *info) */
401/* { */
402/* int sid, match, ret = 0; */
403/* unsigned long long ts; */
404
405/* match = rt_graph_check_server_block(ginfo, record, &sid, &ts); */
406/* if (match && sid == vcpu_info->sid) { */
407/* vcpu_info->fresh = FALSE; */
408/* vcpu_info->block_time = ts; */
409/* vcpu_info->block_cpu = NO_CPU; */
410/* dprintf(3, "VCPU resume for %d on %d at %llu\n", */
411/* sid, record->cpu, ts); */
412/* ret = 1; */
413/* } */
414/* return ret; */
415/* } */
416
417/* /\** */
418/* * vcpu_try_resume - end block box if record matches */
419/* *\/ */
420/* int vcpu_try_resume(struct graph_info *ginfo, struct vcpu_info *vcpu_info, */
421/* struct record *record, struct plot_info *info) */
422/* { */
423/* int sid, match, ret = 0; */
424/* unsigned long long ts; */
425
426/* match = rt_graph_check_server_resume(ginfo, record, &sid, &ts); */
427
428/* if (match && sid == vcpu_info->sid) { */
429/* info->box = TRUE; */
430/* info->bcolor = 0x0; */
431/* info->bfill = TRUE; */
432/* info->bthin = TRUE; */
433/* info->bstart = vcpu_info->block_time; */
434/* info->bend = ts; */
435/* vcpu_info->fresh = FALSE; */
436
437/* vcpu_info->block_time = 0ULL; */
438/* vcpu_info->block_cpu = NO_CPU; */
439/* dprintf(3, "VCPU resume for %d on %d at %llu\n", */
440/* sid, record->cpu, ts); */
441
442/* ret = 1; */
443/* } */
444/* return ret; */
445/* } */
446
447 446
447 plot = trace_graph_plot_append(ginfo, label, PLOT_TYPE_SERVER_CPU,
448 TIME_TYPE_RT, &rt_vcpu_cb, vcpu);
449 trace_graph_plot_add_all_recs(ginfo, plot);
450}
diff --git a/rt-plot-vcpu.h b/rt-plot-vcpu.h
index f88e6ab..3ef33ce 100644
--- a/rt-plot-vcpu.h
+++ b/rt-plot-vcpu.h
@@ -7,50 +7,29 @@ struct vcpu_info {
7 7
8 int sid; 8 int sid;
9 9
10 int run_tid; 10 /* What the vcpu is running */
11 int run_cpu; 11 int task_tid;
12 unsigned long long run_time; 12 int task_cpu;
13 unsigned long long task_run_time;
14 gboolean task_running;
13 15
14 int last_job; 16 /* How the vcpu is running */
15 17 int server_job;
16 int block_cpu; 18 int server_cpu;
17 unsigned long long block_time; 19 unsigned long long server_run_time;
18 20
19 gboolean fresh; 21 gboolean fresh;
20 gboolean running;
21 22
22 char *label; 23 /* False if we should only show what the vcpu is running, not
24 * WHEN the CPU is running
25 */
26 gboolean show_server;
27
28 char *task_label;
29 char *server_label;
23 30
24 struct cont_list *cont; 31 struct cont_list *cont;
25}; 32};
26 33
27void insert_vcpu(struct graph_info *ginfo, struct cont_list *cont, 34void insert_vcpu(struct graph_info *ginfo, struct cont_list *cont,
28 struct vcpu_list *vcpu_info); 35 struct vcpu_list *vcpu_info);
29
30
31/* drawing methods */
32int vcpu_try_release(struct graph_info *ginfo, struct vcpu_info *vcpu_info,
33 struct record *record, struct plot_info *info);
34int vcpu_try_completion(struct graph_info *ginfo,
35 struct vcpu_info *vcpu_info,
36 struct record *record, struct plot_info *info);
37int vcpu_try_block(struct graph_info *ginfo, struct vcpu_info *vcpu_info,
38 struct record *record, struct plot_info *info);
39int vcpu_try_resume(struct graph_info *ginfo, struct vcpu_info *vcpu_info,
40 struct record *record, struct plot_info *info);
41
42/* trace-plot methods */
43void rt_vcpu_plot_start(struct graph_info *ginfo, struct graph_plot *plot,
44 unsigned long long time);
45void rt_vcpu_plot_destroy(struct graph_info *ginfo, struct graph_plot *plot);
46
47/* rt-plot-common methods */
48int rt_vcpu_plot_record_matches(struct rt_plot_common *rt,
49 struct graph_info *ginfo,
50 struct record *record);
51int rt_vcpu_plot_is_drawn(struct graph_info *ginfo, int eid);
52struct record*
53rt_vcpu_plot_write_header(struct rt_plot_common *rt,
54 struct graph_info *ginfo,
55 struct trace_seq *s,
56 unsigned long long time);
diff --git a/rt-plot-vtask.c b/rt-plot-vtask.c
deleted file mode 100644
index 16bb942..0000000
--- a/rt-plot-vtask.c
+++ /dev/null
@@ -1,201 +0,0 @@
1#include <stdio.h>
2#include <string.h>
3#include "trace-graph.h"
4
5#define DEBUG_LEVEL 0
6#if DEBUG_LEVEL > 0
7#define dprintf(l, x...) \
8 do { \
9 if (l <= DEBUG_LEVEL) \
10 printf(x); \
11 } while (0)
12#else
13#define dprintf(l, x...) do { if (0) printf(x); } while (0)
14#endif
15
16static void update_job(struct vcpu_info *info, int job)
17{
18 info->fresh = FALSE;
19
20 if (job > info->last_job) {
21 info->last_job = job;
22 snprintf(info->label, LLABEL, "%d:%d",
23 info->sid, info->last_job);
24 }
25}
26
27static int
28try_server_switch_away(struct graph_info *ginfo, struct vcpu_info *vcpu_info,
29 struct record *record, struct plot_info *info)
30{
31 int job, sid, tid, tjob, match, ret = 0;
32 unsigned long long ts;
33
34 match = rt_graph_check_server_switch_away(ginfo, record,
35 &sid, &job,
36 &tid, &tjob, &ts);
37 if (match && tid == vcpu_info->sid) {
38 update_job(vcpu_info, tjob);
39
40 if (vcpu_info->run_time && vcpu_info->run_time < ts) {
41 info->box = TRUE;
42 info->bcolor = hash_cpu(sid - 1);
43 info->bfill = TRUE;
44 info->bstart = vcpu_info->run_time;
45 info->bend = ts;
46 info->blabel = vcpu_info->label;
47 }
48
49 dprintf(3, "VCPU switch away from %d on %d:%d at %llu\n",
50 tid, sid, job, ts);
51 vcpu_info->run_time = 0ULL;
52 vcpu_info->run_cpu = NO_CPU;
53 vcpu_info->run_tid = 0;
54
55 ret = 1;
56 }
57
58 return ret;
59}
60
61static int try_server_switch_to(struct graph_info *ginfo, struct vcpu_info *vcpu_info,
62 struct record *record, struct plot_info *info)
63{
64 int job, sid, tid, tjob, match, ret = 0;
65 unsigned long long ts;
66
67 match = rt_graph_check_server_switch_to(ginfo, record,
68 &sid, &job, &tid, &tjob, &ts);
69 if (match && tid == vcpu_info->sid) {
70 update_job(vcpu_info, tjob);
71 vcpu_info->run_time = ts;
72 vcpu_info->run_cpu = record->cpu;
73 vcpu_info->run_tid = tid;
74 dprintf(3, "Switch to %d for %d:%d at %llu\n",
75 tid, sid, job, ts);
76 ret = 1;
77 }
78 return ret;
79}
80
81/* static int try_switch_to(struct graph_info *ginfo, struct vcpu_info *vcpu_info, */
82/* struct record *record, struct plot_info *info) */
83/* { */
84/* int job, pid, match, ret = 0; */
85/* unsigned long long ts; */
86
87/* match = rt_graph_check_switch_to(ginfo, record, &pid, &job, &ts); */
88/* if (match && pid && pid == vcpu_info->run_tid && vcpu_info->run_time) { */
89/* info->line = TRUE; */
90/* info->lcolor = hash_pid(pid); */
91/* ret = 1; */
92/* } */
93/* return ret; */
94/* } */
95
96/* static int try_switch_away(struct graph_info *ginfo, struct vcpu_info *vcpu_info, */
97/* struct record *record, struct plot_info *info) */
98/* { */
99/* int job, pid, match, ret = 0; */
100/* unsigned long long ts; */
101
102/* match = rt_graph_check_switch_away(ginfo, record, &pid, &job, &ts); */
103/* if (match && pid && pid == vcpu_info->run_tid) { */
104/* info->line = TRUE; */
105/* info->lcolor = hash_pid(pid); */
106/* ret = 1; */
107/* } */
108/* return ret; */
109/* } */
110
111static void do_plot_end(struct graph_info *ginfo, struct vcpu_info *vcpu_info,
112 struct plot_info *info)
113{
114 int tid, job, is_running, tjob;
115 unsigned long long deadline, release;
116 struct record *record;
117
118 if (ginfo->view_end_time == ginfo->end_time)
119 return;
120
121 if (vcpu_info->run_time && vcpu_info->run_cpu != NO_CPU) {
122 info->box = TRUE;
123 info->bcolor = hash_pid(vcpu_info->sid);
124 info->bfill = TRUE;
125 info->bstart = vcpu_info->run_time;
126 info->bend = ginfo->view_end_time;
127 info->blabel = vcpu_info->label;
128 } else if (vcpu_info->fresh) {
129 is_running = get_server_info(ginfo,
130 (struct rt_plot_common*)vcpu_info,
131 vcpu_info->sid,
132 ginfo->view_end_time,
133 &release, &deadline,
134 &job, &tid, &tjob, &record);
135 if (is_running) {
136 update_job(vcpu_info, job);
137 info->box = TRUE;
138 info->bcolor = hash_pid(vcpu_info->sid);
139 info->bfill = TRUE;
140 info->bstart = vcpu_info->run_time;
141 info->bend = ginfo->view_end_time;
142 info->blabel = vcpu_info->label;
143 }
144 }
145}
146
147static int rt_vtask_plot_event(struct graph_info *ginfo, struct graph_plot *plot,
148 struct record *record, struct plot_info *info)
149{
150 int match;
151 struct vcpu_info *vcpu_info = plot->private;
152
153 if (!record) {
154 do_plot_end(ginfo, vcpu_info, info);
155 return 0;
156 }
157
158 match = try_server_switch_away(ginfo, vcpu_info, record, info) ||
159 try_server_switch_to(ginfo, vcpu_info, record, info) ||
160 /* vcpu_try_block(ginfo, vcpu_info, record, info) || */
161 /* vcpu_try_resume(ginfo, vcpu_info, record, info) || */
162 vcpu_try_release(ginfo, vcpu_info, record, info) ||
163 vcpu_try_completion(ginfo, vcpu_info, record, info);
164 /* try_switch_to(ginfo, vcpu_info, record, info) || */
165 /* try_switch_away(ginfo, vcpu_info, record, info); */
166 return match;
167}
168
169const struct plot_callbacks rt_vtask_cb = {
170 .start = rt_vcpu_plot_start,
171 .destroy = rt_vcpu_plot_destroy,
172 .plot_event = rt_vtask_plot_event,
173 .display_last_event = rt_plot_display_last_event,
174 .display_info = rt_plot_display_info,
175 .match_time = rt_plot_match_time,
176 .find_record = rt_plot_find_record,
177};
178
179void insert_vtask(struct graph_info *ginfo, struct cont_list *cont,
180 struct vcpu_list *vcpu_info)
181{
182 struct graph_plot *plot;
183 struct vcpu_info *vtask;
184 char *label;
185
186 vtask = malloc_or_die(sizeof(*vtask));
187 vtask->sid = vcpu_info->sid;
188 vtask->label = malloc_or_die(LLABEL);
189 vtask->cont = cont;
190
191 vtask->common.record_matches = rt_vcpu_plot_record_matches;
192 vtask->common.is_drawn = rt_vcpu_plot_is_drawn;
193 vtask->common.write_header = rt_vcpu_plot_write_header;
194
195 label = malloc_or_die(1);
196 snprintf(label, 2, " ");
197
198 plot = trace_graph_plot_append(ginfo, label, PLOT_TYPE_SERVER_TASK,
199 TIME_TYPE_RT, &rt_vtask_cb, vtask);
200 trace_graph_plot_add_all_recs(ginfo, plot);
201}
diff --git a/rt-plot-vtask.h b/rt-plot-vtask.h
deleted file mode 100644
index 05a026c..0000000
--- a/rt-plot-vtask.h
+++ /dev/null
@@ -1,4 +0,0 @@
1#include "trace-graph.h"
2
3void insert_vtask(struct graph_info *ginfo, struct cont_list *cont,
4 struct vcpu_list *vcpu_info);
diff --git a/trace-graph.c b/trace-graph.c
index 0aa8137..f1a0486 100644
--- a/trace-graph.c
+++ b/trace-graph.c
@@ -1672,7 +1672,7 @@ static void draw_plot_label(struct graph_info *ginfo, char *label,
1672static void draw_plot_box(struct graph_info *ginfo, int i, 1672static void draw_plot_box(struct graph_info *ginfo, int i,
1673 unsigned long long start, 1673 unsigned long long start,
1674 unsigned long long end, 1674 unsigned long long end,
1675 gboolean fill, gboolean thin, 1675 gboolean fill, gboolean thin, gboolean flip,
1676 char *label, GdkGC *gc) 1676 char *label, GdkGC *gc)
1677{ 1677{
1678 gint x1, x2, y, size; 1678 gint x1, x2, y, size;
@@ -1681,7 +1681,12 @@ static void draw_plot_box(struct graph_info *ginfo, int i,
1681 x2 = convert_time_to_x(ginfo, end); 1681 x2 = convert_time_to_x(ginfo, end);
1682 1682
1683 size = (thin) ? PLOT_BOX_SIZE/4 : PLOT_BOX_SIZE; 1683 size = (thin) ? PLOT_BOX_SIZE/4 : PLOT_BOX_SIZE;
1684 y = PLOT_BOX_TOP(i) + (PLOT_BOX_SIZE - size)/2; 1684 if (!flip)
1685 y = PLOT_BOX_TOP(i);
1686 else
1687 y = PLOT_BOX_TOP(i) - PLOT_BOX_SIZE;
1688
1689 y += (PLOT_BOX_SIZE - size)/2;
1685 1690
1686 gdk_draw_rectangle(ginfo->curr_pixmap, gc, 1691 gdk_draw_rectangle(ginfo->curr_pixmap, gc,
1687 fill, 1692 fill,
@@ -1784,71 +1789,74 @@ static void draw_plot(struct graph_info *ginfo, struct graph_plot *plot,
1784 g_object_unref(layout); 1789 g_object_unref(layout);
1785 } 1790 }
1786 1791
1787 trace_graph_plot_event(ginfo, plot, record, &info); 1792 do {
1793 trace_graph_plot_event(ginfo, plot, record, &info);
1788 1794
1789 if (info.box) { 1795 if (info.box) {
1790 if (info.bcolor != plot->last_color) { 1796 if (info.bcolor != plot->last_color) {
1791 plot->last_color = info.bcolor; 1797 plot->last_color = info.bcolor;
1792 set_color(ginfo->draw, plot->gc, plot->last_color); 1798 set_color(ginfo->draw, plot->gc, plot->last_color);
1793 } 1799 }
1794 1800
1795 draw_plot_box(ginfo, plot->pos, info.bstart, info.bend, 1801 draw_plot_box(ginfo, plot->pos, info.bstart, info.bend,
1796 info.bfill, info.bthin, info.blabel, plot->gc); 1802 info.bfill, info.bthin, info.flip,
1797 } 1803 info.blabel, plot->gc);
1804 }
1798 1805
1799 if (info.release && is_high_res(ginfo)) { 1806 if (info.release && is_high_res(ginfo)) {
1800 if (plot->last_color != 0) { 1807 if (plot->last_color != 0) {
1801 plot->last_color = 0; 1808 plot->last_color = 0;
1802 set_color(ginfo->draw, plot->gc, plot->last_color); 1809 set_color(ginfo->draw, plot->gc, plot->last_color);
1810 }
1811 draw_plot_release(ginfo, plot->pos, info.rtime, plot->gc);
1803 } 1812 }
1804 draw_plot_release(ginfo, plot->pos, info.rtime, plot->gc);
1805 }
1806 1813
1807 if (info.deadline && is_high_res(ginfo)) { 1814 if (info.deadline && is_high_res(ginfo)) {
1808 if (plot->last_color != 0) { 1815 if (plot->last_color != 0) {
1809 plot->last_color = 0; 1816 plot->last_color = 0;
1810 set_color(ginfo->draw, plot->gc, plot->last_color); 1817 set_color(ginfo->draw, plot->gc, plot->last_color);
1818 }
1819 draw_plot_deadline(ginfo, plot->pos, info.dtime, plot->gc);
1811 } 1820 }
1812 draw_plot_deadline(ginfo, plot->pos, info.dtime, plot->gc);
1813 }
1814 1821
1815 if (info.completion && is_high_res(ginfo)) { 1822 if (info.completion && is_high_res(ginfo)) {
1816 if (plot->last_color != 0) { 1823 if (plot->last_color != 0) {
1817 plot->last_color = 0; 1824 plot->last_color = 0;
1818 set_color(ginfo->draw, plot->gc, plot->last_color); 1825 set_color(ginfo->draw, plot->gc, plot->last_color);
1826 }
1827 draw_plot_completion(ginfo, plot->pos, info.ctime, plot->gc);
1819 } 1828 }
1820 draw_plot_completion(ginfo, plot->pos, info.ctime, plot->gc);
1821 }
1822 1829
1823 1830
1824 if (info.line) { 1831 if (info.line) {
1825 if (info.lcolor != plot->last_color) { 1832 if (info.lcolor != plot->last_color) {
1826 plot->last_color = info.lcolor; 1833 plot->last_color = info.lcolor;
1827 set_color(ginfo->draw, plot->gc, plot->last_color); 1834 set_color(ginfo->draw, plot->gc, plot->last_color);
1828 } 1835 }
1829 1836
1830 x = draw_plot_line(ginfo, plot->pos, info.ltime, info.lsmall, plot->gc); 1837 x = draw_plot_line(ginfo, plot->pos, info.ltime, info.lsmall, plot->gc);
1831 1838
1832 /* Figure out if we can show the text for the previous record */ 1839 /* Figure out if we can show the text for the previous record */
1833 1840
1834 plot->p3 = x; 1841 plot->p3 = x;
1835 1842
1836 /* Make sure p2 will be non-zero the next iteration */ 1843 /* Make sure p2 will be non-zero the next iteration */
1837 if (!plot->p3) 1844 if (!plot->p3)
1838 plot->p3 = 1; 1845 plot->p3 = 1;
1839 1846
1840 /* first record, continue */ 1847 /* first record, continue */
1841 if (plot->p2) 1848 if (plot->p2)
1842 plot->p2 = draw_event_label(ginfo, plot->pos, 1849 plot->p2 = draw_event_label(ginfo, plot->pos,
1843 plot->p1, plot->p2, plot->p3, width_16, font); 1850 plot->p1, plot->p2, plot->p3, width_16, font);
1844 1851
1845 plot->p1 = plot->p2; 1852 plot->p1 = plot->p2;
1846 plot->p2 = plot->p3; 1853 plot->p2 = plot->p3;
1847 } 1854 }
1848 1855
1849 if (!record && plot->p2) 1856 if (!record && plot->p2)
1850 draw_event_label(ginfo, plot->pos, 1857 draw_event_label(ginfo, plot->pos,
1851 plot->p1, plot->p2, ginfo->draw_width, width_16, font); 1858 plot->p1, plot->p2, ginfo->draw_width, width_16, font);
1859 } while (info.repeat);
1852} 1860}
1853 1861
1854/* 1862/*
diff --git a/trace-graph.h b/trace-graph.h
index b3eff57..249e800 100644
--- a/trace-graph.h
+++ b/trace-graph.h
@@ -88,6 +88,9 @@ struct plot_info {
88 gboolean dbox; 88 gboolean dbox;
89 unsigned long long dbtime; 89 unsigned long long dbtime;
90 char *dblabel; 90 char *dblabel;
91
92 gboolean flip;
93 gboolean repeat;
91}; 94};
92 95
93/* 96/*
diff --git a/trace-plot.c b/trace-plot.c
index 8551a34..c3b849c 100644
--- a/trace-plot.c
+++ b/trace-plot.c
@@ -345,16 +345,7 @@ int trace_graph_plot_event(struct graph_info *ginfo,
345 struct record *record, 345 struct record *record,
346 struct plot_info *info) 346 struct plot_info *info)
347{ 347{
348 info->line = FALSE; 348 memset(info,0, sizeof(*info));
349 info->box = FALSE;
350 info->bfill = TRUE;
351 info->lsmall = FALSE;
352
353 info->blabel = NULL;
354 info->bthin = FALSE;
355 info->release = FALSE;
356 info->deadline = FALSE;
357 info->completion = FALSE;
358 349
359 if (!plot->cb->plot_event) 350 if (!plot->cb->plot_event)
360 return 0; 351 return 0;