diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2012-03-16 16:40:37 -0400 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2012-03-16 16:40:37 -0400 |
commit | cc295d3e4924efd31c268a57f01b1412c6513301 (patch) | |
tree | 60a4f1e70a5dc0607330b18d24336f8b2fea5462 | |
parent | 1ceec23c6817d0d3cba77ea0e17b95a9fc506d42 (diff) |
containers: added record parsing
-rwxr-xr-x | make_cscope_database.sh | 5 | ||||
-rw-r--r-- | rt-graph.c | 705 | ||||
-rw-r--r-- | rt-graph.h | 140 | ||||
-rw-r--r-- | rt-plot-cpu.c | 37 | ||||
-rw-r--r-- | rt-plot-cpu.h | 1 | ||||
-rw-r--r-- | rt-plot-task.c | 47 | ||||
-rw-r--r-- | trace-graph.c | 4 | ||||
-rw-r--r-- | trace-plot-cpu.c | 5 |
8 files changed, 721 insertions, 223 deletions
diff --git a/make_cscope_database.sh b/make_cscope_database.sh new file mode 100755 index 0000000..c1edd2e --- /dev/null +++ b/make_cscope_database.sh | |||
@@ -0,0 +1,5 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | CSCOPE_FILES="cscope.files" | ||
4 | find . -name "*.[ch]" -print > "${CSCOPE_FILES}" | ||
5 | cscope -b -q -k \ No newline at end of file | ||
@@ -1,7 +1,9 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <string.h. | ||
1 | #include "trace-graph.h" | 3 | #include "trace-graph.h" |
2 | #include "trace-hash.h" | 4 | #include "trace-hash.h" |
3 | 5 | ||
4 | #define DEBUG_LEVEL 3 | 6 | #define DEBUG_LEVEL 0 |
5 | #if DEBUG_LEVEL > 0 | 7 | #if DEBUG_LEVEL > 0 |
6 | #define dprintf(l, x...) \ | 8 | #define dprintf(l, x...) \ |
7 | do { \ | 9 | do { \ |
@@ -17,6 +19,47 @@ static guint get_event_hash_key(gint eid) | |||
17 | return trace_hash(eid) % TS_HASH_SIZE; | 19 | return trace_hash(eid) % TS_HASH_SIZE; |
18 | } | 20 | } |
19 | 21 | ||
22 | static int get_container_key(gint cid) | ||
23 | { | ||
24 | return trace_hash(cid) % CONT_HASH_SIZE; | ||
25 | } | ||
26 | |||
27 | /* | ||
28 | * Returns string value stored in @field. | ||
29 | */ | ||
30 | static char* read_string_field(struct format_field *field, | ||
31 | struct record *record) | ||
32 | { | ||
33 | char *name, *loc; | ||
34 | |||
35 | loc = (char*)(record->data + field->offset); | ||
36 | name = malloc_or_die(field->size); | ||
37 | snprintf(name, field->size, "%s", loc); | ||
38 | return name; | ||
39 | } | ||
40 | |||
41 | #define __FIELD(type, name) type##_##name##_field | ||
42 | #define FIELD(rtg, type, name) rtg->__FIELD(type, name) | ||
43 | #define STORE_FIELD(rtg, e, type, name) \ | ||
44 | do { \ | ||
45 | FIELD(rtg, type, name) = pevent_find_field(e, #name); \ | ||
46 | } while (0) | ||
47 | #define LOAD_LONG(rtg, r, type, name, v) \ | ||
48 | do { \ | ||
49 | pevent_read_number_field(FIELD(rtg, type, name), \ | ||
50 | r->data, v); \ | ||
51 | } while (0) | ||
52 | #define LOAD_INT(rtg, r, type, name, v) \ | ||
53 | do { \ | ||
54 | unsigned long long val; \ | ||
55 | LOAD_LONG(rtg, r, type, name, &val); \ | ||
56 | *v = val; \ | ||
57 | } while (0) | ||
58 | #define LOAD_STRING(rtg, r, type, name, v) \ | ||
59 | do { \ | ||
60 | *v = read_string_field(FIELD(rtg, type, name), r); \ | ||
61 | } while (0) | ||
62 | |||
20 | /* | 63 | /* |
21 | * Returns cached field for @eid at @key. | 64 | * Returns cached field for @eid at @key. |
22 | */ | 65 | */ |
@@ -36,7 +79,8 @@ struct format_field* find_ts_hash(struct ts_list **events, | |||
36 | */ | 79 | */ |
37 | static struct format_field* | 80 | static struct format_field* |
38 | add_ts_hash(struct ts_list **events, gint eid, gint key, | 81 | add_ts_hash(struct ts_list **events, gint eid, gint key, |
39 | struct pevent *pevent, struct record *record) | 82 | struct pevent *pevent, |
83 | struct record *record) | ||
40 | { | 84 | { |
41 | struct ts_list *list; | 85 | struct ts_list *list; |
42 | struct format_field *field; | 86 | struct format_field *field; |
@@ -56,17 +100,93 @@ add_ts_hash(struct ts_list **events, gint eid, gint key, | |||
56 | return field; | 100 | return field; |
57 | } | 101 | } |
58 | 102 | ||
103 | /* | ||
104 | * Return container for @cid and @key, if present. | ||
105 | */ | ||
106 | static struct cont_list* | ||
107 | find_container(struct cont_list **conts, gint cid, gint key) | ||
108 | { | ||
109 | struct cont_list *list; | ||
110 | for (list = conts[key]; list; list = list->next) { | ||
111 | if (list->cid == cid) | ||
112 | return list; | ||
113 | } | ||
114 | return NULL; | ||
115 | } | ||
116 | |||
117 | /* | ||
118 | * Add and return container with @cid and @name to @conts. | ||
119 | */ | ||
120 | static struct cont_list* | ||
121 | add_container(struct cont_list **conts, gint cid, char *name) | ||
122 | { | ||
123 | int key; | ||
124 | struct cont_list *list; | ||
125 | |||
126 | key = get_container_key(cid); | ||
127 | |||
128 | list = find_container(conts, cid, key); | ||
129 | if (!list) { | ||
130 | list = malloc_or_die(sizeof(*list)); | ||
131 | list->cid = cid; | ||
132 | list->name = name; | ||
133 | list->vcpus = NULL; | ||
134 | |||
135 | list->next = conts[key]; | ||
136 | conts[key] = list; | ||
137 | } else { | ||
138 | free(name); | ||
139 | } | ||
140 | return list; | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * Add and return server with @sid to container @cid. | ||
145 | */ | ||
146 | static struct vcpu_list* | ||
147 | add_vcpu(struct cont_list **conts, | ||
148 | int cid, int sid, | ||
149 | unsigned long long wcet, unsigned long long period) | ||
150 | { | ||
151 | int key; | ||
152 | struct cont_list *clist; | ||
153 | struct vcpu_list *vlist; | ||
154 | |||
155 | key = get_container_key(cid); | ||
156 | clist = find_container(conts, cid, key); | ||
157 | if (!clist) | ||
158 | die("Cannot add server %d to non-existant container %d!\n", | ||
159 | sid, cid); | ||
160 | |||
161 | for (vlist = clist->vcpus; vlist; vlist = vlist->next) { | ||
162 | if (vlist->sid == sid) | ||
163 | return vlist; | ||
164 | } | ||
165 | |||
166 | vlist = malloc_or_die(sizeof(*vlist)); | ||
167 | vlist->sid = sid; | ||
168 | vlist->params.wcet = wcet; | ||
169 | vlist->params.period = period; | ||
170 | |||
171 | vlist->next = clist->vcpus; | ||
172 | clist->vcpus = vlist; | ||
173 | |||
174 | return vlist; | ||
175 | } | ||
176 | |||
59 | /** | 177 | /** |
60 | * rt_graph_check_any - parse timestamp of any record | 178 | * rt_graph_check_any - parse timestamp of any record |
61 | * @epid: set to the event's task PID | 179 | * @epid: set to the event's task PID |
62 | * @rt_ts: set to the event's real-time timestamp | 180 | * @rt_ts: set to the event's real-time timestamp |
63 | */ | 181 | */ |
64 | int rt_graph_check_any(struct rt_graph_info *rtg_info, | 182 | int rt_graph_check_any(struct graph_info *ginfo, |
65 | struct pevent *pevent, struct record *record, | 183 | struct record *record, |
66 | gint *epid, gint *out_eid, unsigned long long *ts) | 184 | gint *epid, gint *out_eid, unsigned long long *ts) |
67 | { | 185 | { |
68 | guint key, eid; | 186 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; |
187 | struct pevent *pevent = ginfo->pevent; | ||
69 | struct format_field *field; | 188 | struct format_field *field; |
189 | guint key, eid; | ||
70 | 190 | ||
71 | eid = pevent_data_type(pevent, record); | 191 | eid = pevent_data_type(pevent, record); |
72 | key = get_event_hash_key(eid); | 192 | key = get_event_hash_key(eid); |
@@ -86,17 +206,19 @@ int rt_graph_check_any(struct rt_graph_info *rtg_info, | |||
86 | 206 | ||
87 | /** | 207 | /** |
88 | * rt_graph_check_task_param - check for litmus_task_param record | 208 | * rt_graph_check_task_param - check for litmus_task_param record |
89 | * Return 1 and @pid, @out_wcet, and @out_period if the record matches | 209 | * Return 1 and @pid, @owcet, and @operiod if the record matches |
90 | */ | 210 | */ |
91 | int rt_graph_check_task_param(struct rt_graph_info *rtg_info, | 211 | int rt_graph_check_task_param(struct graph_info *ginfo, |
92 | struct pevent *pevent, struct record *record, | 212 | struct record *record, |
93 | gint *pid, unsigned long long *out_wcet, | 213 | gint *pid, unsigned long long *owcet, |
94 | unsigned long long *out_period) | 214 | unsigned long long *operiod) |
95 | { | 215 | { |
216 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
217 | struct pevent *pevent = ginfo->pevent; | ||
96 | struct event_format *event; | 218 | struct event_format *event; |
97 | struct rt_task_params *params; | 219 | struct rt_task_params *params; |
98 | struct task_list *list; | 220 | struct task_list *list; |
99 | unsigned long long val, wcet, period; | 221 | unsigned long long wcet, period; |
100 | gint id; | 222 | gint id; |
101 | int ret = 0; | 223 | int ret = 0; |
102 | 224 | ||
@@ -111,42 +233,35 @@ int rt_graph_check_task_param(struct rt_graph_info *rtg_info, | |||
111 | goto out; | 233 | goto out; |
112 | rtg_info->task_param_id = event->id; | 234 | rtg_info->task_param_id = event->id; |
113 | dprintf(2, "Found task_param id %d\n", event->id); | 235 | dprintf(2, "Found task_param id %d\n", event->id); |
114 | rtg_info->param_pid_field = pevent_find_field(event, "pid"); | 236 | STORE_FIELD(rtg_info, event, param, pid); |
115 | rtg_info->param_wcet_field = pevent_find_field(event, "wcet"); | 237 | STORE_FIELD(rtg_info, event, param, wcet); |
116 | rtg_info->param_period_field = pevent_find_field(event, "period"); | 238 | STORE_FIELD(rtg_info, event, param, period); |
117 | } | 239 | } |
118 | 240 | ||
119 | id = pevent_data_type(pevent, record); | 241 | id = pevent_data_type(pevent, record); |
120 | if (id == rtg_info->task_param_id) { | 242 | if (id == rtg_info->task_param_id) { |
121 | pevent_read_number_field(rtg_info->param_pid_field, | 243 | LOAD_INT(rtg_info, record, param, pid, pid); |
122 | record->data, &val); | 244 | LOAD_LONG(rtg_info, record, param, wcet, &wcet); |
123 | *pid = val; | 245 | LOAD_LONG(rtg_info, record, param, wcet, &period); |
124 | pevent_read_number_field(rtg_info->param_wcet_field, | 246 | |
125 | record->data, &wcet); | ||
126 | pevent_read_number_field(rtg_info->param_period_field, | ||
127 | record->data, &period); | ||
128 | ret = 1; | 247 | ret = 1; |
129 | dprintf(3, "Read task_param (%d) record for task %d " | 248 | dprintf(3, "Read task_param record for task %d (%llu, %llu)\n", |
130 | "(%llu, %llu)\n", id, *pid, wcet, period); | 249 | *pid, wcet, period); |
131 | 250 | ||
132 | list = add_task_hash(rtg_info->tasks, *pid); | 251 | list = add_task_hash(rtg_info->tasks, *pid); |
133 | if (!list->data) { | 252 | if (!list->data) { |
134 | /* If this pid is plotted, sections of time might later | ||
135 | * be viewed which are after this _param event. In this | ||
136 | * case, that plot would never read a _param event and | ||
137 | * would not know about the task's wcet and deadline. | ||
138 | * Store them with the task to avoid this issue. | ||
139 | */ | ||
140 | params = malloc_or_die(sizeof(*params)); | 253 | params = malloc_or_die(sizeof(*params)); |
141 | params->wcet = wcet; | 254 | params->wcet = wcet; |
142 | params->period = period; | 255 | params->period = period; |
143 | list->data = params; | 256 | list->data = params; |
144 | } | 257 | } |
145 | 258 | ||
259 | /* Store max period to calculate max search distance */ | ||
146 | if (period > rtg_info->max_period) | 260 | if (period > rtg_info->max_period) |
147 | rtg_info->max_period = period; | 261 | rtg_info->max_period = period; |
148 | *out_wcet = wcet; | 262 | |
149 | *out_period = period; | 263 | *owcet = wcet; |
264 | *operiod = period; | ||
150 | } | 265 | } |
151 | out: | 266 | out: |
152 | return ret; | 267 | return ret; |
@@ -156,13 +271,14 @@ int rt_graph_check_task_param(struct rt_graph_info *rtg_info, | |||
156 | * rt_graph_check_switch_to - check for litmus_switch_to record | 271 | * rt_graph_check_switch_to - check for litmus_switch_to record |
157 | * Return 1 and @pid, @job, and @ts if the record matches | 272 | * Return 1 and @pid, @job, and @ts if the record matches |
158 | */ | 273 | */ |
159 | int rt_graph_check_switch_to(struct rt_graph_info *rtg_info, | 274 | int rt_graph_check_switch_to(struct graph_info *ginfo, |
160 | struct pevent *pevent, struct record *record, | 275 | struct record *record, |
161 | gint *pid, gint *job, | 276 | gint *pid, gint *job, |
162 | unsigned long long *ts) | 277 | unsigned long long *ts) |
163 | { | 278 | { |
279 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
280 | struct pevent *pevent = ginfo->pevent; | ||
164 | struct event_format *event; | 281 | struct event_format *event; |
165 | unsigned long long val; | ||
166 | gint id; | 282 | gint id; |
167 | int ret = 0; | 283 | int ret = 0; |
168 | 284 | ||
@@ -172,22 +288,16 @@ int rt_graph_check_switch_to(struct rt_graph_info *rtg_info, | |||
172 | if (!event) | 288 | if (!event) |
173 | goto out; | 289 | goto out; |
174 | rtg_info->switch_to_id = event->id; | 290 | rtg_info->switch_to_id = event->id; |
175 | dprintf(2, "Found switch_to id %d\n", event->id); | 291 | STORE_FIELD(rtg_info, event, switch_to, pid); |
176 | rtg_info->switch_to_pid_field = pevent_find_field(event, "pid"); | 292 | STORE_FIELD(rtg_info, event, switch_to, job); |
177 | rtg_info->switch_to_job_field = pevent_find_field(event, "job"); | ||
178 | rtg_info->switch_to_ts_field = pevent_find_field(event, RT_TS_FIELD); | ||
179 | } | 293 | } |
180 | 294 | ||
181 | id = pevent_data_type(pevent, record); | 295 | id = pevent_data_type(pevent, record); |
182 | if (id == rtg_info->switch_to_id) { | 296 | if (id == rtg_info->switch_to_id) { |
183 | pevent_read_number_field(rtg_info->switch_to_pid_field, | 297 | LOAD_INT(rtg_info, record, switch_to, pid, pid); |
184 | record->data, &val); | 298 | LOAD_INT(rtg_info, record, switch_to, job, job); |
185 | *pid = val; | 299 | *ts = get_rts(ginfo, record); |
186 | pevent_read_number_field(rtg_info->switch_to_job_field, | 300 | |
187 | record->data, &val); | ||
188 | *job = val; | ||
189 | pevent_read_number_field(rtg_info->switch_to_ts_field, | ||
190 | record->data, ts); | ||
191 | ret = 1; | 301 | ret = 1; |
192 | dprintf(3, "Read switch_to (%d) record for job %d:%d, " | 302 | dprintf(3, "Read switch_to (%d) record for job %d:%d, " |
193 | "ts: %llu\n", id, *pid, *job, *ts); | 303 | "ts: %llu\n", id, *pid, *job, *ts); |
@@ -200,13 +310,14 @@ int rt_graph_check_switch_to(struct rt_graph_info *rtg_info, | |||
200 | * rt_graph_check_switch_away - check for litmus_switch_away record | 310 | * rt_graph_check_switch_away - check for litmus_switch_away record |
201 | * Return 1 and @pid, @job, and @ts if the record matches | 311 | * Return 1 and @pid, @job, and @ts if the record matches |
202 | */ | 312 | */ |
203 | int rt_graph_check_switch_away(struct rt_graph_info *rtg_info, | 313 | int rt_graph_check_switch_away(struct graph_info *ginfo, |
204 | struct pevent *pevent, struct record *record, | 314 | struct record *record, |
205 | gint *pid, gint *job, | 315 | gint *pid, gint *job, |
206 | unsigned long long *ts) | 316 | unsigned long long *ts) |
207 | { | 317 | { |
318 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
319 | struct pevent *pevent = ginfo->pevent; | ||
208 | struct event_format *event; | 320 | struct event_format *event; |
209 | unsigned long long val; | ||
210 | gint id; | 321 | gint id; |
211 | int ret = 0; | 322 | int ret = 0; |
212 | 323 | ||
@@ -217,21 +328,16 @@ int rt_graph_check_switch_away(struct rt_graph_info *rtg_info, | |||
217 | goto out; | 328 | goto out; |
218 | rtg_info->switch_away_id = event->id; | 329 | rtg_info->switch_away_id = event->id; |
219 | dprintf(2, "Found switch_away id %d\n", event->id); | 330 | dprintf(2, "Found switch_away id %d\n", event->id); |
220 | rtg_info->switch_away_pid_field = pevent_find_field(event, "pid"); | 331 | STORE_FIELD(rtg_info, event, switch_away, pid); |
221 | rtg_info->switch_away_job_field = pevent_find_field(event, "job"); | 332 | STORE_FIELD(rtg_info, event, switch_away, job); |
222 | rtg_info->switch_away_ts_field = pevent_find_field(event, RT_TS_FIELD); | ||
223 | } | 333 | } |
224 | 334 | ||
225 | id = pevent_data_type(pevent, record); | 335 | id = pevent_data_type(pevent, record); |
226 | if (id == rtg_info->switch_away_id) { | 336 | if (id == rtg_info->switch_away_id) { |
227 | pevent_read_number_field(rtg_info->switch_away_pid_field, | 337 | LOAD_INT(rtg_info, record, switch_away, pid, pid); |
228 | record->data, &val); | 338 | LOAD_INT(rtg_info, record, switch_away, job, job); |
229 | *pid = val; | 339 | *ts = get_rts(ginfo, record); |
230 | pevent_read_number_field(rtg_info->switch_away_job_field, | 340 | |
231 | record->data, &val); | ||
232 | *job = val; | ||
233 | pevent_read_number_field(rtg_info->switch_away_ts_field, | ||
234 | record->data, ts); | ||
235 | ret = 1; | 341 | ret = 1; |
236 | dprintf(3, "Read switch_away (%d) record for job %d:%d, " | 342 | dprintf(3, "Read switch_away (%d) record for job %d:%d, " |
237 | "ts: %llu\n", id, *pid, *job, *ts); | 343 | "ts: %llu\n", id, *pid, *job, *ts); |
@@ -244,14 +350,15 @@ int rt_graph_check_switch_away(struct rt_graph_info *rtg_info, | |||
244 | * rt_graph_check_task_release - check for litmus_task_release record | 350 | * rt_graph_check_task_release - check for litmus_task_release record |
245 | * Return 1 and @pid, @job, @release, and @deadline if the record matches | 351 | * Return 1 and @pid, @job, @release, and @deadline if the record matches |
246 | */ | 352 | */ |
247 | int rt_graph_check_task_release(struct rt_graph_info *rtg_info, | 353 | int rt_graph_check_task_release(struct graph_info *ginfo, |
248 | struct pevent *pevent, struct record *record, | 354 | struct record *record, |
249 | gint *pid, gint *job, | 355 | gint *pid, gint *job, |
250 | unsigned long long *release, | 356 | unsigned long long *release, |
251 | unsigned long long *deadline) | 357 | unsigned long long *deadline) |
252 | { | 358 | { |
359 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
360 | struct pevent *pevent = ginfo->pevent; | ||
253 | struct event_format *event; | 361 | struct event_format *event; |
254 | unsigned long long val; | ||
255 | gint id; | 362 | gint id; |
256 | int ret = 0; | 363 | int ret = 0; |
257 | 364 | ||
@@ -262,24 +369,19 @@ int rt_graph_check_task_release(struct rt_graph_info *rtg_info, | |||
262 | goto out; | 369 | goto out; |
263 | rtg_info->task_release_id = event->id; | 370 | rtg_info->task_release_id = event->id; |
264 | dprintf(2, "Found task_release id %d\n", event->id); | 371 | dprintf(2, "Found task_release id %d\n", event->id); |
265 | rtg_info->release_pid_field = pevent_find_field(event, "pid"); | 372 | STORE_FIELD(rtg_info, event, release, pid); |
266 | rtg_info->release_job_field = pevent_find_field(event, "job"); | 373 | STORE_FIELD(rtg_info, event, release, job); |
267 | rtg_info->release_release_field = pevent_find_field(event, "release"); | 374 | STORE_FIELD(rtg_info, event, release, release); |
268 | rtg_info->release_deadline_field = pevent_find_field(event, "deadline"); | 375 | STORE_FIELD(rtg_info, event, release, deadline); |
269 | } | 376 | } |
270 | 377 | ||
271 | id = pevent_data_type(pevent, record); | 378 | id = pevent_data_type(pevent, record); |
272 | if (id == rtg_info->task_release_id) { | 379 | if (id == rtg_info->task_release_id) { |
273 | pevent_read_number_field(rtg_info->release_pid_field, | 380 | LOAD_INT(rtg_info, record, release, pid, pid); |
274 | record->data, &val); | 381 | LOAD_INT(rtg_info, record, release, job, job); |
275 | *pid = val; | 382 | LOAD_LONG(rtg_info, record, release, release, release); |
276 | pevent_read_number_field(rtg_info->release_job_field, | 383 | LOAD_LONG(rtg_info, record, release, deadline, deadline); |
277 | record->data, &val); | 384 | |
278 | *job = val; | ||
279 | pevent_read_number_field(rtg_info->release_release_field, | ||
280 | record->data, release); | ||
281 | pevent_read_number_field(rtg_info->release_deadline_field, | ||
282 | record->data, deadline); | ||
283 | ret = 1; | 385 | ret = 1; |
284 | dprintf(3, "Read task_release (%d) record for job %d:%d, " | 386 | dprintf(3, "Read task_release (%d) record for job %d:%d, " |
285 | "release: %llu, dead: %llu\n", id, *pid, *job, *release, | 387 | "release: %llu, dead: %llu\n", id, *pid, *job, *release, |
@@ -293,12 +395,13 @@ int rt_graph_check_task_release(struct rt_graph_info *rtg_info, | |||
293 | * rt_graph_check_task_completion - check for litmus_task_completion record | 395 | * rt_graph_check_task_completion - check for litmus_task_completion record |
294 | * Return 1 and @pid, @job, and @ts if the record matches | 396 | * Return 1 and @pid, @job, and @ts if the record matches |
295 | */ | 397 | */ |
296 | int rt_graph_check_task_completion(struct rt_graph_info *rtg_info, | 398 | int rt_graph_check_task_completion(struct graph_info *ginfo, |
297 | struct pevent *pevent, struct record *record, | 399 | struct record *record, |
298 | gint *pid, gint *job, unsigned long long *ts) | 400 | gint *pid, gint *job, unsigned long long *ts) |
299 | { | 401 | { |
402 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
403 | struct pevent *pevent = ginfo->pevent; | ||
300 | struct event_format *event; | 404 | struct event_format *event; |
301 | unsigned long long val; | ||
302 | gint id; | 405 | gint id; |
303 | int ret = 0; | 406 | int ret = 0; |
304 | 407 | ||
@@ -309,21 +412,15 @@ int rt_graph_check_task_completion(struct rt_graph_info *rtg_info, | |||
309 | goto out; | 412 | goto out; |
310 | rtg_info->task_completion_id = event->id; | 413 | rtg_info->task_completion_id = event->id; |
311 | dprintf(2, "Found task_completion id %d\n", event->id); | 414 | dprintf(2, "Found task_completion id %d\n", event->id); |
312 | rtg_info->completion_pid_field = pevent_find_field(event, "pid"); | 415 | STORE_FIELD(rtg_info, event, completion, pid); |
313 | rtg_info->completion_job_field = pevent_find_field(event, "job"); | 416 | STORE_FIELD(rtg_info, event, completion, job); |
314 | rtg_info->completion_ts_field = pevent_find_field(event, RT_TS_FIELD); | ||
315 | } | 417 | } |
316 | 418 | ||
317 | id = pevent_data_type(pevent, record); | 419 | id = pevent_data_type(pevent, record); |
318 | if (id == rtg_info->task_completion_id) { | 420 | if (id == rtg_info->task_completion_id) { |
319 | pevent_read_number_field(rtg_info->completion_pid_field, | 421 | LOAD_INT(rtg_info, record, completion, pid, pid); |
320 | record->data, &val); | 422 | LOAD_INT(rtg_info, record, completion, job, job); |
321 | *pid = val; | 423 | |
322 | pevent_read_number_field(rtg_info->completion_job_field, | ||
323 | record->data, &val); | ||
324 | *job = val; | ||
325 | pevent_read_number_field(rtg_info->completion_ts_field, | ||
326 | record->data, ts); | ||
327 | ret = 1; | 424 | ret = 1; |
328 | dprintf(3, "Read task_completion (%d) record for job %d:%d " | 425 | dprintf(3, "Read task_completion (%d) record for job %d:%d " |
329 | "ts: %llu\n", id, *pid, *job, *ts); | 426 | "ts: %llu\n", id, *pid, *job, *ts); |
@@ -336,12 +433,13 @@ int rt_graph_check_task_completion(struct rt_graph_info *rtg_info, | |||
336 | * rt_graph_check_task_block - check for litmus_task_block record | 433 | * rt_graph_check_task_block - check for litmus_task_block record |
337 | * Return 1, @pid, and @ts if the record matches | 434 | * Return 1, @pid, and @ts if the record matches |
338 | */ | 435 | */ |
339 | int rt_graph_check_task_block(struct rt_graph_info *rtg_info, | 436 | int rt_graph_check_task_block(struct graph_info *ginfo, |
340 | struct pevent *pevent, struct record *record, | 437 | struct record *record, |
341 | gint *pid, unsigned long long *ts) | 438 | gint *pid, unsigned long long *ts) |
342 | { | 439 | { |
440 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
441 | struct pevent *pevent = ginfo->pevent; | ||
343 | struct event_format *event; | 442 | struct event_format *event; |
344 | unsigned long long val; | ||
345 | gint id; | 443 | gint id; |
346 | int ret = 0; | 444 | int ret = 0; |
347 | 445 | ||
@@ -351,18 +449,14 @@ int rt_graph_check_task_block(struct rt_graph_info *rtg_info, | |||
351 | if (!event) | 449 | if (!event) |
352 | goto out; | 450 | goto out; |
353 | dprintf(2, "Found task_block id %d\n", event->id); | 451 | dprintf(2, "Found task_block id %d\n", event->id); |
354 | rtg_info->task_block_id = event->id; | 452 | STORE_FIELD(rtg_info, event, block, pid); |
355 | rtg_info->block_pid_field = pevent_find_field(event, "pid"); | ||
356 | rtg_info->block_ts_field = pevent_find_field(event, RT_TS_FIELD); | ||
357 | } | 453 | } |
358 | 454 | ||
359 | id = pevent_data_type(pevent, record); | 455 | id = pevent_data_type(pevent, record); |
360 | if (id == rtg_info->task_block_id) { | 456 | if (id == rtg_info->task_block_id) { |
361 | pevent_read_number_field(rtg_info->block_pid_field, | 457 | LOAD_INT(rtg_info, record, block, pid, pid); |
362 | record->data, &val); | 458 | *ts = get_rts(ginfo, record); |
363 | *pid = val; | 459 | |
364 | pevent_read_number_field(rtg_info->block_ts_field, | ||
365 | record->data, ts); | ||
366 | ret = 1; | 460 | ret = 1; |
367 | dprintf(3, "Read task_block (%d) record for task %d\n", | 461 | dprintf(3, "Read task_block (%d) record for task %d\n", |
368 | id, *pid); | 462 | id, *pid); |
@@ -373,14 +467,15 @@ int rt_graph_check_task_block(struct rt_graph_info *rtg_info, | |||
373 | 467 | ||
374 | /** | 468 | /** |
375 | * rt_graph_check_task_resume - check for litmus_task_resume record | 469 | * rt_graph_check_task_resume - check for litmus_task_resume record |
376 | * Return 1 and @pid if the record matches | 470 | * Return 1, @pid, and @ts if the record matches |
377 | */ | 471 | */ |
378 | int rt_graph_check_task_resume(struct rt_graph_info *rtg_info, | 472 | int rt_graph_check_task_resume(struct graph_info *ginfo, |
379 | struct pevent *pevent, struct record *record, | 473 | struct record *record, |
380 | gint *pid, unsigned long long *ts) | 474 | gint *pid, unsigned long long *ts) |
381 | { | 475 | { |
476 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
477 | struct pevent *pevent = ginfo->pevent; | ||
382 | struct event_format *event; | 478 | struct event_format *event; |
383 | unsigned long long val; | ||
384 | gint id; | 479 | gint id; |
385 | int ret = 0; | 480 | int ret = 0; |
386 | 481 | ||
@@ -390,18 +485,14 @@ int rt_graph_check_task_resume(struct rt_graph_info *rtg_info, | |||
390 | if (!event) | 485 | if (!event) |
391 | goto out; | 486 | goto out; |
392 | dprintf(2, "Found task_resume id %d\n", event->id); | 487 | dprintf(2, "Found task_resume id %d\n", event->id); |
393 | rtg_info->task_resume_id = event->id; | 488 | STORE_FIELD(rtg_info, event, resume, pid); |
394 | rtg_info->resume_pid_field = pevent_find_field(event, "pid"); | ||
395 | rtg_info->resume_ts_field = pevent_find_field(event, RT_TS_FIELD); | ||
396 | } | 489 | } |
397 | 490 | ||
398 | id = pevent_data_type(pevent, record); | 491 | id = pevent_data_type(pevent, record); |
399 | if (id == rtg_info->task_resume_id) { | 492 | if (id == rtg_info->task_resume_id) { |
400 | pevent_read_number_field(rtg_info->resume_pid_field, | 493 | LOAD_INT(rtg_info, record, resume, pid, pid); |
401 | record->data, &val); | 494 | *ts = get_rts(ginfo, record); |
402 | *pid = val; | 495 | |
403 | pevent_read_number_field(rtg_info->resume_ts_field, | ||
404 | record->data, ts); | ||
405 | ret = 1; | 496 | ret = 1; |
406 | dprintf(3, "Read task_resume (%d) record for task %d\n", | 497 | dprintf(3, "Read task_resume (%d) record for task %d\n", |
407 | id, *pid); | 498 | id, *pid); |
@@ -411,11 +502,342 @@ int rt_graph_check_task_resume(struct rt_graph_info *rtg_info, | |||
411 | } | 502 | } |
412 | 503 | ||
413 | /** | 504 | /** |
505 | * rt_graph_check_container_param - check for litmus_container_param record | ||
506 | * Return 1, @cid, and @name if the record matches | ||
507 | */ | ||
508 | int rt_graph_check_container_param(struct graph_info *ginfo, | ||
509 | struct record *record, | ||
510 | gint *cid, char **name) | ||
511 | { | ||
512 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
513 | struct pevent *pevent = ginfo->pevent; | ||
514 | struct event_format *event; | ||
515 | gint id; | ||
516 | int ret = 0; | ||
517 | |||
518 | if (rtg_info->container_param_id < 0) { | ||
519 | event = pevent_find_event_by_name(pevent, "litmus", | ||
520 | "litmus_container_param"); | ||
521 | if (!event) | ||
522 | goto out; | ||
523 | rtg_info->task_param_id = event->id; | ||
524 | dprintf(2, "Found container_param id %d\n", event->id); | ||
525 | STORE_FIELD(rtg_info, event, cparam, cid); | ||
526 | STORE_FIELD(rtg_info, event, cparam, name); | ||
527 | } | ||
528 | |||
529 | id = pevent_data_type(pevent, record); | ||
530 | if (id == rtg_info->container_param_id) { | ||
531 | LOAD_INT(rtg_info, record, cparam, cid, cid); | ||
532 | LOAD_STRING(rtg_info, record, cparam, name, name); | ||
533 | |||
534 | add_container(rtg_info->containers, *cid, *name); | ||
535 | |||
536 | dprintf(3, "Read container_param for %s - %d\n", | ||
537 | *name, *cid); | ||
538 | ret = 1; | ||
539 | } | ||
540 | out: | ||
541 | return ret; | ||
542 | } | ||
543 | |||
544 | /** | ||
545 | * rt_graph_check_server_param - check for litmus_server_param record | ||
546 | * Return 1, @sid, @ocid, @owcet, and @operiod if the record matches | ||
547 | */ | ||
548 | int rt_graph_check_server_param(struct graph_info *ginfo, struct record *record, | ||
549 | gint *sid, gint *ocid, | ||
550 | unsigned long long *owcet, | ||
551 | unsigned long long *operiod) | ||
552 | { | ||
553 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
554 | struct pevent *pevent = ginfo->pevent; | ||
555 | struct event_format *event; | ||
556 | unsigned long long wcet, period; | ||
557 | gint cid, id; | ||
558 | int ret = 0; | ||
559 | |||
560 | if (rtg_info->server_param_id < 0) { | ||
561 | event = pevent_find_event_by_name(pevent, "litmus", | ||
562 | "litmus_server_param"); | ||
563 | if (!event) | ||
564 | goto out; | ||
565 | rtg_info->task_param_id = event->id; | ||
566 | dprintf(2, "Found server_param id %d\n", event->id); | ||
567 | STORE_FIELD(rtg_info, event, sparam, cid); | ||
568 | STORE_FIELD(rtg_info, event, sparam, sid); | ||
569 | STORE_FIELD(rtg_info, event, sparam, wcet); | ||
570 | STORE_FIELD(rtg_info, event, sparam, period); | ||
571 | } | ||
572 | |||
573 | id = pevent_data_type(pevent, record); | ||
574 | if (id == rtg_info->server_param_id) { | ||
575 | LOAD_INT(rtg_info, record, sparam, sid, sid); | ||
576 | LOAD_INT(rtg_info, record, sparam, cid, &cid); | ||
577 | LOAD_LONG(rtg_info, record, sparam, wcet, &wcet); | ||
578 | LOAD_LONG(rtg_info, record, sparam, period, &period); | ||
579 | |||
580 | add_vcpu(rtg_info->containers, cid, *sid, wcet, period); | ||
581 | |||
582 | ret = 1; | ||
583 | dprintf(3, "Read server_param record for server %d " | ||
584 | "(%llu, %llu) in container %d\n", | ||
585 | *sid, wcet, period, cid); | ||
586 | *ocid = cid; | ||
587 | *owcet = wcet; | ||
588 | *operiod = period; | ||
589 | } | ||
590 | out: | ||
591 | return ret; | ||
592 | } | ||
593 | |||
594 | /** | ||
595 | * rt_graph_check_server_switch_to - check for litmus_server_switch_to record | ||
596 | * Return 1, @sid, @job, @tid, and @ts if the record matches | ||
597 | */ | ||
598 | int rt_graph_check_server_switch_to(struct graph_info *ginfo, | ||
599 | struct record *record, | ||
600 | gint *sid, gint *job, gint *tid, | ||
601 | unsigned long long *ts) | ||
602 | { | ||
603 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
604 | struct pevent *pevent = ginfo->pevent; | ||
605 | struct event_format *event; | ||
606 | gint id; | ||
607 | int ret = 0; | ||
608 | |||
609 | if (rtg_info->server_switch_to_id < 0) { | ||
610 | event = pevent_find_event_by_name(pevent, "litmus", | ||
611 | "litmus_server_switch_to"); | ||
612 | if (!event) | ||
613 | goto out; | ||
614 | rtg_info->server_switch_to_id = event->id; | ||
615 | dprintf(2, "Found server_switch_to id %d\n", event->id); | ||
616 | STORE_FIELD(rtg_info, event, sswitch_to, sid); | ||
617 | STORE_FIELD(rtg_info, event, sswitch_to, job); | ||
618 | STORE_FIELD(rtg_info, event, sswitch_to, tid); | ||
619 | } | ||
620 | |||
621 | id = pevent_data_type(pevent, record); | ||
622 | if (id == rtg_info->server_switch_to_id) { | ||
623 | LOAD_INT(rtg_info, record, sswitch_to, sid, sid); | ||
624 | LOAD_INT(rtg_info, record, sswitch_to, job, job); | ||
625 | LOAD_INT(rtg_info, record, sswitch_to, tid, tid); | ||
626 | *ts = get_rts(ginfo, record); | ||
627 | |||
628 | dprintf(3, "Read server_switch_to(job(%d, %d)): %d", | ||
629 | *sid, *job, *tid); | ||
630 | ret = 1; | ||
631 | } | ||
632 | out: | ||
633 | return ret; | ||
634 | } | ||
635 | |||
636 | /** | ||
637 | * rt_graph_check_server_switch_away - check for litmus_server_switch_away | ||
638 | * Return 1, @sid, @job, @tid, and @ts if the record matches | ||
639 | */ | ||
640 | int rt_graph_check_server_switch_away(struct graph_info *ginfo, | ||
641 | struct record *record, | ||
642 | gint *sid, gint *job, gint *tid, | ||
643 | unsigned long long *ts) | ||
644 | { | ||
645 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
646 | struct pevent *pevent = ginfo->pevent; | ||
647 | struct event_format *event; | ||
648 | gint id; | ||
649 | int ret = 0; | ||
650 | |||
651 | if (rtg_info->server_switch_away_id < 0) { | ||
652 | event = pevent_find_event_by_name(pevent, "litmus", | ||
653 | "litmus_server_switch_away"); | ||
654 | if (!event) | ||
655 | goto out; | ||
656 | rtg_info->server_switch_away_id = event->id; | ||
657 | dprintf(2, "Found server_switch_away id %d\n", event->id); | ||
658 | STORE_FIELD(rtg_info, event, sswitch_away, sid); | ||
659 | STORE_FIELD(rtg_info, event, sswitch_away, job); | ||
660 | STORE_FIELD(rtg_info, event, sswitch_away, tid); | ||
661 | } | ||
662 | |||
663 | id = pevent_data_type(pevent, record); | ||
664 | if (id == rtg_info->server_switch_away_id) { | ||
665 | LOAD_INT(rtg_info, record, sswitch_away, sid, sid); | ||
666 | LOAD_INT(rtg_info, record, sswitch_away, job, job); | ||
667 | LOAD_INT(rtg_info, record, sswitch_away, tid, tid); | ||
668 | *ts = get_rts(ginfo, record); | ||
669 | |||
670 | |||
671 | dprintf(3, "Read server_switch_away(job(%d, %d)): %d", | ||
672 | *sid, *job, *tid); | ||
673 | ret = 1; | ||
674 | } | ||
675 | out: | ||
676 | return ret; | ||
677 | } | ||
678 | |||
679 | /** | ||
680 | * rt_graph_check_server_release - check for litmus_server_release | ||
681 | * Return 1, @sid, @job, @release, and @deadline if the record matches | ||
682 | */ | ||
683 | int rt_graph_check_server_release(struct graph_info *ginfo, | ||
684 | struct record *record, | ||
685 | gint *sid, gint *job, | ||
686 | unsigned long long *release, | ||
687 | unsigned long long *deadline) | ||
688 | { | ||
689 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
690 | struct pevent *pevent = ginfo->pevent; | ||
691 | struct event_format *event; | ||
692 | gint id; | ||
693 | int ret = 0; | ||
694 | |||
695 | if (rtg_info->server_release_id < 0) { | ||
696 | event = pevent_find_event_by_name(pevent, "litmus", | ||
697 | "litmus_server_release"); | ||
698 | if (!event) | ||
699 | goto out; | ||
700 | rtg_info->server_release_id = event->id; | ||
701 | dprintf(2, "Found server_switch_away id %d\n", event->id); | ||
702 | STORE_FIELD(rtg_info, event, srelease, sid); | ||
703 | STORE_FIELD(rtg_info, event, srelease, job); | ||
704 | STORE_FIELD(rtg_info, event, srelease, release); | ||
705 | STORE_FIELD(rtg_info, event, srelease, deadline); | ||
706 | } | ||
707 | |||
708 | id = pevent_data_type(pevent, record); | ||
709 | if (id == rtg_info->server_release_id) { | ||
710 | LOAD_INT(rtg_info, record, srelease, sid, sid); | ||
711 | LOAD_INT(rtg_info, record, srelease, job, job); | ||
712 | LOAD_LONG(rtg_info, record, srelease, release, release); | ||
713 | LOAD_LONG(rtg_info, record, srelease, deadline, deadline); | ||
714 | |||
715 | dprintf(3, "Read server_switch_release(job(%d, %d)), rel: %llu," | ||
716 | " dead: %llu\n", *sid, *job, *release, *deadline); | ||
717 | ret = 1; | ||
718 | } | ||
719 | out: | ||
720 | return ret; | ||
721 | } | ||
722 | |||
723 | /** | ||
724 | * rt_graph_check_server_completion - check for litmus_server_completion record | ||
725 | * Return 1, @sid, and @job if the record matches | ||
726 | */ | ||
727 | int rt_graph_check_server_completion(struct graph_info *ginfo, | ||
728 | struct record *record, | ||
729 | gint *sid, gint *job) | ||
730 | { | ||
731 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
732 | struct pevent *pevent = ginfo->pevent; | ||
733 | struct event_format *event; | ||
734 | gint id; | ||
735 | int ret = 0; | ||
736 | |||
737 | if (rtg_info->server_completion_id < 0) { | ||
738 | event = pevent_find_event_by_name(pevent, "litmus", | ||
739 | "litmus_server_completion"); | ||
740 | if (!event) | ||
741 | goto out; | ||
742 | rtg_info->server_completion_id = event->id; | ||
743 | dprintf(2, "Found server_switch_away id %d\n", event->id); | ||
744 | STORE_FIELD(rtg_info, event, scompletion, sid); | ||
745 | STORE_FIELD(rtg_info, event, scompletion, job); | ||
746 | } | ||
747 | |||
748 | id = pevent_data_type(pevent, record); | ||
749 | if (id == rtg_info->server_completion_id) { | ||
750 | LOAD_INT(rtg_info, record, scompletion, sid, sid); | ||
751 | LOAD_INT(rtg_info, record, scompletion, job, job); | ||
752 | |||
753 | dprintf(3, "Read server_completion(job(%d, %d))\n", *sid, *job); | ||
754 | ret = 1; | ||
755 | } | ||
756 | out: | ||
757 | return ret; | ||
758 | } | ||
759 | |||
760 | |||
761 | /** | ||
762 | * rt_graph_check_server_block - check for litmus_server_block record | ||
763 | * Return 1, @sid, and @ts if the record matches | ||
764 | */ | ||
765 | int rt_graph_check_server_block(struct graph_info *ginfo, | ||
766 | struct record *record, | ||
767 | gint *sid, unsigned long long *ts) | ||
768 | { | ||
769 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
770 | struct pevent *pevent = ginfo->pevent; | ||
771 | struct event_format *event; | ||
772 | gint id; | ||
773 | int ret = 0; | ||
774 | |||
775 | if (rtg_info->server_block_id < 0) { | ||
776 | event = pevent_find_event_by_name(pevent, "litmus", | ||
777 | "litmus_server_block"); | ||
778 | if (!event) | ||
779 | goto out; | ||
780 | dprintf(2, "Found server_block id %d\n", event->id); | ||
781 | STORE_FIELD(rtg_info, event, sblock, sid); | ||
782 | } | ||
783 | |||
784 | id = pevent_data_type(pevent, record); | ||
785 | if (id == rtg_info->server_block_id) { | ||
786 | LOAD_INT(rtg_info, record, sblock, sid, sid); | ||
787 | *ts = get_rts(ginfo, record); | ||
788 | |||
789 | ret = 1; | ||
790 | dprintf(3, "Read server_block record for server %d\n", *sid); | ||
791 | } | ||
792 | out: | ||
793 | return ret; | ||
794 | } | ||
795 | |||
796 | /** | ||
797 | * rt_graph_check_server_resume - check for litmus_server_resume record | ||
798 | * Return 1, @sid, and @ts if the record matches | ||
799 | */ | ||
800 | int rt_graph_check_server_resume(struct graph_info *ginfo, | ||
801 | struct record *record, | ||
802 | gint *sid, unsigned long long *ts) | ||
803 | { | ||
804 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
805 | struct pevent *pevent = ginfo->pevent; | ||
806 | struct event_format *event; | ||
807 | gint id; | ||
808 | int ret = 0; | ||
809 | |||
810 | if (rtg_info->server_resume_id < 0) { | ||
811 | event = pevent_find_event_by_name(pevent, "litmus", | ||
812 | "litmus_server_resume"); | ||
813 | if (!event) | ||
814 | goto out; | ||
815 | dprintf(2, "Found server_resume id %d\n", event->id); | ||
816 | STORE_FIELD(rtg_info, event, sresume, sid); | ||
817 | } | ||
818 | |||
819 | id = pevent_data_type(pevent, record); | ||
820 | if (id == rtg_info->server_resume_id) { | ||
821 | LOAD_INT(rtg_info, record, sresume, sid, sid); | ||
822 | *ts = get_rts(ginfo, record); | ||
823 | |||
824 | ret = 1; | ||
825 | dprintf(3, "Read server_resume record for server %d\n", *sid); | ||
826 | } | ||
827 | out: | ||
828 | return ret; | ||
829 | } | ||
830 | |||
831 | |||
832 | /** | ||
414 | * init_rt_event_cache - reset cached field values | 833 | * init_rt_event_cache - reset cached field values |
415 | */ | 834 | */ |
416 | void init_rt_event_cache(struct rt_graph_info *rtg_info) | 835 | void init_rt_event_cache(struct rt_graph_info *rtg_info) |
417 | { | 836 | { |
418 | dprintf(1, "Initializing RT event cache\n"); | 837 | dprintf(1, "Initializing RT event cache\n"); |
838 | |||
839 | memset(rtg_info, 0, sizeof(*rtg_info)); | ||
840 | |||
419 | rtg_info->task_param_id = -1; | 841 | rtg_info->task_param_id = -1; |
420 | rtg_info->switch_to_id = -1; | 842 | rtg_info->switch_to_id = -1; |
421 | rtg_info->switch_away_id = -1; | 843 | rtg_info->switch_away_id = -1; |
@@ -424,34 +846,14 @@ void init_rt_event_cache(struct rt_graph_info *rtg_info) | |||
424 | rtg_info->task_block_id = -1; | 846 | rtg_info->task_block_id = -1; |
425 | rtg_info->task_resume_id = -1; | 847 | rtg_info->task_resume_id = -1; |
426 | 848 | ||
427 | rtg_info->max_period = 0; | 849 | rtg_info->container_param_id = -1; |
428 | 850 | rtg_info->server_param_id = -1; | |
429 | rtg_info->param_pid_field = NULL; | 851 | rtg_info->server_switch_to_id = -1; |
430 | rtg_info->param_wcet_field = NULL; | 852 | rtg_info->server_switch_away_id = -1; |
431 | rtg_info->param_period_field = NULL; | 853 | rtg_info->server_release_id = -1; |
432 | 854 | rtg_info->server_completion_id = -1; | |
433 | rtg_info->switch_to_pid_field = NULL; | 855 | rtg_info->server_block_id = -1; |
434 | rtg_info->switch_to_job_field = NULL; | 856 | rtg_info->server_resume_id = -1; |
435 | rtg_info->switch_to_ts_field = NULL; | ||
436 | |||
437 | rtg_info->switch_away_pid_field = NULL; | ||
438 | rtg_info->switch_away_job_field = NULL; | ||
439 | rtg_info->switch_away_ts_field = NULL; | ||
440 | |||
441 | rtg_info->release_pid_field = NULL; | ||
442 | rtg_info->release_job_field = NULL; | ||
443 | rtg_info->release_release_field = NULL; | ||
444 | rtg_info->release_deadline_field = NULL; | ||
445 | |||
446 | rtg_info->completion_pid_field = NULL; | ||
447 | rtg_info->completion_job_field = NULL; | ||
448 | rtg_info->completion_ts_field = NULL; | ||
449 | |||
450 | rtg_info->block_pid_field = NULL; | ||
451 | rtg_info->block_ts_field = NULL; | ||
452 | |||
453 | rtg_info->resume_pid_field = NULL; | ||
454 | rtg_info->resume_ts_field = NULL; | ||
455 | } | 857 | } |
456 | 858 | ||
457 | /** | 859 | /** |
@@ -466,8 +868,7 @@ get_rts(struct graph_info *ginfo, struct record *record) | |||
466 | gint epid, eid; | 868 | gint epid, eid; |
467 | unsigned long long ts; | 869 | unsigned long long ts; |
468 | if (!record->cached_rts) { | 870 | if (!record->cached_rts) { |
469 | rt_graph_check_any(&ginfo->rtg_info, ginfo->pevent, record, | 871 | rt_graph_check_any(ginfo, record, &epid, &eid, &ts); |
470 | &epid, &eid, &ts); | ||
471 | record->cached_rts = ts; | 872 | record->cached_rts = ts; |
472 | } else | 873 | } else |
473 | ts = record->cached_rts; | 874 | ts = record->cached_rts; |
@@ -524,9 +925,9 @@ set_cpu_to_rts(struct graph_info *ginfo, unsigned long long rt_target, int cpu) | |||
524 | 925 | ||
525 | /* Zero in in 1.5x the difference increments */ | 926 | /* Zero in in 1.5x the difference increments */ |
526 | if (rts && diff > 0) { | 927 | if (rts && diff > 0) { |
527 | /* rts rt_target | 928 | /* rts rt_target | real-time time |
528 | * seek ? | 929 | * seek ? | trace-cmd time |
529 | * ---|---->>----|--- | 930 | * ---|---->>----|-------- |
530 | */ | 931 | */ |
531 | do { | 932 | do { |
532 | last_seek = seek_time; | 933 | last_seek = seek_time; |
@@ -537,9 +938,9 @@ set_cpu_to_rts(struct graph_info *ginfo, unsigned long long rt_target, int cpu) | |||
537 | tracecmd_set_cpu_to_timestamp(ginfo->handle, cpu, last_seek); | 938 | tracecmd_set_cpu_to_timestamp(ginfo->handle, cpu, last_seek); |
538 | seek_time = last_seek; | 939 | seek_time = last_seek; |
539 | } else if (rts && diff < 0) { | 940 | } else if (rts && diff < 0) { |
540 | /* rt_target rts | 941 | /* rt_target rts | real-time time |
541 | * ? seek | 942 | * ? seek | trace-cmd time |
542 | * ---|----<<----|--- | 943 | * ---|----<<----|-------- |
543 | */ | 944 | */ |
544 | do { | 945 | do { |
545 | seek_time = seek_time - 1.5 * (rts - rt_target); | 946 | seek_time = seek_time - 1.5 * (rts - rt_target); |
@@ -9,23 +9,23 @@ | |||
9 | 9 | ||
10 | #define LLABEL 30 | 10 | #define LLABEL 30 |
11 | #define SEARCH_PERIODS 3 | 11 | #define SEARCH_PERIODS 3 |
12 | |||
13 | #define NO_CPU -1 | 12 | #define NO_CPU -1 |
14 | |||
15 | #define RT_TS_FIELD "__rt_ts" | 13 | #define RT_TS_FIELD "__rt_ts" |
14 | |||
16 | #define TS_HASH_SIZE 12 | 15 | #define TS_HASH_SIZE 12 |
17 | struct ts_list; | 16 | #define CONT_HASH_SIZE 12 |
18 | 17 | ||
19 | struct rt_task_params { | 18 | struct ts_list; |
20 | unsigned long long wcet; | 19 | struct vcpu_list; |
21 | unsigned long long period; | ||
22 | }; | ||
23 | 20 | ||
24 | struct rt_graph_info { | 21 | struct rt_graph_info { |
25 | 22 | ||
26 | /* List of all real-time tasks */ | 23 | /* List of all real-time tasks */ |
27 | struct task_list *tasks[TASK_HASH_SIZE]; | 24 | struct task_list *tasks[TASK_HASH_SIZE]; |
28 | 25 | ||
26 | /* List of all real-time containers */ | ||
27 | struct cont_list *containers[CONT_HASH_SIZE]; | ||
28 | |||
29 | /* Cache of event fields so that they don't need to be located | 29 | /* Cache of event fields so that they don't need to be located |
30 | * during each access. | 30 | * during each access. |
31 | */ | 31 | */ |
@@ -37,12 +37,10 @@ struct rt_graph_info { | |||
37 | gint switch_to_id; | 37 | gint switch_to_id; |
38 | struct format_field *switch_to_pid_field; | 38 | struct format_field *switch_to_pid_field; |
39 | struct format_field *switch_to_job_field; | 39 | struct format_field *switch_to_job_field; |
40 | struct format_field *switch_to_ts_field; | ||
41 | 40 | ||
42 | gint switch_away_id; | 41 | gint switch_away_id; |
43 | struct format_field *switch_away_pid_field; | 42 | struct format_field *switch_away_pid_field; |
44 | struct format_field *switch_away_job_field; | 43 | struct format_field *switch_away_job_field; |
45 | struct format_field *switch_away_ts_field; | ||
46 | 44 | ||
47 | gint task_release_id; | 45 | gint task_release_id; |
48 | struct format_field *release_pid_field; | 46 | struct format_field *release_pid_field; |
@@ -53,55 +51,146 @@ struct rt_graph_info { | |||
53 | gint task_completion_id; | 51 | gint task_completion_id; |
54 | struct format_field *completion_pid_field; | 52 | struct format_field *completion_pid_field; |
55 | struct format_field *completion_job_field; | 53 | struct format_field *completion_job_field; |
56 | struct format_field *completion_ts_field; | ||
57 | 54 | ||
58 | gint task_block_id; | 55 | gint task_block_id; |
59 | struct format_field *block_pid_field; | 56 | struct format_field *block_pid_field; |
60 | struct format_field *block_ts_field; | ||
61 | 57 | ||
62 | gint task_resume_id; | 58 | gint task_resume_id; |
63 | struct format_field *resume_pid_field; | 59 | struct format_field *resume_pid_field; |
64 | struct format_field *resume_ts_field; | 60 | |
61 | gint container_param_id; | ||
62 | struct format_field *cparam_cid_field; | ||
63 | struct format_field *cparam_name_field; | ||
64 | |||
65 | gint server_param_id; | ||
66 | struct format_field *sparam_sid_field; | ||
67 | struct format_field *sparam_cid_field; | ||
68 | struct format_field *sparam_wcet_field; | ||
69 | struct format_field *sparam_period_field; | ||
70 | |||
71 | gint server_switch_to_id; | ||
72 | struct format_field *sswitch_to_sid_field; | ||
73 | struct format_field *sswitch_to_job_field; | ||
74 | struct format_field *sswitch_to_tid_field; | ||
75 | |||
76 | gint server_switch_away_id; | ||
77 | struct format_field *sswitch_away_sid_field; | ||
78 | struct format_field *sswitch_away_job_field; | ||
79 | struct format_field *sswitch_away_tid_field; | ||
80 | |||
81 | gint server_release_id; | ||
82 | struct format_field *srelease_sid_field; | ||
83 | struct format_field *srelease_job_field; | ||
84 | struct format_field *srelease_release_field; | ||
85 | struct format_field *srelease_deadline_field; | ||
86 | |||
87 | gint server_completion_id; | ||
88 | struct format_field *scompletion_sid_field; | ||
89 | struct format_field *scompletion_job_field; | ||
90 | |||
91 | gint server_block_id; | ||
92 | struct format_field *sblock_sid_field; | ||
93 | |||
94 | gint server_resume_id; | ||
95 | struct format_field *sresume_sid_field; | ||
96 | |||
65 | 97 | ||
66 | /* Cache of ts fields for non-litmus events */ | 98 | /* Cache of ts fields for non-litmus events */ |
67 | struct ts_list *events[TS_HASH_SIZE]; | 99 | struct ts_list *events[TS_HASH_SIZE]; |
68 | 100 | ||
101 | /* Used to calculate maximum search times */ | ||
69 | unsigned long long max_period; | 102 | unsigned long long max_period; |
70 | }; | 103 | }; |
71 | 104 | ||
105 | /* | ||
106 | * A list of cached time-stamp fields | ||
107 | */ | ||
72 | struct ts_list { | 108 | struct ts_list { |
73 | struct ts_list *next; | 109 | struct ts_list *next; |
74 | gint eid; | 110 | gint eid; |
75 | struct format_field *ts_field; | 111 | struct format_field *ts_field; |
76 | }; | 112 | }; |
77 | 113 | ||
114 | /* | ||
115 | * Per-task real-time data | ||
116 | */ | ||
117 | struct rt_task_params { | ||
118 | unsigned long long wcet; | ||
119 | unsigned long long period; | ||
120 | }; | ||
121 | |||
122 | /* | ||
123 | * A list of servers | ||
124 | */ | ||
125 | struct vcpu_list { | ||
126 | struct vcpu_list *next; | ||
127 | gint sid; | ||
128 | struct rt_task_params params; | ||
129 | }; | ||
130 | |||
131 | /* | ||
132 | * A list of containers | ||
133 | */ | ||
134 | struct cont_list { | ||
135 | struct cont_list *next; | ||
136 | gint cid; | ||
137 | const char* name; | ||
138 | struct vcpu_list *vcpus; | ||
139 | }; | ||
140 | |||
78 | /* Event parsers */ | 141 | /* Event parsers */ |
79 | int rt_graph_check_any(struct rt_graph_info *rtinfo, | 142 | int rt_graph_check_any(struct graph_info *ginfo, struct record *record, |
80 | struct pevent *pevent, struct record *record, | ||
81 | gint *pid, gint *eid, unsigned long long *ts); | 143 | gint *pid, gint *eid, unsigned long long *ts); |
82 | int rt_graph_check_task_param(struct rt_graph_info *rtinfo, struct pevent *pevent, | 144 | int rt_graph_check_task_param(struct graph_info *ginfo, |
83 | struct record *record, gint *pid, | 145 | struct record *record, gint *pid, |
84 | unsigned long long *wcet, | 146 | unsigned long long *wcet, |
85 | unsigned long long *period); | 147 | unsigned long long *period); |
86 | int rt_graph_check_switch_to(struct rt_graph_info *rtinfo, struct pevent *pevent, | 148 | int rt_graph_check_switch_to(struct graph_info *ginfo, |
87 | struct record *record, gint *pid, gint *job, | 149 | struct record *record, gint *pid, gint *job, |
88 | unsigned long long *when); | 150 | unsigned long long *when); |
89 | int rt_graph_check_switch_away(struct rt_graph_info *rtinfo, struct pevent *pevent, | 151 | int rt_graph_check_switch_away(struct graph_info *ginfo, |
90 | struct record *record, gint *pid, gint *job, | 152 | struct record *record, gint *pid, gint *job, |
91 | unsigned long long *when); | 153 | unsigned long long *when); |
92 | int rt_graph_check_task_release(struct rt_graph_info *rtinfo, struct pevent *pevent, | 154 | int rt_graph_check_task_release(struct graph_info *ginfo, |
93 | struct record *record, gint *pid, gint *job, | 155 | struct record *record, gint *pid, gint *job, |
94 | unsigned long long *release, | 156 | unsigned long long *release, |
95 | unsigned long long *deadline); | 157 | unsigned long long *deadline); |
96 | int rt_graph_check_task_completion(struct rt_graph_info *rtinfo, struct pevent *pevent, | 158 | int rt_graph_check_task_completion(struct graph_info *ginfo, |
97 | struct record *record, gint *pid, gint *job, | 159 | struct record *record, gint *pid, gint *job, |
98 | unsigned long long *when); | 160 | unsigned long long *when); |
99 | int rt_graph_check_task_block(struct rt_graph_info *rtinfo, struct pevent *pevent, | 161 | int rt_graph_check_task_block(struct graph_info *ginfo, |
100 | struct record *record, gint *pid, | 162 | struct record *record, gint *pid, |
101 | unsigned long long *when); | 163 | unsigned long long *when); |
102 | int rt_graph_check_task_resume(struct rt_graph_info *rtinfo, struct pevent *pevent, | 164 | int rt_graph_check_task_resume(struct graph_info *ginfo, struct record *record, |
103 | struct record *record, gint *pid, | 165 | gint *pid, unsigned long long *when); |
104 | unsigned long long *when); | 166 | int rt_graph_check_container_param(struct graph_info *ginfo, |
167 | struct record *record, | ||
168 | gint *cid, char **name); | ||
169 | int rt_graph_check_server_param(struct graph_info *ginfo, struct record *record, | ||
170 | gint *sid, gint *cid, | ||
171 | unsigned long long *wcet, | ||
172 | unsigned long long *period); | ||
173 | int rt_graph_check_server_switch_to(struct graph_info *ginfo, | ||
174 | struct record *record, | ||
175 | gint *sid, gint *job, gint *tid, | ||
176 | unsigned long long *when); | ||
177 | int rt_graph_check_server_switch_away(struct graph_info *ginfo, | ||
178 | struct record *record, | ||
179 | gint *sid, gint *job, gint *tid, | ||
180 | unsigned long long *when); | ||
181 | int rt_graph_check_server_release(struct graph_info *ginfo, | ||
182 | struct record *record, | ||
183 | gint *sid, gint *job, | ||
184 | unsigned long long *release, | ||
185 | unsigned long long *deadline); | ||
186 | int rt_graph_check_server_completion(struct graph_info *ginfo, | ||
187 | struct record *record, | ||
188 | gint *sid, gint *job); | ||
189 | int rt_graph_check_server_block(struct graph_info *ginfo, | ||
190 | struct record *record, gint *pid, | ||
191 | unsigned long long *when); | ||
192 | int rt_graph_check_server_resume(struct graph_info *ginfo, struct record *record, | ||
193 | gint *pid, unsigned long long *when); | ||
105 | void init_rt_event_cache(struct rt_graph_info *rtinfo); | 194 | void init_rt_event_cache(struct rt_graph_info *rtinfo); |
106 | 195 | ||
107 | /* Methods for dealing with RT timestamps */ | 196 | /* Methods for dealing with RT timestamps */ |
@@ -122,4 +211,9 @@ static inline void nano_to_milli(unsigned long long time, | |||
122 | *nsec = time % 1000000ULL; | 211 | *nsec = time % 1000000ULL; |
123 | } | 212 | } |
124 | 213 | ||
214 | static inline float nano_as_milli(unsigned long long time) | ||
215 | { | ||
216 | return (float)time / 1000000ULL; | ||
217 | } | ||
218 | |||
125 | #endif | 219 | #endif |
diff --git a/rt-plot-cpu.c b/rt-plot-cpu.c index 4c98a95..e32f085 100644 --- a/rt-plot-cpu.c +++ b/rt-plot-cpu.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #include <string.h> | ||
1 | #include "trace-graph.h" | 2 | #include "trace-graph.h" |
2 | #include "cpu.h" | 3 | #include "cpu.h" |
3 | 4 | ||
@@ -35,7 +36,7 @@ next_sa_record(struct graph_info *ginfo, struct rt_cpu_info *rtc_info, | |||
35 | free_record(record); | 36 | free_record(record); |
36 | break; | 37 | break; |
37 | } | 38 | } |
38 | match = rt_graph_check_switch_away(rtg_info, pevent, record, | 39 | match = rt_graph_check_switch_away(ginfo, record, |
39 | &pid, &dint, &dull); | 40 | &pid, &dint, &dull); |
40 | if (match) { | 41 | if (match) { |
41 | ret = record; | 42 | ret = record; |
@@ -149,7 +150,7 @@ static int get_time_info(struct graph_info *ginfo, | |||
149 | if (get_rts(ginfo, record) > max_ts) | 150 | if (get_rts(ginfo, record) > max_ts) |
150 | break; | 151 | break; |
151 | 152 | ||
152 | #define ARG rtg_info, ginfo->pevent, record, &pid, &job, &dull | 153 | #define ARG ginfo, record, &pid, &job, &dull |
153 | if (rt_graph_check_switch_to(ARG) && pid) { | 154 | if (rt_graph_check_switch_to(ARG) && pid) { |
154 | goto out; | 155 | goto out; |
155 | } else if (rt_graph_check_switch_away(ARG) && pid) { | 156 | } else if (rt_graph_check_switch_away(ARG) && pid) { |
@@ -184,8 +185,7 @@ try_switch_away(struct graph_info *ginfo, struct rt_cpu_info *rtc_info, | |||
184 | int job, pid, match; | 185 | int job, pid, match; |
185 | unsigned long long ts; | 186 | unsigned long long ts; |
186 | 187 | ||
187 | match = rt_graph_check_switch_away(&ginfo->rtg_info, ginfo->pevent, | 188 | match = rt_graph_check_switch_away(ginfo, record, &pid, &job, &ts); |
188 | record, &pid, &job, &ts); | ||
189 | match = match && pid; | 189 | match = match && pid; |
190 | if (match) { | 190 | if (match) { |
191 | update_pid(rtc_info, pid); | 191 | update_pid(rtc_info, pid); |
@@ -212,10 +212,8 @@ try_switch_to(struct graph_info *ginfo, struct rt_cpu_info *rtc_info, | |||
212 | int job, pid, match; | 212 | int job, pid, match; |
213 | unsigned long long ts; | 213 | unsigned long long ts; |
214 | 214 | ||
215 | match = rt_graph_check_switch_to(&ginfo->rtg_info, ginfo->pevent, | 215 | match = rt_graph_check_switch_to(ginfo, record, &pid, &job, &ts); |
216 | record, &pid, &job, &ts); | ||
217 | match = match && pid; | 216 | match = match && pid; |
218 | |||
219 | if (match) { | 217 | if (match) { |
220 | update_pid(rtc_info, pid); | 218 | update_pid(rtc_info, pid); |
221 | rtc_info->rt_run_time = ts; | 219 | rtc_info->rt_run_time = ts; |
@@ -231,8 +229,7 @@ try_completion(struct graph_info *ginfo, struct rt_cpu_info *rtc_info, | |||
231 | int pid, job, match; | 229 | int pid, job, match; |
232 | unsigned long long ts; | 230 | unsigned long long ts; |
233 | 231 | ||
234 | match = rt_graph_check_task_completion(&ginfo->rtg_info, ginfo->pevent, | 232 | match = rt_graph_check_task_completion(ginfo, record, &pid, &job, &ts); |
235 | record, &pid, &job, &ts); | ||
236 | if (match) { | 233 | if (match) { |
237 | info->completion = TRUE; | 234 | info->completion = TRUE; |
238 | info->ctime = ts; | 235 | info->ctime = ts; |
@@ -336,7 +333,6 @@ static int rt_cpu_plot_event(struct graph_info *ginfo, struct graph_plot *plot, | |||
336 | int pid, eid, match, dint; | 333 | int pid, eid, match, dint; |
337 | unsigned long long ts, dull; | 334 | unsigned long long ts, dull; |
338 | struct rt_cpu_info *rtc_info = plot->private; | 335 | struct rt_cpu_info *rtc_info = plot->private; |
339 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
340 | 336 | ||
341 | if (!record) { | 337 | if (!record) { |
342 | do_plot_end(ginfo, rtc_info, info); | 338 | do_plot_end(ginfo, rtc_info, info); |
@@ -355,7 +351,7 @@ static int rt_cpu_plot_event(struct graph_info *ginfo, struct graph_plot *plot, | |||
355 | /* Have to call checks to ensure ids are loaded. Otherwise, | 351 | /* Have to call checks to ensure ids are loaded. Otherwise, |
356 | * is_displayed will not work here or in any other methods. | 352 | * is_displayed will not work here or in any other methods. |
357 | */ | 353 | */ |
358 | #define ARG rtg_info, ginfo->pevent, record, &pid | 354 | #define ARG ginfo,record, &pid |
359 | rt_graph_check_task_param(ARG, &dull, &dull); | 355 | rt_graph_check_task_param(ARG, &dull, &dull); |
360 | rt_graph_check_task_release(ARG, &dint, &dull, &dull); | 356 | rt_graph_check_task_release(ARG, &dint, &dull, &dull); |
361 | rt_graph_check_task_block(ARG, &dull); | 357 | rt_graph_check_task_block(ARG, &dull); |
@@ -559,26 +555,33 @@ void rt_plot_cpus_plotted(struct graph_info *ginfo, | |||
559 | } | 555 | } |
560 | 556 | ||
561 | /** | 557 | /** |
562 | * rt_plot_cpu - create a plot for @cpu. | 558 | * rt_plot_cpu_label - create a plot for @cpu with @label. |
563 | */ | 559 | */ |
564 | void rt_plot_cpu(struct graph_info *ginfo, int cpu) | 560 | void rt_plot_cpu_label(struct graph_info *ginfo, int cpu, char* label) |
565 | { | 561 | { |
566 | struct rt_cpu_info *rtc_info; | 562 | struct rt_cpu_info *rtc_info; |
567 | struct graph_plot *plot; | 563 | struct graph_plot *plot; |
568 | char label[100]; | ||
569 | 564 | ||
570 | rtc_info = malloc_or_die(sizeof(*rtc_info)); | 565 | rtc_info = malloc_or_die(sizeof(*rtc_info)); |
571 | memset(rtc_info, 0, sizeof(*rtc_info)); | 566 | memset(rtc_info, 0, sizeof(*rtc_info)); |
572 | rtc_info->cpu = cpu; | 567 | rtc_info->cpu = cpu; |
573 | rtc_info->label = malloc_or_die(LLABEL); | 568 | rtc_info->label = label; |
574 | |||
575 | snprintf(label, 100, "RT-CPU %d", cpu); | ||
576 | 569 | ||
577 | plot = trace_graph_plot_append(ginfo, label, PLOT_TYPE_RT_CPU, | 570 | plot = trace_graph_plot_append(ginfo, label, PLOT_TYPE_RT_CPU, |
578 | TIME_TYPE_RT, &rt_cpu_cb, rtc_info); | 571 | TIME_TYPE_RT, &rt_cpu_cb, rtc_info); |
579 | trace_graph_plot_add_all_recs(ginfo, plot); | 572 | trace_graph_plot_add_all_recs(ginfo, plot); |
580 | } | 573 | } |
581 | 574 | ||
575 | /** | ||
576 | * rt_plot_cpu - create a plot for @cpu. | ||
577 | */ | ||
578 | void rt_plot_cpu(struct graph_info *ginfo, int cpu) | ||
579 | { | ||
580 | char *label = malloc_or_die(LLABEL); | ||
581 | snprintf(label, 100, "RT-CPU %d", cpu); | ||
582 | rt_plot_cpu_label(ginfo, cpu, label); | ||
583 | } | ||
584 | |||
582 | void rt_plot_init_cpus(struct graph_info *ginfo, int cpus) | 585 | void rt_plot_init_cpus(struct graph_info *ginfo, int cpus) |
583 | { | 586 | { |
584 | long cpu; | 587 | long cpu; |
diff --git a/rt-plot-cpu.h b/rt-plot-cpu.h index 4af978d..2742c76 100644 --- a/rt-plot-cpu.h +++ b/rt-plot-cpu.h | |||
@@ -10,6 +10,7 @@ struct rt_cpu_info { | |||
10 | char *label; | 10 | char *label; |
11 | }; | 11 | }; |
12 | 12 | ||
13 | void rt_plot_labeled_cpu(struct graph_info *ginfo, int cpu, char *label); | ||
13 | void rt_plot_cpu(struct graph_info *ginfo, int cpu); | 14 | void rt_plot_cpu(struct graph_info *ginfo, int cpu); |
14 | void rt_plot_cpus_plotted(struct graph_info *ginfo, | 15 | void rt_plot_cpus_plotted(struct graph_info *ginfo, |
15 | gboolean *all_cpus, guint64 **cpu_mask); | 16 | gboolean *all_cpus, guint64 **cpu_mask); |
diff --git a/rt-plot-task.c b/rt-plot-task.c index a5b475f..524b1f9 100644 --- a/rt-plot-task.c +++ b/rt-plot-task.c | |||
@@ -1,3 +1,5 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <string.h> | ||
1 | #include "trace-graph.h" | 3 | #include "trace-graph.h" |
2 | #include "trace-filter.h" | 4 | #include "trace-filter.h" |
3 | 5 | ||
@@ -21,12 +23,11 @@ static gboolean record_matches_pid(struct graph_info *ginfo, | |||
21 | { | 23 | { |
22 | gint dint, pid = 0, match; | 24 | gint dint, pid = 0, match; |
23 | unsigned long long dull; | 25 | unsigned long long dull; |
24 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
25 | 26 | ||
26 | /* Must use check_* in case record has not been found yet, | 27 | /* Must use check_* in case record has not been found yet, |
27 | * this macro was the best of many terrible options. | 28 | * this macro was the best of many terrible options. |
28 | */ | 29 | */ |
29 | #define ARG rtg_info, ginfo->pevent, record, &pid | 30 | #define ARG ginfo, record, &pid |
30 | match = rt_graph_check_switch_to(ARG, &dint, &dull) || | 31 | match = rt_graph_check_switch_to(ARG, &dint, &dull) || |
31 | rt_graph_check_switch_away(ARG, &dint, &dull) || | 32 | rt_graph_check_switch_away(ARG, &dint, &dull) || |
32 | rt_graph_check_task_release(ARG, &dint, &dull, &dull) || | 33 | rt_graph_check_task_release(ARG, &dint, &dull, &dull) || |
@@ -63,10 +64,10 @@ next_box_record(struct graph_info *ginfo, struct rt_task_info *rtt_info, | |||
63 | } | 64 | } |
64 | 65 | ||
65 | /* Sorry mother */ | 66 | /* Sorry mother */ |
66 | #define ARG rtg_info, pevent, record, &pid | 67 | #define ARG ginfo, record, &pid |
67 | match = rt_graph_check_switch_to(ARG, &dint, &dull) || | 68 | match = rt_graph_check_switch_to(ARG, &dint, &dull) || |
68 | rt_graph_check_switch_away(ARG, &dint, &dull) || | 69 | rt_graph_check_switch_away(ARG, &dint, &dull) || |
69 | rt_graph_check_task_block(ARG, &dull) || | 70 | rt_graph_check_task_block(ARG, &dull) || |
70 | rt_graph_check_task_resume(ARG, &dull); | 71 | rt_graph_check_task_resume(ARG, &dull); |
71 | #undef ARG | 72 | #undef ARG |
72 | eid = (match) ? pevent_data_type(pevent, record) : 0; | 73 | eid = (match) ? pevent_data_type(pevent, record) : 0; |
@@ -164,7 +165,6 @@ get_previous_release(struct graph_info *ginfo, struct rt_task_info *rtt_info, | |||
164 | int pid, job, match; | 165 | int pid, job, match; |
165 | unsigned long long release, deadline; | 166 | unsigned long long release, deadline; |
166 | struct record *last_record, *record, *ret = NULL; | 167 | struct record *last_record, *record, *ret = NULL; |
167 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
168 | 168 | ||
169 | last_record = tracecmd_peek_data(ginfo->handle, cpu); | 169 | last_record = tracecmd_peek_data(ginfo->handle, cpu); |
170 | *out_job = *out_release = *out_deadline = 0; | 170 | *out_job = *out_release = *out_deadline = 0; |
@@ -177,8 +177,7 @@ get_previous_release(struct graph_info *ginfo, struct rt_task_info *rtt_info, | |||
177 | free_record(record); | 177 | free_record(record); |
178 | goto out; | 178 | goto out; |
179 | } | 179 | } |
180 | match = rt_graph_check_task_release(rtg_info, ginfo->pevent, | 180 | match = rt_graph_check_task_release(ginfo, record, &pid, &job, |
181 | record, &pid, &job, | ||
182 | &release, &deadline); | 181 | &release, &deadline); |
183 | free_record(last_record); | 182 | free_record(last_record); |
184 | last_record = record; | 183 | last_record = record; |
@@ -267,8 +266,7 @@ static int try_param(struct graph_info *ginfo, struct rt_task_info *rtt_info, | |||
267 | if (rtt_info->params_found) | 266 | if (rtt_info->params_found) |
268 | goto out; | 267 | goto out; |
269 | 268 | ||
270 | match = rt_graph_check_task_param(&ginfo->rtg_info, ginfo->pevent, | 269 | match = rt_graph_check_task_param(ginfo, record, &pid, &wcet, &period); |
271 | record, &pid, &wcet, &period); | ||
272 | if (match && pid == rtt_info->pid) { | 270 | if (match && pid == rtt_info->pid) { |
273 | update_job(rtt_info, 0); | 271 | update_job(rtt_info, 0); |
274 | rtt_info->wcet = wcet; | 272 | rtt_info->wcet = wcet; |
@@ -290,8 +288,7 @@ static int try_release(struct graph_info *ginfo, struct rt_task_info *rtt_info, | |||
290 | int pid, job, match, ret = 0; | 288 | int pid, job, match, ret = 0; |
291 | unsigned long long release, deadline; | 289 | unsigned long long release, deadline; |
292 | 290 | ||
293 | match = rt_graph_check_task_release(&ginfo->rtg_info, ginfo->pevent, | 291 | match = rt_graph_check_task_release(ginfo, record, &pid, &job, |
294 | record, &pid, &job, | ||
295 | &release, &deadline); | 292 | &release, &deadline); |
296 | if (match && pid == rtt_info->pid) { | 293 | if (match && pid == rtt_info->pid) { |
297 | update_job(rtt_info, job); | 294 | update_job(rtt_info, job); |
@@ -320,8 +317,7 @@ static int try_completion(struct graph_info *ginfo, | |||
320 | int pid, job, match, ret = 0; | 317 | int pid, job, match, ret = 0; |
321 | unsigned long long ts; | 318 | unsigned long long ts; |
322 | 319 | ||
323 | match = rt_graph_check_task_completion(&ginfo->rtg_info, ginfo->pevent, | 320 | match = rt_graph_check_task_completion(ginfo, record, &pid, &job, &ts); |
324 | record, &pid, &job, &ts); | ||
325 | if (match && pid == rtt_info->pid) { | 321 | if (match && pid == rtt_info->pid) { |
326 | 322 | ||
327 | info->completion = TRUE; | 323 | info->completion = TRUE; |
@@ -341,8 +337,7 @@ static int try_block(struct graph_info *ginfo, struct rt_task_info *rtt_info, | |||
341 | int pid, match, ret = 0; | 337 | int pid, match, ret = 0; |
342 | unsigned long long ts; | 338 | unsigned long long ts; |
343 | 339 | ||
344 | match = rt_graph_check_task_block(&ginfo->rtg_info, ginfo->pevent, | 340 | match = rt_graph_check_task_block(ginfo, record, &pid, &ts); |
345 | record, &pid, &ts); | ||
346 | if (match && pid == rtt_info->pid) { | 341 | if (match && pid == rtt_info->pid) { |
347 | rtt_info->fresh = FALSE; | 342 | rtt_info->fresh = FALSE; |
348 | rtt_info->block_time = ts; | 343 | rtt_info->block_time = ts; |
@@ -360,8 +355,7 @@ static int try_resume(struct graph_info *ginfo, struct rt_task_info *rtt_info, | |||
360 | int pid, match, ret = 0; | 355 | int pid, match, ret = 0; |
361 | unsigned long long ts; | 356 | unsigned long long ts; |
362 | 357 | ||
363 | match = rt_graph_check_task_resume(&ginfo->rtg_info, ginfo->pevent, | 358 | match = rt_graph_check_task_resume(ginfo, record, &pid, &ts); |
364 | record, &pid, &ts); | ||
365 | if (match && pid == rtt_info->pid) { | 359 | if (match && pid == rtt_info->pid) { |
366 | info->box = TRUE; | 360 | info->box = TRUE; |
367 | info->bcolor = 0x0; | 361 | info->bcolor = 0x0; |
@@ -388,8 +382,7 @@ try_switch_away(struct graph_info *ginfo, struct rt_task_info *rtt_info, | |||
388 | int job, pid, match, ret = 0; | 382 | int job, pid, match, ret = 0; |
389 | unsigned long long ts; | 383 | unsigned long long ts; |
390 | 384 | ||
391 | match = rt_graph_check_switch_away(&ginfo->rtg_info, ginfo->pevent, | 385 | match = rt_graph_check_switch_away(ginfo, record, &pid, &job, &ts); |
392 | record, &pid, &job, &ts); | ||
393 | if (match && pid == rtt_info->pid) { | 386 | if (match && pid == rtt_info->pid) { |
394 | update_job(rtt_info, job); | 387 | update_job(rtt_info, job); |
395 | 388 | ||
@@ -422,8 +415,7 @@ static int try_switch_to(struct graph_info *ginfo, struct rt_task_info *rtt_info | |||
422 | int job, pid, match, ret = 0; | 415 | int job, pid, match, ret = 0; |
423 | unsigned long long ts; | 416 | unsigned long long ts; |
424 | 417 | ||
425 | match = rt_graph_check_switch_to(&ginfo->rtg_info, ginfo->pevent, | 418 | match = rt_graph_check_switch_to(ginfo, record, &pid, &job, &ts); |
426 | record, &pid, &job, &ts); | ||
427 | if (match && pid == rtt_info->pid) { | 419 | if (match && pid == rtt_info->pid) { |
428 | update_job(rtt_info, job); | 420 | update_job(rtt_info, job); |
429 | rtt_info->run_time = ts; | 421 | rtt_info->run_time = ts; |
@@ -442,8 +434,7 @@ static int try_other(struct graph_info *ginfo, struct rt_task_info *rtt_info, | |||
442 | unsigned long long ts; | 434 | unsigned long long ts; |
443 | 435 | ||
444 | pid = rtt_info->pid; | 436 | pid = rtt_info->pid; |
445 | rt_graph_check_any(&ginfo->rtg_info, ginfo->pevent, record, | 437 | rt_graph_check_any(ginfo, record, &epid, &eid, &ts); |
446 | &epid, &eid, &ts); | ||
447 | 438 | ||
448 | my_pid = (pid == epid); | 439 | my_pid = (pid == epid); |
449 | my_cpu = (rtt_info->run_time && record->cpu == rtt_info->run_cpu); | 440 | my_cpu = (rtt_info->run_time && record->cpu == rtt_info->run_cpu); |
@@ -801,7 +792,7 @@ void rt_plot_task(struct graph_info *ginfo, int pid, int pos) | |||
801 | struct graph_plot *plot; | 792 | struct graph_plot *plot; |
802 | struct task_list *list; | 793 | struct task_list *list; |
803 | const char *comm; | 794 | const char *comm; |
804 | unsigned long long wm, wn, pm, pn; | 795 | float ms_wcet, ms_period; |
805 | char *plot_label; | 796 | char *plot_label; |
806 | int len; | 797 | int len; |
807 | 798 | ||
@@ -816,16 +807,16 @@ void rt_plot_task(struct graph_info *ginfo, int pid, int pos) | |||
816 | rtt_info->pid = pid; | 807 | rtt_info->pid = pid; |
817 | rtt_info->label = malloc_or_die(LLABEL); | 808 | rtt_info->label = malloc_or_die(LLABEL); |
818 | 809 | ||
819 | nano_to_milli(params->wcet, &wm, &wn); | 810 | ms_wcet = nano_as_milli(params->wcet); |
820 | nano_to_milli(params->period, &pm, &pn); | 811 | ms_period = nano_as_milli(params->period); |
821 | 812 | ||
822 | /* Create plot */ | 813 | /* Create plot */ |
823 | comm = pevent_data_comm_from_pid(ginfo->pevent, pid); | 814 | comm = pevent_data_comm_from_pid(ginfo->pevent, pid); |
824 | len = strlen(comm) + 100; | 815 | len = strlen(comm) + 100; |
825 | plot_label = malloc_or_die(len); | 816 | plot_label = malloc_or_die(len); |
826 | snprintf(plot_label, len, | 817 | snprintf(plot_label, len, |
827 | "%s-%d\n(%llu.%1llu, %llu.%1llu)", | 818 | "%s-%d\n(%1.1f, %1.1f)", |
828 | comm, pid, wm, wn, pm, pn); | 819 | comm, pid, ms_wcet, ms_period); |
829 | plot = trace_graph_plot_insert(ginfo, pos, plot_label, PLOT_TYPE_RT_TASK, | 820 | plot = trace_graph_plot_insert(ginfo, pos, plot_label, PLOT_TYPE_RT_TASK, |
830 | TIME_TYPE_RT, | 821 | TIME_TYPE_RT, |
831 | &rt_task_cb, rtt_info); | 822 | &rt_task_cb, rtt_info); |
diff --git a/trace-graph.c b/trace-graph.c index 226c893..d309bc8 100644 --- a/trace-graph.c +++ b/trace-graph.c | |||
@@ -55,7 +55,7 @@ | |||
55 | #define PLOT_GIVE 2 | 55 | #define PLOT_GIVE 2 |
56 | #define PLOT_BEGIN 80 | 56 | #define PLOT_BEGIN 80 |
57 | #define PLOT_SEP 50 | 57 | #define PLOT_SEP 50 |
58 | #define MAX_TRI_TIME 20000000 | 58 | #define MAX_TRI_TIME 10000000 |
59 | #define PLOT_LINE(plot) (PLOT_SEP * (plot) + PLOT_BEGIN + PLOT_SIZE) | 59 | #define PLOT_LINE(plot) (PLOT_SEP * (plot) + PLOT_BEGIN + PLOT_SIZE) |
60 | #define PLOT_TOP(plot) (PLOT_LINE(plot) - PLOT_SIZE * 2) | 60 | #define PLOT_TOP(plot) (PLOT_LINE(plot) - PLOT_SIZE * 2) |
61 | #define PLOT_BOX_TOP(plot) (PLOT_LINE(plot) - PLOT_SIZE) | 61 | #define PLOT_BOX_TOP(plot) (PLOT_LINE(plot) - PLOT_SIZE) |
@@ -1646,7 +1646,7 @@ static gint draw_plot_line(struct graph_info *ginfo, int i, | |||
1646 | x = convert_time_to_x(ginfo, time); | 1646 | x = convert_time_to_x(ginfo, time); |
1647 | y = PLOT_TOP(i); | 1647 | y = PLOT_TOP(i); |
1648 | 1648 | ||
1649 | if (!small || is_high_res(ginfo)) { | 1649 | if (is_high_res(ginfo)) { |
1650 | gdk_draw_line(ginfo->curr_pixmap, gc, | 1650 | gdk_draw_line(ginfo->curr_pixmap, gc, |
1651 | x, y, x, PLOT_BOTTOM(i)); | 1651 | x, y, x, PLOT_BOTTOM(i)); |
1652 | } | 1652 | } |
diff --git a/trace-plot-cpu.c b/trace-plot-cpu.c index 9b927e1..469b4fd 100644 --- a/trace-plot-cpu.c +++ b/trace-plot-cpu.c | |||
@@ -77,6 +77,7 @@ static int filter_record(struct graph_info *ginfo, | |||
77 | gboolean is_sched_switch = FALSE; | 77 | gboolean is_sched_switch = FALSE; |
78 | gboolean is_wakeup = FALSE; | 78 | gboolean is_wakeup = FALSE; |
79 | const char *comm; | 79 | const char *comm; |
80 | char *name; | ||
80 | int wake_pid; | 81 | int wake_pid; |
81 | int filter; | 82 | int filter; |
82 | gint rpid; | 83 | gint rpid; |
@@ -89,8 +90,10 @@ static int filter_record(struct graph_info *ginfo, | |||
89 | 90 | ||
90 | 91 | ||
91 | /* Load real-time records */ | 92 | /* Load real-time records */ |
92 | rt_graph_check_task_param(&ginfo->rtg_info, ginfo->pevent, record, | 93 | rt_graph_check_task_param(ginfo, record, |
93 | &rpid, &wcet, &period); | 94 | &rpid, &wcet, &period); |
95 | rt_graph_check_container_param(ginfo, record, &rpid, &name); | ||
96 | rt_graph_check_server_param(ginfo, record, &rpid, &rpid, &period, &wcet); | ||
94 | 97 | ||
95 | if (trace_graph_check_sched_switch(ginfo, record, sched_pid, &comm)) { | 98 | if (trace_graph_check_sched_switch(ginfo, record, sched_pid, &comm)) { |
96 | is_sched_switch = TRUE; | 99 | is_sched_switch = TRUE; |