aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan <hermanjl@hermanjl-Aspire-5553G.(none)>2012-03-05 14:22:27 -0500
committerJonathan <hermanjl@hermanjl-Aspire-5553G.(none)>2012-03-05 14:22:27 -0500
commit8bcd73ddae5d74fb9b2b8aaedd3aa6a39ef3f75d (patch)
tree9688d2b57716c73b182722acab62101203a9105a
parentf69435260fd14ef8d9ba13774da0fcba4b5d212c (diff)
rt-graph: Litmus events and tasks loaded on startup
-rw-r--r--Makefile8
-rw-r--r--kernel-shark.c44
-rw-r--r--rt-graph.c78
-rw-r--r--rt-graph.h31
-rw-r--r--trace-graph-main.c2
-rw-r--r--trace-graph.c91
-rw-r--r--trace-graph.h7
-rw-r--r--trace-plot-cpu.c20
8 files changed, 164 insertions, 117 deletions
diff --git a/Makefile b/Makefile
index c97cab7..dc7100e 100644
--- a/Makefile
+++ b/Makefile
@@ -299,12 +299,14 @@ TRACE_GUI_OBJS = trace-filter.o trace-compat.o trace-hash.o trace-dialog.o \
299TRACE_CMD_OBJS = trace-cmd.o trace-record.o trace-read.o trace-split.o trace-listen.o \ 299TRACE_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
301TRACE_VIEW_OBJS = trace-view.o trace-view-store.o 301TRACE_VIEW_OBJS = trace-view.o trace-view-store.o
302TRACE_GRAPH_OBJS = trace-graph.o trace-plot.o trace-plot-cpu.o trace-plot-task.o 302RT_GRAPH_OBJS = rt-graph.o rt-plot-task.o
303RT_GRAPH_OBJS = rt-graph.o 303TRACE_GRAPH_OBJS = trace-graph.o trace-plot.o \
304 trace-plot-cpu.o trace-plot-task.o \
305 $(RT_GRAPH_OBJS) task-list.o
304TRACE_VIEW_MAIN_OBJS = trace-view-main.o $(TRACE_VIEW_OBJS) $(TRACE_GUI_OBJS) 306TRACE_VIEW_MAIN_OBJS = trace-view-main.o $(TRACE_VIEW_OBJS) $(TRACE_GUI_OBJS)
305TRACE_GRAPH_MAIN_OBJS = trace-graph-main.o $(TRACE_GRAPH_OBJS) $(TRACE_GUI_OBJS) 307TRACE_GRAPH_MAIN_OBJS = trace-graph-main.o $(TRACE_GRAPH_OBJS) $(TRACE_GUI_OBJS)
306KERNEL_SHARK_OBJS = $(TRACE_VIEW_OBJS) $(TRACE_GRAPH_OBJS) $(TRACE_GUI_OBJS) \ 308KERNEL_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
309PEVENT_LIB_OBJS = parse-events.o trace-seq.o parse-filter.o parse-utils.o 311PEVENT_LIB_OBJS = parse-events.o trace-seq.o parse-filter.o parse-utils.o
310TCMD_LIB_OBJS = $(PEVENT_LIB_OBJS) trace-util.o trace-input.o trace-ftrace.o \ 312TCMD_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 */
1281static void
1282plot_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 */
1281static void 1304static void
1282help_content_clicked (gpointer data) 1305help_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);
diff --git a/rt-graph.c b/rt-graph.c
index 6eab52f..71f2033 100644
--- a/rt-graph.c
+++ b/rt-graph.c
@@ -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 */
51int rt_graph_check_task_release(struct rt_graph_info *rtinfo, 68int 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 */
92int rt_graph_check_task_completion(struct rt_graph_info *rtinfo, 115int 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 */
129int rt_graph_check_task_block(struct rt_graph_info *rtinfo, 158int 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 */
162int rt_graph_check_task_resume(struct rt_graph_info *rtinfo, 197int 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 */
194void init_rt_event_cache(struct rt_graph_info *rtinfo) 235void 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}
diff --git a/rt-graph.h b/rt-graph.h
index 0ea921a..3037301 100644
--- a/rt-graph.h
+++ b/rt-graph.h
@@ -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
7struct rt_graph_info { 8struct 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 */
30int rt_graph_check_task_param(struct rt_graph_info *rtinfo, struct pevent *pevent, 43int 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);
34int rt_graph_check_task_release(struct rt_graph_info *rtinfo, struct pevent *pevent, 47int 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);
37int rt_graph_check_task_completion(struct rt_graph_info *rtinfo, struct pevent *pevent, 51int 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);
39int rt_graph_check_task_block(struct rt_graph_info *rtinfo, struct pevent *pevent, 54int 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);
41int rt_graph_check_task_resume(struct rt_graph_info *rtinfo, struct pevent *pevent, 57int 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);
43void init_rt_event_cache(struct rt_graph_info *rtinfo); 60void init_rt_event_cache(struct rt_graph_info *rtinfo);
44 61
62/* Metadata */
63void rt_plot_task_plotted(struct rt_graph_info *rt_info, gint **plotted);
64
65/* Callbacks for managing task list */
66void rt_plot_task_update_callback(gboolean accept, gint *selected,
67 gint *non_select, gpointer data);
68void 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;
70static void redraw_pixmap_backend(struct graph_info *ginfo); 70static void redraw_pixmap_backend(struct graph_info *ginfo);
71static void update_label_window(struct graph_info *ginfo); 71static void update_label_window(struct graph_info *ginfo);
72 72
73struct task_list {
74 struct task_list *next;
75 gint pid;
76};
77
78static guint get_task_hash_key(gint pid)
79{
80 return trace_hash(pid) % TASK_HASH_SIZE;
81}
82
83static 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
96static 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
114static 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 */
135gint *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
158static void convert_nano(unsigned long long time, unsigned long *sec, 73static 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
215struct filter_task_item * 132struct 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
30struct graph_info; 31struct 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
150struct task_list;
151 150
152struct graph_info { 151struct 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
308void trace_graph_copy_filter(struct graph_info *ginfo, 307void 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);
311gint *trace_graph_task_list(struct graph_info *ginfo);
312 310
313int trace_graph_load_filters(struct graph_info *ginfo, 311int 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,
400void graph_plot_task_plotted(struct graph_info *ginfo, 398void 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