diff options
author | Jonathan <hermanjl@hermanjl-Aspire-5553G.(none)> | 2012-03-05 14:22:27 -0500 |
---|---|---|
committer | Jonathan <hermanjl@hermanjl-Aspire-5553G.(none)> | 2012-03-05 14:22:27 -0500 |
commit | 8bcd73ddae5d74fb9b2b8aaedd3aa6a39ef3f75d (patch) | |
tree | 9688d2b57716c73b182722acab62101203a9105a | |
parent | f69435260fd14ef8d9ba13774da0fcba4b5d212c (diff) |
rt-graph: Litmus events and tasks loaded on startup
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | kernel-shark.c | 44 | ||||
-rw-r--r-- | rt-graph.c | 78 | ||||
-rw-r--r-- | rt-graph.h | 31 | ||||
-rw-r--r-- | trace-graph-main.c | 2 | ||||
-rw-r--r-- | trace-graph.c | 91 | ||||
-rw-r--r-- | trace-graph.h | 7 | ||||
-rw-r--r-- | trace-plot-cpu.c | 20 |
8 files changed, 164 insertions, 117 deletions
@@ -299,12 +299,14 @@ TRACE_GUI_OBJS = trace-filter.o trace-compat.o trace-hash.o trace-dialog.o \ | |||
299 | TRACE_CMD_OBJS = trace-cmd.o trace-record.o trace-read.o trace-split.o trace-listen.o \ | 299 | TRACE_CMD_OBJS = trace-cmd.o trace-record.o trace-read.o trace-split.o trace-listen.o \ |
300 | trace-stack.o trace-options.o | 300 | trace-stack.o trace-options.o |
301 | TRACE_VIEW_OBJS = trace-view.o trace-view-store.o | 301 | TRACE_VIEW_OBJS = trace-view.o trace-view-store.o |
302 | TRACE_GRAPH_OBJS = trace-graph.o trace-plot.o trace-plot-cpu.o trace-plot-task.o | 302 | RT_GRAPH_OBJS = rt-graph.o rt-plot-task.o |
303 | RT_GRAPH_OBJS = rt-graph.o | 303 | TRACE_GRAPH_OBJS = trace-graph.o trace-plot.o \ |
304 | trace-plot-cpu.o trace-plot-task.o \ | ||
305 | $(RT_GRAPH_OBJS) task-list.o | ||
304 | TRACE_VIEW_MAIN_OBJS = trace-view-main.o $(TRACE_VIEW_OBJS) $(TRACE_GUI_OBJS) | 306 | TRACE_VIEW_MAIN_OBJS = trace-view-main.o $(TRACE_VIEW_OBJS) $(TRACE_GUI_OBJS) |
305 | TRACE_GRAPH_MAIN_OBJS = trace-graph-main.o $(TRACE_GRAPH_OBJS) $(TRACE_GUI_OBJS) | 307 | TRACE_GRAPH_MAIN_OBJS = trace-graph-main.o $(TRACE_GRAPH_OBJS) $(TRACE_GUI_OBJS) |
306 | KERNEL_SHARK_OBJS = $(TRACE_VIEW_OBJS) $(TRACE_GRAPH_OBJS) $(TRACE_GUI_OBJS) \ | 308 | KERNEL_SHARK_OBJS = $(TRACE_VIEW_OBJS) $(TRACE_GRAPH_OBJS) $(TRACE_GUI_OBJS) \ |
307 | $(RT_GRAPH_OBJS) trace-capture.o kernel-shark.o | 309 | trace-capture.o kernel-shark.o |
308 | 310 | ||
309 | PEVENT_LIB_OBJS = parse-events.o trace-seq.o parse-filter.o parse-utils.o | 311 | PEVENT_LIB_OBJS = parse-events.o trace-seq.o parse-filter.o parse-utils.o |
310 | TCMD_LIB_OBJS = $(PEVENT_LIB_OBJS) trace-util.o trace-input.o trace-ftrace.o \ | 312 | TCMD_LIB_OBJS = $(PEVENT_LIB_OBJS) trace-util.o trace-input.o trace-ftrace.o \ |
diff --git a/kernel-shark.c b/kernel-shark.c index 0c89e00..e0c123a 100644 --- a/kernel-shark.c +++ b/kernel-shark.c | |||
@@ -969,7 +969,7 @@ __list_tasks_clicked (struct shark_info *info, | |||
969 | 969 | ||
970 | store = TRACE_VIEW_STORE(model); | 970 | store = TRACE_VIEW_STORE(model); |
971 | 971 | ||
972 | tasks = trace_graph_task_list(ginfo); | 972 | tasks = task_list_pids(ginfo->tasks); |
973 | selected = filter_task_pids(task_filter); | 973 | selected = filter_task_pids(task_filter); |
974 | 974 | ||
975 | trace_task_dialog(info->handle, tasks, selected, func, info); | 975 | trace_task_dialog(info->handle, tasks, selected, func, info); |
@@ -1068,7 +1068,7 @@ __graph_tasks_clicked (struct shark_info *info, | |||
1068 | if (!ginfo->handle) | 1068 | if (!ginfo->handle) |
1069 | return; | 1069 | return; |
1070 | 1070 | ||
1071 | tasks = trace_graph_task_list(ginfo); | 1071 | tasks = task_list_pids(ginfo->tasks); |
1072 | selected = filter_task_pids(task_filter); | 1072 | selected = filter_task_pids(task_filter); |
1073 | 1073 | ||
1074 | trace_task_dialog(ginfo->handle, tasks, selected, func, info); | 1074 | trace_task_dialog(ginfo->handle, tasks, selected, func, info); |
@@ -1268,7 +1268,7 @@ plot_tasks_clicked (gpointer data) | |||
1268 | if (!ginfo->handle) | 1268 | if (!ginfo->handle) |
1269 | return; | 1269 | return; |
1270 | 1270 | ||
1271 | tasks = trace_graph_task_list(ginfo); | 1271 | tasks = task_list_pids(ginfo->tasks); |
1272 | graph_plot_task_plotted(ginfo, &selected); | 1272 | graph_plot_task_plotted(ginfo, &selected); |
1273 | 1273 | ||
1274 | trace_task_dialog(ginfo->handle, tasks, selected, | 1274 | trace_task_dialog(ginfo->handle, tasks, selected, |
@@ -1277,6 +1277,29 @@ plot_tasks_clicked (gpointer data) | |||
1277 | free(selected); | 1277 | free(selected); |
1278 | } | 1278 | } |
1279 | 1279 | ||
1280 | /* Callback for the clicked signal of the plot real-time tasks button */ | ||
1281 | static void | ||
1282 | plot_rt_tasks_clicked (gpointer data) | ||
1283 | { | ||
1284 | struct shark_info *info = data; | ||
1285 | struct graph_info *ginfo = info->ginfo; | ||
1286 | struct rt_graph_info *rtinfo; | ||
1287 | gint *selected; | ||
1288 | gint *tasks; | ||
1289 | |||
1290 | if (!ginfo->handle) | ||
1291 | return; | ||
1292 | |||
1293 | rtinfo = &ginfo->rtinfo; | ||
1294 | tasks = task_list_pids(rtinfo->tasks); | ||
1295 | rt_plot_task_plotted(rtinfo, &selected); | ||
1296 | |||
1297 | trace_task_dialog(ginfo->handle, tasks, selected, | ||
1298 | rt_plot_task_update_callback, rtinfo); | ||
1299 | free(tasks); | ||
1300 | free(selected); | ||
1301 | } | ||
1302 | |||
1280 | /* Callback for the clicked signal of the help contents button */ | 1303 | /* Callback for the clicked signal of the help contents button */ |
1281 | static void | 1304 | static void |
1282 | help_content_clicked (gpointer data) | 1305 | help_content_clicked (gpointer data) |
@@ -2184,6 +2207,21 @@ void kernel_shark(int argc, char **argv) | |||
2184 | /* We do need to show menu items */ | 2207 | /* We do need to show menu items */ |
2185 | gtk_widget_show(sub_item); | 2208 | gtk_widget_show(sub_item); |
2186 | 2209 | ||
2210 | /* --- Plot - RT Tasks Option --- */ | ||
2211 | |||
2212 | sub_item = gtk_menu_item_new_with_label("Real-Time Tasks"); | ||
2213 | |||
2214 | /* Add them to the menu */ | ||
2215 | gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item); | ||
2216 | |||
2217 | /* We can attach the Quit menu item to our exit function */ | ||
2218 | g_signal_connect_swapped (G_OBJECT (sub_item), "activate", | ||
2219 | G_CALLBACK (plot_rt_tasks_clicked), | ||
2220 | (gpointer) info); | ||
2221 | |||
2222 | /* We do need to show menu items */ | ||
2223 | gtk_widget_show(sub_item); | ||
2224 | |||
2187 | 2225 | ||
2188 | /* --- End Plot Options --- */ | 2226 | /* --- End Plot Options --- */ |
2189 | gtk_menu_item_set_submenu(GTK_MENU_ITEM (menu_item), menu); | 2227 | gtk_menu_item_set_submenu(GTK_MENU_ITEM (menu_item), menu); |
@@ -1,5 +1,16 @@ | |||
1 | #include "rt-graph.h" | 1 | #include "rt-graph.h" |
2 | #include "trace-hash.h" | ||
2 | 3 | ||
4 | #define DEBUG_LEVEL 1 | ||
5 | #if DEBUG_LEVEL > 0 | ||
6 | #define dprintf(l, x...) \ | ||
7 | do { \ | ||
8 | if (l <= DEBUG_LEVEL) \ | ||
9 | printf(x); \ | ||
10 | } while (0) | ||
11 | #else | ||
12 | #define dprintf(l, x...) do { if (0) printf(x); } while (0) | ||
13 | #endif | ||
3 | /** | 14 | /** |
4 | * rt_graph_check_task_param - check for litmus_task_param record | 15 | * rt_graph_check_task_param - check for litmus_task_param record |
5 | * Return 1 and @pid, @wcet, and @period if the record matches | 16 | * Return 1 and @pid, @wcet, and @period if the record matches |
@@ -22,8 +33,9 @@ int rt_graph_check_task_param(struct rt_graph_info *rtinfo, | |||
22 | event = pevent_find_event_by_name(pevent, "litmus", | 33 | event = pevent_find_event_by_name(pevent, "litmus", |
23 | "litmus_task_param"); | 34 | "litmus_task_param"); |
24 | if (!event) | 35 | if (!event) |
25 | return 0; | 36 | goto out; |
26 | rtinfo->task_param_id = event->id; | 37 | rtinfo->task_param_id = event->id; |
38 | dprintf(2, "Found task_param id %d\n", event->id); | ||
27 | rtinfo->param_pid_field = pevent_find_field(event, "pid"); | 39 | rtinfo->param_pid_field = pevent_find_field(event, "pid"); |
28 | rtinfo->param_wcet_field = pevent_find_field(event, "wcet"); | 40 | rtinfo->param_wcet_field = pevent_find_field(event, "wcet"); |
29 | rtinfo->param_period_field = pevent_find_field(event, "period"); | 41 | rtinfo->param_period_field = pevent_find_field(event, "period"); |
@@ -39,8 +51,13 @@ int rt_graph_check_task_param(struct rt_graph_info *rtinfo, | |||
39 | pevent_read_number_field(rtinfo->param_period_field, | 51 | pevent_read_number_field(rtinfo->param_period_field, |
40 | record->data, period); | 52 | record->data, period); |
41 | ret = 1; | 53 | ret = 1; |
42 | } | 54 | dprintf(3, "Read task_param (%d) record for task %d " |
55 | "(%llu, %llu)\n", id, *pid, *wcet, *period); | ||
43 | 56 | ||
57 | /* Only of these per task, so we can safely add new tasks now */ | ||
58 | add_task_hash(rtinfo->tasks, *pid); | ||
59 | } | ||
60 | out: | ||
44 | return ret; | 61 | return ret; |
45 | } | 62 | } |
46 | 63 | ||
@@ -50,7 +67,7 @@ int rt_graph_check_task_param(struct rt_graph_info *rtinfo, | |||
50 | */ | 67 | */ |
51 | int rt_graph_check_task_release(struct rt_graph_info *rtinfo, | 68 | int rt_graph_check_task_release(struct rt_graph_info *rtinfo, |
52 | struct pevent *pevent, struct record *record, | 69 | struct pevent *pevent, struct record *record, |
53 | gint *pid, gint *job, | 70 | gint *pid, gint *job, unsigned long long *release, |
54 | unsigned long long *deadline) | 71 | unsigned long long *deadline) |
55 | { | 72 | { |
56 | struct event_format *event; | 73 | struct event_format *event; |
@@ -62,10 +79,12 @@ int rt_graph_check_task_release(struct rt_graph_info *rtinfo, | |||
62 | event = pevent_find_event_by_name(pevent, "litmus", | 79 | event = pevent_find_event_by_name(pevent, "litmus", |
63 | "litmus_task_release"); | 80 | "litmus_task_release"); |
64 | if (!event) | 81 | if (!event) |
65 | return 0; | 82 | goto out; |
66 | rtinfo->task_release_id = event->id; | 83 | rtinfo->task_release_id = event->id; |
84 | dprintf(2, "Found task_release id %d\n", event->id); | ||
67 | rtinfo->release_pid_field = pevent_find_field(event, "pid"); | 85 | rtinfo->release_pid_field = pevent_find_field(event, "pid"); |
68 | rtinfo->release_job_field = pevent_find_field(event, "job"); | 86 | rtinfo->release_job_field = pevent_find_field(event, "job"); |
87 | rtinfo->release_release_field = pevent_find_field(event, "release"); | ||
69 | rtinfo->release_deadline_field = pevent_find_field(event, "deadline"); | 88 | rtinfo->release_deadline_field = pevent_find_field(event, "deadline"); |
70 | } | 89 | } |
71 | 90 | ||
@@ -77,11 +96,15 @@ int rt_graph_check_task_release(struct rt_graph_info *rtinfo, | |||
77 | pevent_read_number_field(rtinfo->release_job_field, | 96 | pevent_read_number_field(rtinfo->release_job_field, |
78 | record->data, &val); | 97 | record->data, &val); |
79 | *job = val; | 98 | *job = val; |
99 | pevent_read_number_field(rtinfo->release_release_field, | ||
100 | record->data, release); | ||
80 | pevent_read_number_field(rtinfo->release_deadline_field, | 101 | pevent_read_number_field(rtinfo->release_deadline_field, |
81 | record->data, deadline); | 102 | record->data, deadline); |
82 | ret = 1; | 103 | ret = 1; |
104 | dprintf(3, "Read task_release (%d) record for job %d:%d, " | ||
105 | "dead: %llu\n", id, *pid, *job, *deadline); | ||
83 | } | 106 | } |
84 | 107 | out: | |
85 | return ret; | 108 | return ret; |
86 | } | 109 | } |
87 | 110 | ||
@@ -91,21 +114,23 @@ int rt_graph_check_task_release(struct rt_graph_info *rtinfo, | |||
91 | */ | 114 | */ |
92 | int rt_graph_check_task_completion(struct rt_graph_info *rtinfo, | 115 | int rt_graph_check_task_completion(struct rt_graph_info *rtinfo, |
93 | struct pevent *pevent, struct record *record, | 116 | struct pevent *pevent, struct record *record, |
94 | gint *pid, gint *job) | 117 | gint *pid, gint *job, unsigned long long *when) |
95 | { | 118 | { |
96 | struct event_format *event; | 119 | struct event_format *event; |
97 | unsigned long long val; | 120 | unsigned long long val; |
98 | gint id; | 121 | gint id; |
99 | int ret = 0; | 122 | int ret = 0; |
100 | 123 | ||
101 | if (rtinfo->task_param_id < 0) { | 124 | if (rtinfo->task_completion_id < 0) { |
102 | event = pevent_find_event_by_name(pevent, "litmus", | 125 | event = pevent_find_event_by_name(pevent, "litmus", |
103 | "litmus_task_completion"); | 126 | "litmus_task_completion"); |
104 | if (!event) | 127 | if (!event) |
105 | return 0; | 128 | goto out; |
106 | rtinfo->task_completion_id = event->id; | 129 | rtinfo->task_completion_id = event->id; |
130 | dprintf(2, "Found task_completion id %d\n", event->id); | ||
107 | rtinfo->completion_pid_field = pevent_find_field(event, "pid"); | 131 | rtinfo->completion_pid_field = pevent_find_field(event, "pid"); |
108 | rtinfo->completion_job_field = pevent_find_field(event, "job"); | 132 | rtinfo->completion_job_field = pevent_find_field(event, "job"); |
133 | rtinfo->completion_when_field = pevent_find_field(event, "when"); | ||
109 | } | 134 | } |
110 | 135 | ||
111 | id = pevent_data_type(pevent, record); | 136 | id = pevent_data_type(pevent, record); |
@@ -116,9 +141,13 @@ int rt_graph_check_task_completion(struct rt_graph_info *rtinfo, | |||
116 | pevent_read_number_field(rtinfo->completion_job_field, | 141 | pevent_read_number_field(rtinfo->completion_job_field, |
117 | record->data, &val); | 142 | record->data, &val); |
118 | *job = val; | 143 | *job = val; |
144 | pevent_read_number_field(rtinfo->completion_when_field, | ||
145 | record->data, when); | ||
119 | ret = 1; | 146 | ret = 1; |
147 | dprintf(3, "Read task_completion (%d) record for job %d:%d\n", | ||
148 | id, *pid, *job); | ||
120 | } | 149 | } |
121 | 150 | out: | |
122 | return ret; | 151 | return ret; |
123 | } | 152 | } |
124 | 153 | ||
@@ -128,7 +157,7 @@ int rt_graph_check_task_completion(struct rt_graph_info *rtinfo, | |||
128 | */ | 157 | */ |
129 | int rt_graph_check_task_block(struct rt_graph_info *rtinfo, | 158 | int rt_graph_check_task_block(struct rt_graph_info *rtinfo, |
130 | struct pevent *pevent, struct record *record, | 159 | struct pevent *pevent, struct record *record, |
131 | gint *pid) | 160 | gint *pid, unsigned long long *when) |
132 | { | 161 | { |
133 | struct event_format *event; | 162 | struct event_format *event; |
134 | unsigned long long val; | 163 | unsigned long long val; |
@@ -139,9 +168,11 @@ int rt_graph_check_task_block(struct rt_graph_info *rtinfo, | |||
139 | event = pevent_find_event_by_name(pevent, "litmus", | 168 | event = pevent_find_event_by_name(pevent, "litmus", |
140 | "litmus_task_block"); | 169 | "litmus_task_block"); |
141 | if (!event) | 170 | if (!event) |
142 | return 0; | 171 | goto out; |
172 | dprintf(2, "Found task_block id %d\n", event->id); | ||
143 | rtinfo->task_block_id = event->id; | 173 | rtinfo->task_block_id = event->id; |
144 | rtinfo->block_pid_field = pevent_find_field(event, "pid"); | 174 | rtinfo->block_pid_field = pevent_find_field(event, "pid"); |
175 | rtinfo->block_when_field = pevent_find_field(event, "when"); | ||
145 | } | 176 | } |
146 | 177 | ||
147 | id = pevent_data_type(pevent, record); | 178 | id = pevent_data_type(pevent, record); |
@@ -149,9 +180,13 @@ int rt_graph_check_task_block(struct rt_graph_info *rtinfo, | |||
149 | pevent_read_number_field(rtinfo->block_pid_field, | 180 | pevent_read_number_field(rtinfo->block_pid_field, |
150 | record->data, &val); | 181 | record->data, &val); |
151 | *pid = val; | 182 | *pid = val; |
183 | pevent_read_number_field(rtinfo->block_when_field, | ||
184 | record->data, when); | ||
152 | ret = 1; | 185 | ret = 1; |
186 | dprintf(3, "Read task_block (%d) record for task %d\n", | ||
187 | id, *pid); | ||
153 | } | 188 | } |
154 | 189 | out: | |
155 | return ret; | 190 | return ret; |
156 | } | 191 | } |
157 | 192 | ||
@@ -161,7 +196,7 @@ int rt_graph_check_task_block(struct rt_graph_info *rtinfo, | |||
161 | */ | 196 | */ |
162 | int rt_graph_check_task_resume(struct rt_graph_info *rtinfo, | 197 | int rt_graph_check_task_resume(struct rt_graph_info *rtinfo, |
163 | struct pevent *pevent, struct record *record, | 198 | struct pevent *pevent, struct record *record, |
164 | gint *pid) | 199 | gint *pid, unsigned long long *when) |
165 | { | 200 | { |
166 | struct event_format *event; | 201 | struct event_format *event; |
167 | unsigned long long val; | 202 | unsigned long long val; |
@@ -172,9 +207,11 @@ int rt_graph_check_task_resume(struct rt_graph_info *rtinfo, | |||
172 | event = pevent_find_event_by_name(pevent, "litmus", | 207 | event = pevent_find_event_by_name(pevent, "litmus", |
173 | "litmus_task_resume"); | 208 | "litmus_task_resume"); |
174 | if (!event) | 209 | if (!event) |
175 | return 0; | 210 | goto out; |
211 | dprintf(2, "Found task_resume id %d\n", event->id); | ||
176 | rtinfo->task_resume_id = event->id; | 212 | rtinfo->task_resume_id = event->id; |
177 | rtinfo->resume_pid_field = pevent_find_field(event, "pid"); | 213 | rtinfo->resume_pid_field = pevent_find_field(event, "pid"); |
214 | rtinfo->resume_when_field = pevent_find_field(event, "when"); | ||
178 | } | 215 | } |
179 | 216 | ||
180 | id = pevent_data_type(pevent, record); | 217 | id = pevent_data_type(pevent, record); |
@@ -182,9 +219,13 @@ int rt_graph_check_task_resume(struct rt_graph_info *rtinfo, | |||
182 | pevent_read_number_field(rtinfo->resume_pid_field, | 219 | pevent_read_number_field(rtinfo->resume_pid_field, |
183 | record->data, &val); | 220 | record->data, &val); |
184 | *pid = val; | 221 | *pid = val; |
222 | pevent_read_number_field(rtinfo->resume_when_field, | ||
223 | record->data, when); | ||
185 | ret = 1; | 224 | ret = 1; |
225 | dprintf(3, "Read task_resume (%d) record for task %d\n", | ||
226 | id, *pid); | ||
186 | } | 227 | } |
187 | 228 | out: | |
188 | return ret; | 229 | return ret; |
189 | } | 230 | } |
190 | 231 | ||
@@ -193,7 +234,7 @@ int rt_graph_check_task_resume(struct rt_graph_info *rtinfo, | |||
193 | */ | 234 | */ |
194 | void init_rt_event_cache(struct rt_graph_info *rtinfo) | 235 | void init_rt_event_cache(struct rt_graph_info *rtinfo) |
195 | { | 236 | { |
196 | print("hello"); | 237 | dprintf(1, "Initializing RT event cache\n"); |
197 | rtinfo->task_param_id = -1; | 238 | rtinfo->task_param_id = -1; |
198 | rtinfo->task_release_id = -1; | 239 | rtinfo->task_release_id = -1; |
199 | rtinfo->task_completion_id = -1; | 240 | rtinfo->task_completion_id = -1; |
@@ -206,11 +247,16 @@ void init_rt_event_cache(struct rt_graph_info *rtinfo) | |||
206 | 247 | ||
207 | rtinfo->release_pid_field = NULL; | 248 | rtinfo->release_pid_field = NULL; |
208 | rtinfo->release_job_field = NULL; | 249 | rtinfo->release_job_field = NULL; |
250 | rtinfo->release_release_field = NULL; | ||
209 | rtinfo->release_deadline_field = NULL; | 251 | rtinfo->release_deadline_field = NULL; |
210 | 252 | ||
211 | rtinfo->completion_pid_field = NULL; | 253 | rtinfo->completion_pid_field = NULL; |
212 | rtinfo->completion_job_field = NULL; | 254 | rtinfo->completion_job_field = NULL; |
255 | rtinfo->completion_when_field = NULL; | ||
213 | 256 | ||
214 | rtinfo->block_pid_field = NULL; | 257 | rtinfo->block_pid_field = NULL; |
258 | rtinfo->block_when_field = NULL; | ||
259 | |||
215 | rtinfo->resume_pid_field = NULL; | 260 | rtinfo->resume_pid_field = NULL; |
261 | rtinfo->resume_when_field = NULL; | ||
216 | } | 262 | } |
@@ -3,9 +3,13 @@ | |||
3 | 3 | ||
4 | #include <gtk/gtk.h> | 4 | #include <gtk/gtk.h> |
5 | #include "trace-cmd.h" | 5 | #include "trace-cmd.h" |
6 | #include "task-list.h" | ||
6 | 7 | ||
7 | struct rt_graph_info { | 8 | struct rt_graph_info { |
8 | 9 | ||
10 | /* List of all tasks */ | ||
11 | struct task_list *tasks[TASK_HASH_SIZE]; | ||
12 | |||
9 | /* Cache of event fields so that they don't need to be located | 13 | /* Cache of event fields so that they don't need to be located |
10 | * during each access. | 14 | * during each access. |
11 | */ | 15 | */ |
@@ -13,33 +17,54 @@ struct rt_graph_info { | |||
13 | struct format_field *param_pid_field; | 17 | struct format_field *param_pid_field; |
14 | struct format_field *param_wcet_field; | 18 | struct format_field *param_wcet_field; |
15 | struct format_field *param_period_field; | 19 | struct format_field *param_period_field; |
20 | |||
16 | gint task_release_id; | 21 | gint task_release_id; |
17 | struct format_field *release_pid_field; | 22 | struct format_field *release_pid_field; |
18 | struct format_field *release_job_field; | 23 | struct format_field *release_job_field; |
24 | struct format_field *release_release_field; | ||
19 | struct format_field *release_deadline_field; | 25 | struct format_field *release_deadline_field; |
26 | |||
20 | gint task_completion_id; | 27 | gint task_completion_id; |
21 | struct format_field *completion_pid_field; | 28 | struct format_field *completion_pid_field; |
22 | struct format_field *completion_job_field; | 29 | struct format_field *completion_job_field; |
30 | struct format_field *completion_when_field; | ||
31 | |||
23 | gint task_block_id; | 32 | gint task_block_id; |
24 | struct format_field *block_pid_field; | 33 | struct format_field *block_pid_field; |
34 | struct format_field *block_when_field; | ||
35 | |||
25 | gint task_resume_id; | 36 | gint task_resume_id; |
26 | struct format_field *resume_pid_field; | 37 | struct format_field *resume_pid_field; |
38 | struct format_field *resume_when_field; | ||
27 | 39 | ||
28 | }; | 40 | }; |
29 | 41 | ||
42 | /* Event parsers */ | ||
30 | int rt_graph_check_task_param(struct rt_graph_info *rtinfo, struct pevent *pevent, | 43 | int rt_graph_check_task_param(struct rt_graph_info *rtinfo, struct pevent *pevent, |
31 | struct record *record, gint *pid, | 44 | struct record *record, gint *pid, |
32 | unsigned long long *wcet, | 45 | unsigned long long *wcet, |
33 | unsigned long long *period); | 46 | unsigned long long *period); |
34 | int rt_graph_check_task_release(struct rt_graph_info *rtinfo, struct pevent *pevent, | 47 | int rt_graph_check_task_release(struct rt_graph_info *rtinfo, struct pevent *pevent, |
35 | struct record *record, gint *pid, gint *job, | 48 | struct record *record, gint *pid, gint *job, |
49 | unsigned long long *release, | ||
36 | unsigned long long *deadline); | 50 | unsigned long long *deadline); |
37 | int rt_graph_check_task_completion(struct rt_graph_info *rtinfo, struct pevent *pevent, | 51 | int rt_graph_check_task_completion(struct rt_graph_info *rtinfo, struct pevent *pevent, |
38 | struct record *record, gint *pid, gint *job); | 52 | struct record *record, gint *pid, gint *job, |
53 | unsigned long long *when); | ||
39 | int rt_graph_check_task_block(struct rt_graph_info *rtinfo, struct pevent *pevent, | 54 | int rt_graph_check_task_block(struct rt_graph_info *rtinfo, struct pevent *pevent, |
40 | struct record *record, gint *pid); | 55 | struct record *record, gint *pid, |
56 | unsigned long long *when); | ||
41 | int rt_graph_check_task_resume(struct rt_graph_info *rtinfo, struct pevent *pevent, | 57 | int rt_graph_check_task_resume(struct rt_graph_info *rtinfo, struct pevent *pevent, |
42 | struct record *record, gint *pid); | 58 | struct record *record, gint *pid, |
59 | unsigned long long *when); | ||
43 | void init_rt_event_cache(struct rt_graph_info *rtinfo); | 60 | void init_rt_event_cache(struct rt_graph_info *rtinfo); |
44 | 61 | ||
62 | /* Metadata */ | ||
63 | void rt_plot_task_plotted(struct rt_graph_info *rt_info, gint **plotted); | ||
64 | |||
65 | /* Callbacks for managing task list */ | ||
66 | void rt_plot_task_update_callback(gboolean accept, gint *selected, | ||
67 | gint *non_select, gpointer data); | ||
68 | void rt_plot_task_plotted(struct rt_graph_info *rtinfo, gint **plotted); | ||
69 | |||
45 | #endif | 70 | #endif |
diff --git a/trace-graph-main.c b/trace-graph-main.c index f2c8e54..b296994 100644 --- a/trace-graph-main.c +++ b/trace-graph-main.c | |||
@@ -145,7 +145,7 @@ plot_tasks_clicked (gpointer data) | |||
145 | if (!ginfo->handle) | 145 | if (!ginfo->handle) |
146 | return; | 146 | return; |
147 | 147 | ||
148 | tasks = trace_graph_task_list(ginfo); | 148 | tasks = task_list_pids(ginfo->tasks); |
149 | graph_plot_task_plotted(ginfo, &selected); | 149 | graph_plot_task_plotted(ginfo, &selected); |
150 | 150 | ||
151 | trace_task_dialog(ginfo->handle, tasks, selected, | 151 | trace_task_dialog(ginfo->handle, tasks, selected, |
diff --git a/trace-graph.c b/trace-graph.c index 6dafadf..819482e 100644 --- a/trace-graph.c +++ b/trace-graph.c | |||
@@ -70,91 +70,6 @@ static GdkGC *red; | |||
70 | static void redraw_pixmap_backend(struct graph_info *ginfo); | 70 | static void redraw_pixmap_backend(struct graph_info *ginfo); |
71 | static void update_label_window(struct graph_info *ginfo); | 71 | static void update_label_window(struct graph_info *ginfo); |
72 | 72 | ||
73 | struct task_list { | ||
74 | struct task_list *next; | ||
75 | gint pid; | ||
76 | }; | ||
77 | |||
78 | static guint get_task_hash_key(gint pid) | ||
79 | { | ||
80 | return trace_hash(pid) % TASK_HASH_SIZE; | ||
81 | } | ||
82 | |||
83 | static struct task_list *find_task_hash(struct graph_info *ginfo, | ||
84 | gint key, gint pid) | ||
85 | { | ||
86 | struct task_list *list; | ||
87 | |||
88 | for (list = ginfo->tasks[key]; list; list = list->next) { | ||
89 | if (list->pid == pid) | ||
90 | return list; | ||
91 | } | ||
92 | |||
93 | return NULL; | ||
94 | } | ||
95 | |||
96 | static struct task_list *add_task_hash(struct graph_info *ginfo, | ||
97 | int pid) | ||
98 | { | ||
99 | struct task_list *list; | ||
100 | guint key = get_task_hash_key(pid); | ||
101 | |||
102 | list = find_task_hash(ginfo, key, pid); | ||
103 | if (list) | ||
104 | return list; | ||
105 | |||
106 | list = malloc_or_die(sizeof(*list)); | ||
107 | list->pid = pid; | ||
108 | list->next = ginfo->tasks[key]; | ||
109 | ginfo->tasks[key] = list; | ||
110 | |||
111 | return list; | ||
112 | } | ||
113 | |||
114 | static void free_task_hash(struct graph_info *ginfo) | ||
115 | { | ||
116 | struct task_list *list; | ||
117 | int i; | ||
118 | |||
119 | for (i = 0; i < TASK_HASH_SIZE; i++) { | ||
120 | while (ginfo->tasks[i]) { | ||
121 | list = ginfo->tasks[i]; | ||
122 | ginfo->tasks[i] = list->next; | ||
123 | free(list); | ||
124 | } | ||
125 | } | ||
126 | } | ||
127 | |||
128 | /** | ||
129 | * trace_graph_task_list - return an allocated list of all found tasks | ||
130 | * @ginfo: The graph info structure | ||
131 | * | ||
132 | * Returns an allocated list of pids found in the graph, ending | ||
133 | * with a -1. This array must be freed with free(). | ||
134 | */ | ||
135 | gint *trace_graph_task_list(struct graph_info *ginfo) | ||
136 | { | ||
137 | struct task_list *list; | ||
138 | gint *pids; | ||
139 | gint count = 0; | ||
140 | gint i; | ||
141 | |||
142 | for (i = 0; i < TASK_HASH_SIZE; i++) { | ||
143 | list = ginfo->tasks[i]; | ||
144 | while (list) { | ||
145 | if (count) | ||
146 | pids = realloc(pids, sizeof(*pids) * (count + 2)); | ||
147 | else | ||
148 | pids = malloc(sizeof(*pids) * 2); | ||
149 | pids[count++] = list->pid; | ||
150 | pids[count] = -1; | ||
151 | list = list->next; | ||
152 | } | ||
153 | } | ||
154 | |||
155 | return pids; | ||
156 | } | ||
157 | |||
158 | static void convert_nano(unsigned long long time, unsigned long *sec, | 73 | static void convert_nano(unsigned long long time, unsigned long *sec, |
159 | unsigned long *usec) | 74 | unsigned long *usec) |
160 | { | 75 | { |
@@ -210,6 +125,8 @@ static void init_event_cache(struct graph_info *ginfo) | |||
210 | * it into the pevent command line list. | 125 | * it into the pevent command line list. |
211 | */ | 126 | */ |
212 | ginfo->read_comms = TRUE; | 127 | ginfo->read_comms = TRUE; |
128 | |||
129 | init_rt_event_cache(&ginfo->rtinfo); | ||
213 | } | 130 | } |
214 | 131 | ||
215 | struct filter_task_item * | 132 | struct filter_task_item * |
@@ -1082,7 +999,7 @@ int trace_graph_check_sched_switch(struct graph_info *ginfo, | |||
1082 | if (ginfo->read_comms) { | 999 | if (ginfo->read_comms) { |
1083 | /* record all pids, for task plots */ | 1000 | /* record all pids, for task plots */ |
1084 | this_pid = pevent_data_pid(ginfo->pevent, record); | 1001 | this_pid = pevent_data_pid(ginfo->pevent, record); |
1085 | add_task_hash(ginfo, this_pid); | 1002 | add_task_hash(ginfo->tasks, this_pid); |
1086 | } | 1003 | } |
1087 | 1004 | ||
1088 | if (ginfo->event_sched_switch_id < 0) { | 1005 | if (ginfo->event_sched_switch_id < 0) { |
@@ -2385,7 +2302,7 @@ void trace_graph_free_info(struct graph_info *ginfo) | |||
2385 | pevent_filter_free(ginfo->event_filter); | 2302 | pevent_filter_free(ginfo->event_filter); |
2386 | trace_graph_plot_free(ginfo); | 2303 | trace_graph_plot_free(ginfo); |
2387 | tracecmd_close(ginfo->handle); | 2304 | tracecmd_close(ginfo->handle); |
2388 | free_task_hash(ginfo); | 2305 | free_task_hash(ginfo->tasks); |
2389 | 2306 | ||
2390 | ginfo->cursor = 0; | 2307 | ginfo->cursor = 0; |
2391 | } | 2308 | } |
diff --git a/trace-graph.h b/trace-graph.h index c3ae5a3..92d9883 100644 --- a/trace-graph.h +++ b/trace-graph.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #include "trace-cmd.h" | 25 | #include "trace-cmd.h" |
26 | #include "trace-hash.h" | 26 | #include "trace-hash.h" |
27 | #include "trace-xml.h" | 27 | #include "trace-xml.h" |
28 | #include "task-list.h" | ||
28 | #include "rt-graph.h" | 29 | #include "rt-graph.h" |
29 | 30 | ||
30 | struct graph_info; | 31 | struct graph_info; |
@@ -146,8 +147,6 @@ struct plot_hash { | |||
146 | }; | 147 | }; |
147 | 148 | ||
148 | #define PLOT_HASH_SIZE 1024 | 149 | #define PLOT_HASH_SIZE 1024 |
149 | #define TASK_HASH_SIZE 1024 | ||
150 | struct task_list; | ||
151 | 150 | ||
152 | struct graph_info { | 151 | struct graph_info { |
153 | struct tracecmd_input *handle; | 152 | struct tracecmd_input *handle; |
@@ -230,7 +229,7 @@ struct graph_info { | |||
230 | struct format_field *wakeup_new_pid_field; | 229 | struct format_field *wakeup_new_pid_field; |
231 | struct format_field *wakeup_new_success_field; | 230 | struct format_field *wakeup_new_success_field; |
232 | 231 | ||
233 | struct rt_graph_info rt_info; | 232 | struct rt_graph_info rtinfo; |
234 | 233 | ||
235 | gboolean read_comms; /* Read all comms on first load */ | 234 | gboolean read_comms; /* Read all comms on first load */ |
236 | 235 | ||
@@ -308,7 +307,6 @@ gboolean trace_graph_filter_on_event(struct graph_info *ginfo, struct record *re | |||
308 | void trace_graph_copy_filter(struct graph_info *ginfo, | 307 | void trace_graph_copy_filter(struct graph_info *ginfo, |
309 | gboolean all_events, | 308 | gboolean all_events, |
310 | struct event_filter *event_filter); | 309 | struct event_filter *event_filter); |
311 | gint *trace_graph_task_list(struct graph_info *ginfo); | ||
312 | 310 | ||
313 | int trace_graph_load_filters(struct graph_info *ginfo, | 311 | int trace_graph_load_filters(struct graph_info *ginfo, |
314 | struct tracecmd_xml_handle *handle); | 312 | struct tracecmd_xml_handle *handle); |
@@ -400,4 +398,5 @@ void graph_plot_task_update_callback(gboolean accept, | |||
400 | void graph_plot_task_plotted(struct graph_info *ginfo, | 398 | void graph_plot_task_plotted(struct graph_info *ginfo, |
401 | gint **plotted); | 399 | gint **plotted); |
402 | 400 | ||
401 | |||
403 | #endif /* _TRACE_GRAPH_H */ | 402 | #endif /* _TRACE_GRAPH_H */ |
diff --git a/trace-plot-cpu.c b/trace-plot-cpu.c index 7514b34..5dea225 100644 --- a/trace-plot-cpu.c +++ b/trace-plot-cpu.c | |||
@@ -95,11 +95,31 @@ static int filter_record(struct graph_info *ginfo, | |||
95 | const char *comm; | 95 | const char *comm; |
96 | int wake_pid; | 96 | int wake_pid; |
97 | int filter; | 97 | int filter; |
98 | gint rpid; | ||
99 | gint job; | ||
100 | unsigned long long release; | ||
101 | unsigned long long deadline; | ||
102 | unsigned long long period; | ||
103 | unsigned long long wcet; | ||
104 | unsigned long long when; | ||
98 | 105 | ||
99 | *orig_pid = pevent_data_pid(ginfo->pevent, record); | 106 | *orig_pid = pevent_data_pid(ginfo->pevent, record); |
100 | 107 | ||
101 | filter = trace_graph_filter_on_task(ginfo, *orig_pid); | 108 | filter = trace_graph_filter_on_task(ginfo, *orig_pid); |
102 | 109 | ||
110 | |||
111 | /* Load real-time records */ | ||
112 | rt_graph_check_task_param(&ginfo->rtinfo, ginfo->pevent, record, | ||
113 | &rpid, &wcet, &period); | ||
114 | rt_graph_check_task_release(&ginfo->rtinfo, ginfo->pevent, record, | ||
115 | &rpid, &job, &release, &deadline); | ||
116 | rt_graph_check_task_completion(&ginfo->rtinfo, ginfo->pevent, record, | ||
117 | &rpid, &job, &when); | ||
118 | rt_graph_check_task_block(&ginfo->rtinfo, ginfo->pevent, record, | ||
119 | &rpid, &when); | ||
120 | rt_graph_check_task_resume(&ginfo->rtinfo, ginfo->pevent, record, | ||
121 | &rpid, &when); | ||
122 | |||
103 | if (trace_graph_check_sched_switch(ginfo, record, sched_pid, &comm)) { | 123 | if (trace_graph_check_sched_switch(ginfo, record, sched_pid, &comm)) { |
104 | is_sched_switch = TRUE; | 124 | is_sched_switch = TRUE; |
105 | 125 | ||