diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2012-03-24 17:45:12 -0400 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2012-03-24 17:45:12 -0400 |
commit | b53dd6d749e0a164010f2cf1fedab2b10b8bb305 (patch) | |
tree | c241366acea35e0ab58509ef7b441c5299a1c0b8 | |
parent | cc295d3e4924efd31c268a57f01b1412c6513301 (diff) |
containers: abstracted out common task-type code
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | kernel-shark.c | 28 | ||||
-rw-r--r-- | rt-graph.c | 141 | ||||
-rw-r--r-- | rt-graph.h | 27 | ||||
-rw-r--r-- | rt-plot-cpu.c | 30 | ||||
-rw-r--r-- | rt-plot-cpu.h | 2 | ||||
-rw-r--r-- | rt-plot-task.c | 338 | ||||
-rw-r--r-- | rt-plot-task.h | 4 | ||||
-rw-r--r-- | trace-graph.h | 2 | ||||
-rw-r--r-- | trace-plot-task.c | 2 |
10 files changed, 180 insertions, 397 deletions
@@ -299,7 +299,8 @@ 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 | RT_GRAPH_OBJS = rt-graph.o rt-plot-task.o rt-plot-cpu.o | 302 | RT_GRAPH_OBJS = rt-graph.o rt-plot-task.o rt-plot-cpu.o rt-plot-container.o rt-plot.o \ |
303 | rt-plot-vcpu.o | ||
303 | TRACE_GRAPH_OBJS = trace-graph.o trace-plot.o \ | 304 | TRACE_GRAPH_OBJS = trace-graph.o trace-plot.o \ |
304 | trace-plot-cpu.o trace-plot-task.o \ | 305 | trace-plot-cpu.o trace-plot-task.o \ |
305 | $(RT_GRAPH_OBJS) task-list.o | 306 | $(RT_GRAPH_OBJS) task-list.o |
diff --git a/kernel-shark.c b/kernel-shark.c index 6e41406..6b6cdd4 100644 --- a/kernel-shark.c +++ b/kernel-shark.c | |||
@@ -1308,6 +1308,18 @@ plot_rt_tasks_clicked (gpointer data) | |||
1308 | free(selected); | 1308 | free(selected); |
1309 | } | 1309 | } |
1310 | 1310 | ||
1311 | /* Callback for the clicked signal of the plot real-time tasks button */ | ||
1312 | static void | ||
1313 | plot_containers_clicked (gpointer data) | ||
1314 | { | ||
1315 | struct shark_info *info = data; | ||
1316 | struct graph_info *ginfo = info->ginfo; | ||
1317 | if (!ginfo->handle) | ||
1318 | return; | ||
1319 | |||
1320 | trace_container_dialog(ginfo, NULL); | ||
1321 | } | ||
1322 | |||
1311 | static void | 1323 | static void |
1312 | show_all_rt_clicked (gpointer data) | 1324 | show_all_rt_clicked (gpointer data) |
1313 | { | 1325 | { |
@@ -2259,6 +2271,22 @@ void kernel_shark(int argc, char **argv) | |||
2259 | 2271 | ||
2260 | /* --- Plot - RT CPUs Option --- */ | 2272 | /* --- Plot - RT CPUs Option --- */ |
2261 | 2273 | ||
2274 | sub_item = gtk_menu_item_new_with_label("Containers"); | ||
2275 | |||
2276 | /* Add them to the menu */ | ||
2277 | gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item); | ||
2278 | |||
2279 | /* We can attach the Quit menu item to our exit function */ | ||
2280 | g_signal_connect_swapped (G_OBJECT (sub_item), "activate", | ||
2281 | G_CALLBACK (plot_containers_clicked), | ||
2282 | (gpointer) info); | ||
2283 | |||
2284 | /* We do need to show menu items */ | ||
2285 | gtk_widget_show(sub_item); | ||
2286 | |||
2287 | |||
2288 | /* --- Plot - RT CPUs Option --- */ | ||
2289 | |||
2262 | sub_item = gtk_menu_item_new_with_label("Real-Time CPUs"); | 2290 | sub_item = gtk_menu_item_new_with_label("Real-Time CPUs"); |
2263 | 2291 | ||
2264 | /* Add them to the menu */ | 2292 | /* Add them to the menu */ |
@@ -1,5 +1,5 @@ | |||
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | #include <string.h. | 2 | #include <string.h> |
3 | #include "trace-graph.h" | 3 | #include "trace-graph.h" |
4 | #include "trace-hash.h" | 4 | #include "trace-hash.h" |
5 | 5 | ||
@@ -14,16 +14,11 @@ | |||
14 | #define dprintf(l, x...) do { if (0) printf(x); } while (0) | 14 | #define dprintf(l, x...) do { if (0) printf(x); } while (0) |
15 | #endif | 15 | #endif |
16 | 16 | ||
17 | static guint get_event_hash_key(gint eid) | 17 | static inline guint get_event_hash_key(gint eid) |
18 | { | 18 | { |
19 | return trace_hash(eid) % TS_HASH_SIZE; | 19 | return trace_hash(eid) % TS_HASH_SIZE; |
20 | } | 20 | } |
21 | 21 | ||
22 | static int get_container_key(gint cid) | ||
23 | { | ||
24 | return trace_hash(cid) % CONT_HASH_SIZE; | ||
25 | } | ||
26 | |||
27 | /* | 22 | /* |
28 | * Returns string value stored in @field. | 23 | * Returns string value stored in @field. |
29 | */ | 24 | */ |
@@ -100,10 +95,10 @@ add_ts_hash(struct ts_list **events, gint eid, gint key, | |||
100 | return field; | 95 | return field; |
101 | } | 96 | } |
102 | 97 | ||
103 | /* | 98 | /** |
104 | * Return container for @cid and @key, if present. | 99 | * Return container for @cid and @key, if present. |
105 | */ | 100 | */ |
106 | static struct cont_list* | 101 | struct cont_list* |
107 | find_container(struct cont_list **conts, gint cid, gint key) | 102 | find_container(struct cont_list **conts, gint cid, gint key) |
108 | { | 103 | { |
109 | struct cont_list *list; | 104 | struct cont_list *list; |
@@ -126,11 +121,13 @@ add_container(struct cont_list **conts, gint cid, char *name) | |||
126 | key = get_container_key(cid); | 121 | key = get_container_key(cid); |
127 | 122 | ||
128 | list = find_container(conts, cid, key); | 123 | list = find_container(conts, cid, key); |
124 | |||
129 | if (!list) { | 125 | if (!list) { |
130 | list = malloc_or_die(sizeof(*list)); | 126 | list = malloc_or_die(sizeof(*list)); |
131 | list->cid = cid; | 127 | list->cid = cid; |
132 | list->name = name; | 128 | list->name = name; |
133 | list->vcpus = NULL; | 129 | list->vcpus = NULL; |
130 | list->plotted = FALSE; | ||
134 | 131 | ||
135 | list->next = conts[key]; | 132 | list->next = conts[key]; |
136 | conts[key] = list; | 133 | conts[key] = list; |
@@ -150,7 +147,7 @@ add_vcpu(struct cont_list **conts, | |||
150 | { | 147 | { |
151 | int key; | 148 | int key; |
152 | struct cont_list *clist; | 149 | struct cont_list *clist; |
153 | struct vcpu_list *vlist; | 150 | struct vcpu_list *vlist, *prev, *next; |
154 | 151 | ||
155 | key = get_container_key(cid); | 152 | key = get_container_key(cid); |
156 | clist = find_container(conts, cid, key); | 153 | clist = find_container(conts, cid, key); |
@@ -168,8 +165,24 @@ add_vcpu(struct cont_list **conts, | |||
168 | vlist->params.wcet = wcet; | 165 | vlist->params.wcet = wcet; |
169 | vlist->params.period = period; | 166 | vlist->params.period = period; |
170 | 167 | ||
171 | vlist->next = clist->vcpus; | 168 | /* Insert in order */ |
172 | clist->vcpus = vlist; | 169 | if (!clist->vcpus) { |
170 | vlist->next = clist->vcpus; | ||
171 | clist->vcpus = vlist; | ||
172 | } else { | ||
173 | prev = clist->vcpus; | ||
174 | for (next = prev->next; next; prev = next, next = prev->next) { | ||
175 | if (sid < next->sid) { | ||
176 | vlist->next = next; | ||
177 | prev->next = vlist; | ||
178 | break; | ||
179 | } | ||
180 | } | ||
181 | if (!next) { | ||
182 | vlist->next = NULL; | ||
183 | prev->next = vlist; | ||
184 | } | ||
185 | } | ||
173 | 186 | ||
174 | return vlist; | 187 | return vlist; |
175 | } | 188 | } |
@@ -520,7 +533,7 @@ int rt_graph_check_container_param(struct graph_info *ginfo, | |||
520 | "litmus_container_param"); | 533 | "litmus_container_param"); |
521 | if (!event) | 534 | if (!event) |
522 | goto out; | 535 | goto out; |
523 | rtg_info->task_param_id = event->id; | 536 | rtg_info->container_param_id = event->id; |
524 | dprintf(2, "Found container_param id %d\n", event->id); | 537 | dprintf(2, "Found container_param id %d\n", event->id); |
525 | STORE_FIELD(rtg_info, event, cparam, cid); | 538 | STORE_FIELD(rtg_info, event, cparam, cid); |
526 | STORE_FIELD(rtg_info, event, cparam, name); | 539 | STORE_FIELD(rtg_info, event, cparam, name); |
@@ -562,7 +575,7 @@ int rt_graph_check_server_param(struct graph_info *ginfo, struct record *record, | |||
562 | "litmus_server_param"); | 575 | "litmus_server_param"); |
563 | if (!event) | 576 | if (!event) |
564 | goto out; | 577 | goto out; |
565 | rtg_info->task_param_id = event->id; | 578 | rtg_info->server_param_id = event->id; |
566 | dprintf(2, "Found server_param id %d\n", event->id); | 579 | dprintf(2, "Found server_param id %d\n", event->id); |
567 | STORE_FIELD(rtg_info, event, sparam, cid); | 580 | STORE_FIELD(rtg_info, event, sparam, cid); |
568 | STORE_FIELD(rtg_info, event, sparam, sid); | 581 | STORE_FIELD(rtg_info, event, sparam, sid); |
@@ -726,7 +739,8 @@ int rt_graph_check_server_release(struct graph_info *ginfo, | |||
726 | */ | 739 | */ |
727 | int rt_graph_check_server_completion(struct graph_info *ginfo, | 740 | int rt_graph_check_server_completion(struct graph_info *ginfo, |
728 | struct record *record, | 741 | struct record *record, |
729 | gint *sid, gint *job) | 742 | gint *sid, gint *job, |
743 | unsigned long long *ts) | ||
730 | { | 744 | { |
731 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | 745 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; |
732 | struct pevent *pevent = ginfo->pevent; | 746 | struct pevent *pevent = ginfo->pevent; |
@@ -749,6 +763,7 @@ int rt_graph_check_server_completion(struct graph_info *ginfo, | |||
749 | if (id == rtg_info->server_completion_id) { | 763 | if (id == rtg_info->server_completion_id) { |
750 | LOAD_INT(rtg_info, record, scompletion, sid, sid); | 764 | LOAD_INT(rtg_info, record, scompletion, sid, sid); |
751 | LOAD_INT(rtg_info, record, scompletion, job, job); | 765 | LOAD_INT(rtg_info, record, scompletion, job, job); |
766 | *ts = get_rts(ginfo, record); | ||
752 | 767 | ||
753 | dprintf(3, "Read server_completion(job(%d, %d))\n", *sid, *job); | 768 | dprintf(3, "Read server_completion(job(%d, %d))\n", *sid, *job); |
754 | ret = 1; | 769 | ret = 1; |
@@ -874,99 +889,3 @@ get_rts(struct graph_info *ginfo, struct record *record) | |||
874 | ts = record->cached_rts; | 889 | ts = record->cached_rts; |
875 | return ts; | 890 | return ts; |
876 | } | 891 | } |
877 | |||
878 | /** | ||
879 | * next_rts - find a real-time timestamp AROUND an FTRACE time | ||
880 | * @ginfo: Current state of the graph | ||
881 | * @cpu: CPU to search | ||
882 | * @ft_target: FTRACE time to seek towards | ||
883 | * | ||
884 | * Returns the RT time of a record CLOSELY BEFORE @ft_time. | ||
885 | */ | ||
886 | unsigned long long | ||
887 | next_rts(struct graph_info *ginfo, int cpu, unsigned long long ft_target) | ||
888 | { | ||
889 | struct record *record; | ||
890 | unsigned long long ts = 0ULL; | ||
891 | tracecmd_set_cpu_to_timestamp(ginfo->handle, cpu, ft_target); | ||
892 | record = tracecmd_read_data(ginfo->handle, cpu); | ||
893 | if (record) { | ||
894 | ts = get_rts(ginfo, record); | ||
895 | free_record(record); | ||
896 | return ts; | ||
897 | } else | ||
898 | return 0; | ||
899 | } | ||
900 | |||
901 | /** | ||
902 | * set_cpu_to_rts - seek CPU to a time closely preceding a real-time timestamp | ||
903 | * @ginfo: Current state o the graph | ||
904 | * @cpu: The CPU to seek | ||
905 | * @rt_target: RT time to seek towards | ||
906 | * | ||
907 | * This seeks to a real-time timestamp, not the default ftrace timestamps. | ||
908 | * The @cpu seek location will be placed before the given time, but will | ||
909 | * not necessarily be placed _right_ before the time. | ||
910 | */ | ||
911 | void | ||
912 | set_cpu_to_rts(struct graph_info *ginfo, unsigned long long rt_target, int cpu) | ||
913 | { | ||
914 | struct record *record; | ||
915 | unsigned long long last_rts, rts, seek_time, last_seek; | ||
916 | long long diff; | ||
917 | |||
918 | rts = next_rts(ginfo, cpu, rt_target); | ||
919 | diff = rt_target - rts; | ||
920 | |||
921 | /* "Guess" a new target based on difference */ | ||
922 | seek_time = rt_target + diff; | ||
923 | rts = next_rts(ginfo, cpu, seek_time); | ||
924 | diff = rt_target - rts; | ||
925 | |||
926 | /* Zero in in 1.5x the difference increments */ | ||
927 | if (rts && diff > 0) { | ||
928 | /* rts rt_target | real-time time | ||
929 | * seek ? | trace-cmd time | ||
930 | * ---|---->>----|-------- | ||
931 | */ | ||
932 | do { | ||
933 | last_seek = seek_time; | ||
934 | last_rts = rts; | ||
935 | seek_time = seek_time + 1.5 * (rt_target - rts); | ||
936 | rts = next_rts(ginfo, cpu, seek_time); | ||
937 | } while (rts < rt_target && last_rts != rts); | ||
938 | tracecmd_set_cpu_to_timestamp(ginfo->handle, cpu, last_seek); | ||
939 | seek_time = last_seek; | ||
940 | } else if (rts && diff < 0) { | ||
941 | /* rt_target rts | real-time time | ||
942 | * ? seek | trace-cmd time | ||
943 | * ---|----<<----|-------- | ||
944 | */ | ||
945 | do { | ||
946 | seek_time = seek_time - 1.5 * (rts - rt_target); | ||
947 | rts = next_rts(ginfo, cpu, seek_time); | ||
948 | } while (rts > rt_target); | ||
949 | } | ||
950 | |||
951 | /* Get to first record at or after time */ | ||
952 | while ((record = tracecmd_read_data(ginfo->handle, cpu))) { | ||
953 | if (get_rts(ginfo, record) >= rt_target) | ||
954 | break; | ||
955 | free_record(record); | ||
956 | } | ||
957 | if (record) { | ||
958 | tracecmd_set_cursor(ginfo->handle, cpu, record->offset); | ||
959 | free_record(record); | ||
960 | } else | ||
961 | tracecmd_set_cpu_to_timestamp(ginfo->handle, cpu, seek_time); | ||
962 | } | ||
963 | |||
964 | /** | ||
965 | * set_cpus_to_time - seek all cpus to real-time @rt_target | ||
966 | */ | ||
967 | void set_cpus_to_rts(struct graph_info *ginfo, unsigned long long rt_target) | ||
968 | { | ||
969 | int cpu; | ||
970 | for (cpu = 0; cpu < ginfo->cpus; cpu++) | ||
971 | set_cpu_to_rts(ginfo, rt_target, cpu); | ||
972 | } | ||
@@ -4,8 +4,10 @@ | |||
4 | #include <gtk/gtk.h> | 4 | #include <gtk/gtk.h> |
5 | #include "task-list.h" | 5 | #include "task-list.h" |
6 | #include "trace-cmd.h" | 6 | #include "trace-cmd.h" |
7 | #include "rt-plot.h" | ||
7 | #include "rt-plot-task.h" | 8 | #include "rt-plot-task.h" |
8 | #include "rt-plot-cpu.h" | 9 | #include "rt-plot-cpu.h" |
10 | #include "rt-plot-container.h" | ||
9 | 11 | ||
10 | #define LLABEL 30 | 12 | #define LLABEL 30 |
11 | #define SEARCH_PERIODS 3 | 13 | #define SEARCH_PERIODS 3 |
@@ -102,6 +104,7 @@ struct rt_graph_info { | |||
102 | unsigned long long max_period; | 104 | unsigned long long max_period; |
103 | }; | 105 | }; |
104 | 106 | ||
107 | |||
105 | /* | 108 | /* |
106 | * A list of cached time-stamp fields | 109 | * A list of cached time-stamp fields |
107 | */ | 110 | */ |
@@ -134,6 +137,7 @@ struct vcpu_list { | |||
134 | struct cont_list { | 137 | struct cont_list { |
135 | struct cont_list *next; | 138 | struct cont_list *next; |
136 | gint cid; | 139 | gint cid; |
140 | gboolean plotted; | ||
137 | const char* name; | 141 | const char* name; |
138 | struct vcpu_list *vcpus; | 142 | struct vcpu_list *vcpus; |
139 | }; | 143 | }; |
@@ -173,7 +177,7 @@ int rt_graph_check_server_param(struct graph_info *ginfo, struct record *record, | |||
173 | int rt_graph_check_server_switch_to(struct graph_info *ginfo, | 177 | int rt_graph_check_server_switch_to(struct graph_info *ginfo, |
174 | struct record *record, | 178 | struct record *record, |
175 | gint *sid, gint *job, gint *tid, | 179 | gint *sid, gint *job, gint *tid, |
176 | unsigned long long *when); | 180 | unsigned long long *when); |
177 | int rt_graph_check_server_switch_away(struct graph_info *ginfo, | 181 | int rt_graph_check_server_switch_away(struct graph_info *ginfo, |
178 | struct record *record, | 182 | struct record *record, |
179 | gint *sid, gint *job, gint *tid, | 183 | gint *sid, gint *job, gint *tid, |
@@ -185,7 +189,8 @@ int rt_graph_check_server_release(struct graph_info *ginfo, | |||
185 | unsigned long long *deadline); | 189 | unsigned long long *deadline); |
186 | int rt_graph_check_server_completion(struct graph_info *ginfo, | 190 | int rt_graph_check_server_completion(struct graph_info *ginfo, |
187 | struct record *record, | 191 | struct record *record, |
188 | gint *sid, gint *job); | 192 | gint *sid, gint *job, |
193 | unsigned long long *when); | ||
189 | int rt_graph_check_server_block(struct graph_info *ginfo, | 194 | int rt_graph_check_server_block(struct graph_info *ginfo, |
190 | struct record *record, gint *pid, | 195 | struct record *record, gint *pid, |
191 | unsigned long long *when); | 196 | unsigned long long *when); |
@@ -193,15 +198,12 @@ int rt_graph_check_server_resume(struct graph_info *ginfo, struct record *record | |||
193 | gint *pid, unsigned long long *when); | 198 | gint *pid, unsigned long long *when); |
194 | void init_rt_event_cache(struct rt_graph_info *rtinfo); | 199 | void init_rt_event_cache(struct rt_graph_info *rtinfo); |
195 | 200 | ||
196 | /* Methods for dealing with RT timestamps */ | ||
197 | unsigned long long get_rts(struct graph_info *ginfo, | 201 | unsigned long long get_rts(struct graph_info *ginfo, |
198 | struct record *record); | 202 | struct record *record); |
199 | unsigned long long next_rts(struct graph_info *ginfo, int cpu, | 203 | |
200 | unsigned long long ft_target); | 204 | |
201 | void set_cpu_to_rts(struct graph_info *ginfo, | 205 | /* Other */ |
202 | unsigned long long rt_target, int cpu); | 206 | struct cont_list* find_container(struct cont_list **conts, gint cid, gint key); |
203 | void set_cpus_to_rts(struct graph_info *ginfo, | ||
204 | unsigned long long rt_target); | ||
205 | 207 | ||
206 | static inline void nano_to_milli(unsigned long long time, | 208 | static inline void nano_to_milli(unsigned long long time, |
207 | unsigned long long *msec, | 209 | unsigned long long *msec, |
@@ -216,4 +218,11 @@ static inline float nano_as_milli(unsigned long long time) | |||
216 | return (float)time / 1000000ULL; | 218 | return (float)time / 1000000ULL; |
217 | } | 219 | } |
218 | 220 | ||
221 | static inline int get_container_key(gint cid) | ||
222 | { | ||
223 | return trace_hash(cid) % CONT_HASH_SIZE; | ||
224 | } | ||
225 | |||
226 | #define max_rt_search(ginfo) (SEARCH_PERIODS*ginfo->rtg_info.max_period) | ||
227 | |||
219 | #endif | 228 | #endif |
diff --git a/rt-plot-cpu.c b/rt-plot-cpu.c index e32f085..28ae26b 100644 --- a/rt-plot-cpu.c +++ b/rt-plot-cpu.c | |||
@@ -55,13 +55,13 @@ static inline int | |||
55 | is_displayed(struct graph_info *ginfo, int eid) | 55 | is_displayed(struct graph_info *ginfo, int eid) |
56 | { | 56 | { |
57 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | 57 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; |
58 | return !(eid == rtg_info->switch_away_id || | 58 | return (eid == rtg_info->switch_away_id || |
59 | eid == rtg_info->switch_to_id || | 59 | eid == rtg_info->switch_to_id || |
60 | eid == rtg_info->task_completion_id || | 60 | eid == rtg_info->task_completion_id || |
61 | eid == rtg_info->task_block_id || | 61 | eid == rtg_info->task_block_id || |
62 | eid == rtg_info->task_resume_id || | 62 | eid == rtg_info->task_resume_id || |
63 | eid == rtg_info->task_release_id || | 63 | eid == rtg_info->task_release_id || |
64 | eid == ginfo->event_sched_switch_id); | 64 | eid == ginfo->event_sched_switch_id); |
65 | } | 65 | } |
66 | 66 | ||
67 | static struct record* | 67 | static struct record* |
@@ -78,7 +78,7 @@ __find_record(struct graph_info *ginfo, int cpu, unsigned long long time, | |||
78 | eid = pevent_data_type(ginfo->pevent, record); | 78 | eid = pevent_data_type(ginfo->pevent, record); |
79 | 79 | ||
80 | if (display) | 80 | if (display) |
81 | ignored = !is_displayed(ginfo, eid); | 81 | ignored = is_displayed(ginfo, eid); |
82 | 82 | ||
83 | if (get_rts(ginfo, record) >= time && !ignored) | 83 | if (get_rts(ginfo, record) >= time && !ignored) |
84 | break; | 84 | break; |
@@ -140,6 +140,7 @@ static int get_time_info(struct graph_info *ginfo, | |||
140 | cpu = rtc_info->cpu; | 140 | cpu = rtc_info->cpu; |
141 | *out_pid = *out_job = is_running = 0; | 141 | *out_pid = *out_job = is_running = 0; |
142 | 142 | ||
143 | /* TODO: inneficient */ | ||
143 | *out_record = find_display_record(ginfo, cpu, time); | 144 | *out_record = find_display_record(ginfo, cpu, time); |
144 | record = find_record(ginfo, cpu, time); | 145 | record = find_record(ginfo, cpu, time); |
145 | if (!record) | 146 | if (!record) |
@@ -330,8 +331,9 @@ static void rt_cpu_plot_start(struct graph_info *ginfo, struct graph_plot *plot, | |||
330 | static int rt_cpu_plot_event(struct graph_info *ginfo, struct graph_plot *plot, | 331 | static int rt_cpu_plot_event(struct graph_info *ginfo, struct graph_plot *plot, |
331 | struct record *record, struct plot_info *info) | 332 | struct record *record, struct plot_info *info) |
332 | { | 333 | { |
333 | int pid, eid, match, dint; | 334 | int pid = 0, eid, match, dint; |
334 | unsigned long long ts, dull; | 335 | unsigned long long ts, dull; |
336 | char *dchar; | ||
335 | struct rt_cpu_info *rtc_info = plot->private; | 337 | struct rt_cpu_info *rtc_info = plot->private; |
336 | 338 | ||
337 | if (!record) { | 339 | if (!record) { |
@@ -348,18 +350,21 @@ static int rt_cpu_plot_event(struct graph_info *ginfo, struct graph_plot *plot, | |||
348 | try_sched_switch(ginfo, rtc_info, record, info); | 350 | try_sched_switch(ginfo, rtc_info, record, info); |
349 | 351 | ||
350 | if (!match) { | 352 | if (!match) { |
351 | /* Have to call checks to ensure ids are loaded. Otherwise, | 353 | /* TODO: this should not be necessary! |
354 | * Have to call checks to ensure ids are loaded. Otherwise, | ||
352 | * is_displayed will not work here or in any other methods. | 355 | * is_displayed will not work here or in any other methods. |
353 | */ | 356 | */ |
354 | #define ARG ginfo,record, &pid | 357 | #define ARG ginfo,record, &pid |
355 | rt_graph_check_task_param(ARG, &dull, &dull); | 358 | rt_graph_check_task_param(ARG, &dull, &dull); |
359 | rt_graph_check_container_param(ARG, &dchar); | ||
360 | rt_graph_check_server_param(ARG, &dint, &dull, &dull); | ||
356 | rt_graph_check_task_release(ARG, &dint, &dull, &dull); | 361 | rt_graph_check_task_release(ARG, &dint, &dull, &dull); |
357 | rt_graph_check_task_block(ARG, &dull); | 362 | rt_graph_check_task_block(ARG, &dull); |
358 | rt_graph_check_task_resume(ARG, &dull); | 363 | rt_graph_check_task_resume(ARG, &dull); |
359 | rt_graph_check_any(ARG, &eid, &ts); | 364 | rt_graph_check_any(ARG, &eid, &ts); |
360 | #undef ARG | 365 | #undef ARG |
361 | 366 | ||
362 | if (is_displayed(ginfo, eid)) { | 367 | if (!is_displayed(ginfo, eid)) { |
363 | info->line = TRUE; | 368 | info->line = TRUE; |
364 | info->lcolor = hash_pid(pid); | 369 | info->lcolor = hash_pid(pid); |
365 | info->ltime = ts; | 370 | info->ltime = ts; |
@@ -462,8 +467,7 @@ static void rt_cpu_plot_destroy(struct graph_info *ginfo, struct graph_plot *plo | |||
462 | free(rtc_info); | 467 | free(rtc_info); |
463 | } | 468 | } |
464 | 469 | ||
465 | 470 | const struct plot_callbacks rt_cpu_cb = { | |
466 | static const struct plot_callbacks rt_cpu_cb = { | ||
467 | .start = rt_cpu_plot_start, | 471 | .start = rt_cpu_plot_start, |
468 | .destroy = rt_cpu_plot_destroy, | 472 | .destroy = rt_cpu_plot_destroy, |
469 | .plot_event = rt_cpu_plot_event, | 473 | .plot_event = rt_cpu_plot_event, |
diff --git a/rt-plot-cpu.h b/rt-plot-cpu.h index 2742c76..d7e1e57 100644 --- a/rt-plot-cpu.h +++ b/rt-plot-cpu.h | |||
@@ -10,6 +10,8 @@ struct rt_cpu_info { | |||
10 | char *label; | 10 | char *label; |
11 | }; | 11 | }; |
12 | 12 | ||
13 | const struct plot_callbacks rt_cpu_cb; | ||
14 | |||
13 | void rt_plot_labeled_cpu(struct graph_info *ginfo, int cpu, char *label); | 15 | void rt_plot_labeled_cpu(struct graph_info *ginfo, int cpu, char *label); |
14 | void rt_plot_cpu(struct graph_info *ginfo, int cpu); | 16 | void rt_plot_cpu(struct graph_info *ginfo, int cpu); |
15 | void rt_plot_cpus_plotted(struct graph_info *ginfo, | 17 | void rt_plot_cpus_plotted(struct graph_info *ginfo, |
diff --git a/rt-plot-task.c b/rt-plot-task.c index 524b1f9..3175f23 100644 --- a/rt-plot-task.c +++ b/rt-plot-task.c | |||
@@ -3,7 +3,7 @@ | |||
3 | #include "trace-graph.h" | 3 | #include "trace-graph.h" |
4 | #include "trace-filter.h" | 4 | #include "trace-filter.h" |
5 | 5 | ||
6 | #define DEBUG_LEVEL 0 | 6 | #define DEBUG_LEVEL 4 |
7 | #if DEBUG_LEVEL > 0 | 7 | #if DEBUG_LEVEL > 0 |
8 | #define dprintf(l, x...) \ | 8 | #define dprintf(l, x...) \ |
9 | do { \ | 9 | do { \ |
@@ -15,31 +15,6 @@ | |||
15 | #endif | 15 | #endif |
16 | 16 | ||
17 | /* | 17 | /* |
18 | * Return 1 if @record is relevant to @match_pid. | ||
19 | */ | ||
20 | static gboolean record_matches_pid(struct graph_info *ginfo, | ||
21 | struct record *record, | ||
22 | int match_pid) | ||
23 | { | ||
24 | gint dint, pid = 0, match; | ||
25 | unsigned long long dull; | ||
26 | |||
27 | /* Must use check_* in case record has not been found yet, | ||
28 | * this macro was the best of many terrible options. | ||
29 | */ | ||
30 | #define ARG ginfo, record, &pid | ||
31 | match = rt_graph_check_switch_to(ARG, &dint, &dull) || | ||
32 | rt_graph_check_switch_away(ARG, &dint, &dull) || | ||
33 | rt_graph_check_task_release(ARG, &dint, &dull, &dull) || | ||
34 | rt_graph_check_task_completion(ARG, &dint, &dull) || | ||
35 | rt_graph_check_task_block(ARG, &dull) || | ||
36 | rt_graph_check_task_resume(ARG, &dull) || | ||
37 | rt_graph_check_any(ARG, &dint, &dull); | ||
38 | #undef ARG | ||
39 | return pid == match_pid; | ||
40 | } | ||
41 | |||
42 | /* | ||
43 | * Return the first record after @time (within a range) which draws a box. | 18 | * Return the first record after @time (within a range) which draws a box. |
44 | */ | 19 | */ |
45 | static struct record* | 20 | static struct record* |
@@ -83,51 +58,6 @@ next_box_record(struct graph_info *ginfo, struct rt_task_info *rtt_info, | |||
83 | } | 58 | } |
84 | 59 | ||
85 | /* | 60 | /* |
86 | * Return first relevant record after @time. | ||
87 | * @display: If set, only considers records which aren't plotted | ||
88 | */ | ||
89 | static struct record* | ||
90 | __find_record(struct graph_info *ginfo, gint pid, guint64 time, int display) | ||
91 | { | ||
92 | int next_cpu, match, eid, ignored; | ||
93 | struct record *record; | ||
94 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
95 | |||
96 | set_cpus_to_rts(ginfo, time); | ||
97 | while ((record = tracecmd_read_next_data(ginfo->handle, &next_cpu))) { | ||
98 | ignored = 0; | ||
99 | match = record_matches_pid(ginfo, record, pid); | ||
100 | if (display) { | ||
101 | eid = pevent_data_type(ginfo->pevent, record); | ||
102 | ignored = (eid == rtg_info->switch_away_id || | ||
103 | eid == rtg_info->switch_to_id || | ||
104 | eid == rtg_info->task_completion_id || | ||
105 | eid == rtg_info->task_block_id || | ||
106 | eid == rtg_info->task_resume_id || | ||
107 | eid == rtg_info->task_release_id); | ||
108 | } | ||
109 | ignored = ignored || eid == ginfo->event_sched_switch_id; | ||
110 | if (get_rts(ginfo, record) >= time && match && !ignored) | ||
111 | break; | ||
112 | free_record(record); | ||
113 | }; | ||
114 | |||
115 | return record; | ||
116 | } | ||
117 | |||
118 | static inline struct record* | ||
119 | find_record(struct graph_info *ginfo, gint pid, guint64 time) | ||
120 | { | ||
121 | return __find_record(ginfo, pid, time, 0); | ||
122 | } | ||
123 | |||
124 | static inline struct record* | ||
125 | find_display_record(struct graph_info *ginfo, gint pid, guint64 time) | ||
126 | { | ||
127 | return __find_record(ginfo, pid, time, 1); | ||
128 | } | ||
129 | |||
130 | /* | ||
131 | * Update current job in @rtt_info, ensuring monotonic increase. | 61 | * Update current job in @rtt_info, ensuring monotonic increase. |
132 | */ | 62 | */ |
133 | static int update_job(struct rt_task_info *rtt_info, int job) | 63 | static int update_job(struct rt_task_info *rtt_info, int job) |
@@ -145,56 +75,6 @@ static int update_job(struct rt_task_info *rtt_info, int job) | |||
145 | return 1; | 75 | return 1; |
146 | } | 76 | } |
147 | 77 | ||
148 | |||
149 | |||
150 | /* | ||
151 | * Find the information for the last release of @rtt_info on @cpu before @time. | ||
152 | * @min_ts: the minimum time stamp to parse | ||
153 | * | ||
154 | * Returns release record and @out_job, @out_release, and @out_deadline if a | ||
155 | * release was found after @mints matching @time. | ||
156 | */ | ||
157 | static struct record* | ||
158 | get_previous_release(struct graph_info *ginfo, struct rt_task_info *rtt_info, | ||
159 | int cpu, | ||
160 | unsigned long long min_ts, unsigned long long time, | ||
161 | int *out_job, | ||
162 | unsigned long long *out_release, | ||
163 | unsigned long long *out_deadline) | ||
164 | { | ||
165 | int pid, job, match; | ||
166 | unsigned long long release, deadline; | ||
167 | struct record *last_record, *record, *ret = NULL; | ||
168 | |||
169 | last_record = tracecmd_peek_data(ginfo->handle, cpu); | ||
170 | *out_job = *out_release = *out_deadline = 0; | ||
171 | if (!last_record) | ||
172 | return NULL; | ||
173 | last_record->ref_count++; | ||
174 | |||
175 | while ((record = tracecmd_read_prev(ginfo->handle, last_record))) { | ||
176 | if (record->ts < min_ts) { | ||
177 | free_record(record); | ||
178 | goto out; | ||
179 | } | ||
180 | match = rt_graph_check_task_release(ginfo, record, &pid, &job, | ||
181 | &release, &deadline); | ||
182 | free_record(last_record); | ||
183 | last_record = record; | ||
184 | if (match && (pid == rtt_info->pid) && release <= time) { | ||
185 | ret = record; | ||
186 | last_record = NULL; | ||
187 | *out_job = job; | ||
188 | *out_release = release; | ||
189 | *out_deadline = deadline; | ||
190 | break; | ||
191 | } | ||
192 | }; | ||
193 | out: | ||
194 | free_record(last_record); | ||
195 | return ret; | ||
196 | } | ||
197 | |||
198 | /* | 78 | /* |
199 | * Get information about the given @time. | 79 | * Get information about the given @time. |
200 | * @out_job: Job number at this time | 80 | * @out_job: Job number at this time |
@@ -215,15 +95,11 @@ static int get_time_info(struct graph_info *ginfo, | |||
215 | struct record **out_record) | 95 | struct record **out_record) |
216 | 96 | ||
217 | { | 97 | { |
218 | int cpu, job; | 98 | int job; |
219 | unsigned long long release, deadline, min_ts; | ||
220 | struct record *record; | ||
221 | struct offset_cache *offsets; | ||
222 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
223 | 99 | ||
224 | /* Seek CPUs to first record after this time */ | 100 | /* Seek CPUs to first record after this time */ |
225 | *out_job = *out_release = *out_deadline = 0; | 101 | *out_record = find_rt_record(ginfo, |
226 | *out_record = find_record(ginfo, rtt_info->pid, time); | 102 | (struct rt_plot_common*)rtt_info, time); |
227 | if (!*out_record) | 103 | if (!*out_record) |
228 | return 0; | 104 | return 0; |
229 | 105 | ||
@@ -236,22 +112,8 @@ static int get_time_info(struct graph_info *ginfo, | |||
236 | goto out; | 112 | goto out; |
237 | } | 113 | } |
238 | 114 | ||
239 | min_ts = time - SEARCH_PERIODS * rtg_info->max_period; | 115 | get_previous_release(ginfo, rtt_info->pid, time, |
240 | *out_job = *out_release = *out_deadline = 0; | 116 | out_job, out_release, out_deadline); |
241 | |||
242 | offsets = save_offsets(ginfo); | ||
243 | for (cpu = 0; cpu < ginfo->cpus; cpu++) { | ||
244 | record = get_previous_release(ginfo, rtt_info, cpu, min_ts, | ||
245 | time, &job, &release, &deadline); | ||
246 | if (record && record->ts > min_ts) { | ||
247 | *out_job = job; | ||
248 | *out_release = release; | ||
249 | *out_deadline = deadline; | ||
250 | min_ts = record->ts; | ||
251 | } | ||
252 | free_record(record); | ||
253 | } | ||
254 | restore_offsets(ginfo, offsets); | ||
255 | out: | 117 | out: |
256 | return 1; | 118 | return 1; |
257 | } | 119 | } |
@@ -537,9 +399,6 @@ static void rt_task_plot_start(struct graph_info *ginfo, struct graph_plot *plot | |||
537 | 399 | ||
538 | dprintf(4,"%s\n", __FUNCTION__); | 400 | dprintf(4,"%s\n", __FUNCTION__); |
539 | 401 | ||
540 | rtt_info->wcet = 0ULL; | ||
541 | rtt_info->period = 0ULL; | ||
542 | |||
543 | rtt_info->run_time = time; | 402 | rtt_info->run_time = time; |
544 | rtt_info->block_time = time; | 403 | rtt_info->block_time = time; |
545 | rtt_info->run_cpu = NO_CPU; | 404 | rtt_info->run_cpu = NO_CPU; |
@@ -548,7 +407,8 @@ static void rt_task_plot_start(struct graph_info *ginfo, struct graph_plot *plot | |||
548 | rtt_info->fresh = TRUE; | 407 | rtt_info->fresh = TRUE; |
549 | for (i = 0; i < 3; i++) | 408 | for (i = 0; i < 3; i++) |
550 | rtt_info->first_rels[i] = 0ULL; | 409 | rtt_info->first_rels[i] = 0ULL; |
551 | rtt_info->last_job = 0; | 410 | rtt_info->last_job = -1; |
411 | update_job(rtt_info, 0); | ||
552 | } | 412 | } |
553 | 413 | ||
554 | static void rt_task_plot_destroy(struct graph_info *ginfo, struct graph_plot *plot) | 414 | static void rt_task_plot_destroy(struct graph_info *ginfo, struct graph_plot *plot) |
@@ -560,143 +420,91 @@ static void rt_task_plot_destroy(struct graph_info *ginfo, struct graph_plot *pl | |||
560 | free(rtt_info); | 420 | free(rtt_info); |
561 | } | 421 | } |
562 | 422 | ||
563 | static int rt_task_plot_display_last_event(struct graph_info *ginfo, | 423 | static int |
564 | struct graph_plot *plot, | 424 | rt_task_plot_record_matches(struct rt_plot_common *rt, |
565 | struct trace_seq *s, | 425 | struct graph_info *ginfo, |
566 | unsigned long long time) | 426 | struct record *record) |
427 | |||
567 | { | 428 | { |
568 | int eid; | 429 | struct rt_task_info *rtt_info = (struct rt_task_info*)rt; |
569 | struct event_format *event; | 430 | gint dint, pid = 0, match, match_pid; |
570 | struct record *record; | 431 | unsigned long long dull; |
571 | struct offset_cache *offsets; | ||
572 | struct rt_task_info *rtt_info = plot->private; | ||
573 | 432 | ||
574 | dprintf(4,"%s\n", __FUNCTION__); | 433 | match_pid = rtt_info->pid; |
575 | 434 | ||
576 | offsets = save_offsets(ginfo); | 435 | /* Must use check_* in case record has not been found yet, |
577 | record = find_display_record(ginfo, rtt_info->pid, time); | 436 | * this macro was the best of many terrible options. |
578 | restore_offsets(ginfo, offsets); | 437 | */ |
579 | if (!record) | 438 | #define ARG ginfo, record, &pid |
580 | return 0; | 439 | match = rt_graph_check_switch_to(ARG, &dint, &dull) || |
440 | rt_graph_check_switch_away(ARG, &dint, &dull) || | ||
441 | rt_graph_check_task_release(ARG, &dint, &dull, &dull) || | ||
442 | rt_graph_check_task_completion(ARG, &dint, &dull) || | ||
443 | rt_graph_check_task_block(ARG, &dull) || | ||
444 | rt_graph_check_task_resume(ARG, &dull) || | ||
445 | rt_graph_check_any(ARG, &dint, &dull); | ||
446 | #undef ARG | ||
447 | return pid == match_pid; | ||
448 | } | ||
581 | 449 | ||
582 | eid = pevent_data_type(ginfo->pevent, record); | ||
583 | event = pevent_data_event_from_type(ginfo->pevent, eid); | ||
584 | if (event) | ||
585 | trace_seq_puts(s, event->name); | ||
586 | else | ||
587 | trace_seq_printf(s, "UNKNOWN EVENT %d\n", eid); | ||
588 | trace_seq_putc(s, '\n'); | ||
589 | trace_seq_printf(s, "CPU %d\n", record->cpu); | ||
590 | free_record(record); | ||
591 | 450 | ||
592 | return 1; | 451 | static int rt_task_plot_is_drawn(struct graph_info *ginfo, int eid) |
452 | { | ||
453 | struct rt_graph_info *rtg_info = &ginfo->rtg_info; | ||
454 | |||
455 | return (eid == rtg_info->switch_away_id || | ||
456 | eid == rtg_info->switch_to_id || | ||
457 | eid == rtg_info->task_completion_id || | ||
458 | eid == rtg_info->task_block_id || | ||
459 | eid == rtg_info->task_resume_id || | ||
460 | eid == rtg_info->task_release_id); | ||
593 | } | 461 | } |
594 | 462 | ||
595 | static int rt_task_plot_display_info(struct graph_info *ginfo, | 463 | static struct record* |
596 | struct graph_plot *plot, | 464 | rt_task_plot_write_header(struct rt_plot_common *rt, |
597 | struct trace_seq *s, | 465 | struct graph_info *ginfo, |
598 | unsigned long long time) | 466 | struct trace_seq *s, |
467 | unsigned long long time) | ||
599 | { | 468 | { |
600 | const char *comm; | 469 | const char *comm; |
601 | int pid, job, eid; | 470 | int pid, job, found; |
602 | struct record *record; | 471 | struct record *record; |
603 | struct event_format *event; | 472 | unsigned long long release, deadline; |
604 | unsigned long long msec, nsec; | 473 | struct rt_task_info *rtt_info = (struct rt_task_info*)rt; |
605 | unsigned long long release, deadline, rts; | ||
606 | struct rt_task_info *rtt_info = plot->private; | ||
607 | struct offset_cache *offsets; | ||
608 | 474 | ||
609 | dprintf(4,"%s\n", __FUNCTION__); | 475 | dprintf(4,"%s\n", __FUNCTION__); |
610 | 476 | ||
611 | offsets = save_offsets(ginfo); | 477 | found = get_time_info(ginfo, rtt_info, time, |
612 | get_time_info(ginfo, rtt_info, time, | 478 | &job, &release, &deadline, &record); |
613 | &job, &release, &deadline, &record); | 479 | if (!found) |
614 | restore_offsets(ginfo, offsets); | 480 | goto out; |
615 | 481 | ||
616 | pid = rtt_info->pid; | 482 | pid = rtt_info->pid; |
617 | comm = pevent_data_comm_from_pid(ginfo->pevent, pid); | 483 | comm = pevent_data_comm_from_pid(ginfo->pevent, pid); |
618 | trace_seq_printf(s, "%s-%d:%d\n", comm, pid, job); | 484 | trace_seq_printf(s, "%s-%d:%d\n", comm, pid, job); |
619 | 485 | ||
620 | if (record) { | 486 | if (in_res(ginfo, deadline, time)) { |
621 | rts = get_rts(ginfo, record); | 487 | trace_seq_printf(s, "\nlitmus_deadline\n" |
622 | eid = pevent_data_type(ginfo->pevent, record); | 488 | "deadline(job(%d,%d)): %llu\n", |
623 | 489 | pid, job, deadline); | |
624 | if (in_res(ginfo, deadline, time)) { | ||
625 | trace_seq_printf(s, "\nlitmus_deadline\n" | ||
626 | "deadline(job(%d,%d)): %llu\n", | ||
627 | pid, job, deadline); | ||
628 | } | ||
629 | if (in_res(ginfo, release, time)) { | ||
630 | trace_seq_printf(s, "\nlitmus_release\n" | ||
631 | "release(job(%d,%d)): %llu\n", | ||
632 | pid, job, release); | ||
633 | } | ||
634 | |||
635 | if (in_res(ginfo, rts, time)) { | ||
636 | event = pevent_data_event_from_type(ginfo->pevent, eid); | ||
637 | if (event) { | ||
638 | trace_seq_putc(s, '\n'); | ||
639 | trace_seq_puts(s, event->name); | ||
640 | trace_seq_putc(s, '\n'); | ||
641 | pevent_event_info(s, event, record); | ||
642 | } else | ||
643 | trace_seq_printf(s, "\nUNKNOWN EVENT %d\n", eid); | ||
644 | } | ||
645 | trace_seq_putc(s, '\n'); | ||
646 | nano_to_milli(time, &msec, &nsec); | ||
647 | trace_seq_printf(s, "%llu.%06llu ms CPU: %03d", | ||
648 | msec, nsec, record->cpu); | ||
649 | free_record(record); | ||
650 | } | 490 | } |
651 | 491 | if (in_res(ginfo, release, time)) { | |
652 | return 1; | 492 | trace_seq_printf(s, "\nlitmus_release\n" |
653 | } | 493 | "release(job(%d,%d)): %llu\n", |
654 | 494 | pid, job, release); | |
655 | static int rt_task_plot_match_time(struct graph_info *ginfo, | 495 | } |
656 | struct graph_plot *plot, | 496 | out: |
657 | unsigned long long time) | 497 | return record; |
658 | { | ||
659 | struct record *record = NULL; | ||
660 | struct rt_task_info *rtt_info = plot->private; | ||
661 | int next_cpu, match, ret; | ||
662 | |||
663 | dprintf(4,"%s\n", __FUNCTION__); | ||
664 | |||
665 | set_cpus_to_rts(ginfo, time); | ||
666 | |||
667 | do { | ||
668 | free_record(record); | ||
669 | record = tracecmd_read_next_data(ginfo->handle, &next_cpu); | ||
670 | if (!record) | ||
671 | return 0; | ||
672 | match = record_matches_pid(ginfo, record, rtt_info->pid); | ||
673 | } while ((!match && get_rts(ginfo, record) < time + 1) || | ||
674 | (match && get_rts(ginfo, record) < time)); | ||
675 | |||
676 | if (record && get_rts(ginfo, record) == time) | ||
677 | ret = 1; | ||
678 | free_record(record); | ||
679 | |||
680 | return ret; | ||
681 | } | ||
682 | |||
683 | static struct record * | ||
684 | rt_task_plot_find_record(struct graph_info *ginfo, struct graph_plot *plot, | ||
685 | unsigned long long time) | ||
686 | { | ||
687 | struct rt_task_info *rtt_info = plot->private; | ||
688 | return find_record(ginfo, rtt_info->pid, time); | ||
689 | } | 498 | } |
690 | 499 | ||
691 | 500 | const struct plot_callbacks rt_task_cb = { | |
692 | static const struct plot_callbacks rt_task_cb = { | ||
693 | .start = rt_task_plot_start, | 501 | .start = rt_task_plot_start, |
694 | .destroy = rt_task_plot_destroy, | 502 | .destroy = rt_task_plot_destroy, |
695 | .plot_event = rt_task_plot_event, | 503 | .plot_event = rt_task_plot_event, |
696 | .display_last_event = rt_task_plot_display_last_event, | 504 | .display_last_event = rt_plot_display_last_event, |
697 | .display_info = rt_task_plot_display_info, | 505 | .display_info = rt_plot_display_info, |
698 | .match_time = rt_task_plot_match_time, | 506 | .match_time = rt_plot_match_time, |
699 | .find_record = rt_task_plot_find_record, | 507 | .find_record = rt_plot_find_record, |
700 | }; | 508 | }; |
701 | 509 | ||
702 | void rt_plot_task_update_callback(gboolean accept, | 510 | void rt_plot_task_update_callback(gboolean accept, |
@@ -806,6 +614,12 @@ void rt_plot_task(struct graph_info *ginfo, int pid, int pos) | |||
806 | rtt_info = malloc_or_die(sizeof(*rtt_info)); | 614 | rtt_info = malloc_or_die(sizeof(*rtt_info)); |
807 | rtt_info->pid = pid; | 615 | rtt_info->pid = pid; |
808 | rtt_info->label = malloc_or_die(LLABEL); | 616 | rtt_info->label = malloc_or_die(LLABEL); |
617 | rtt_info->wcet = params->wcet; | ||
618 | rtt_info->period = params->period; | ||
619 | |||
620 | rtt_info->common.record_matches = rt_task_plot_record_matches; | ||
621 | rtt_info->common.is_drawn = rt_task_plot_is_drawn; | ||
622 | rtt_info->common.write_header = rt_task_plot_write_header; | ||
809 | 623 | ||
810 | ms_wcet = nano_as_milli(params->wcet); | 624 | ms_wcet = nano_as_milli(params->wcet); |
811 | ms_period = nano_as_milli(params->period); | 625 | ms_period = nano_as_milli(params->period); |
@@ -825,7 +639,7 @@ void rt_plot_task(struct graph_info *ginfo, int pid, int pos) | |||
825 | } | 639 | } |
826 | 640 | ||
827 | void rt_plot_add_all_tasks(struct graph_info *ginfo) | 641 | void rt_plot_add_all_tasks(struct graph_info *ginfo) |
828 | { | 642 | { |
829 | gint *tasks; | 643 | gint *tasks; |
830 | int i; | 644 | int i; |
831 | tasks = task_list_pids(ginfo->rtg_info.tasks); | 645 | tasks = task_list_pids(ginfo->rtg_info.tasks); |
diff --git a/rt-plot-task.h b/rt-plot-task.h index a61a2b7..ddbfb1c 100644 --- a/rt-plot-task.h +++ b/rt-plot-task.h | |||
@@ -4,6 +4,8 @@ | |||
4 | #include "trace-plot-task.h" | 4 | #include "trace-plot-task.h" |
5 | 5 | ||
6 | struct rt_task_info { | 6 | struct rt_task_info { |
7 | struct rt_plot_common common; | ||
8 | |||
7 | int pid; | 9 | int pid; |
8 | unsigned long long wcet; | 10 | unsigned long long wcet; |
9 | unsigned long long period; | 11 | unsigned long long period; |
@@ -25,6 +27,8 @@ struct rt_task_info { | |||
25 | char *label; | 27 | char *label; |
26 | }; | 28 | }; |
27 | 29 | ||
30 | const struct plot_callbacks rt_task_cb; | ||
31 | |||
28 | void rt_plot_task(struct graph_info *ginfo, int pid, int pos); | 32 | void rt_plot_task(struct graph_info *ginfo, int pid, int pos); |
29 | void rt_plot_tasks_plotted(struct graph_info *ginfo, gint **plotted); | 33 | void rt_plot_tasks_plotted(struct graph_info *ginfo, gint **plotted); |
30 | void rt_plot_task_update_callback(gboolean accept, gint *selected, | 34 | void rt_plot_task_update_callback(gboolean accept, gint *selected, |
diff --git a/trace-graph.h b/trace-graph.h index 4bfef4d..d56438d 100644 --- a/trace-graph.h +++ b/trace-graph.h | |||
@@ -47,6 +47,8 @@ enum graph_plot_type { | |||
47 | PLOT_TYPE_TASK, | 47 | PLOT_TYPE_TASK, |
48 | PLOT_TYPE_RT_TASK, | 48 | PLOT_TYPE_RT_TASK, |
49 | PLOT_TYPE_RT_CPU, | 49 | PLOT_TYPE_RT_CPU, |
50 | PLOT_TYPE_SERVER_TASK, | ||
51 | PLOT_TYPE_SERVER_CPU | ||
50 | }; | 52 | }; |
51 | 53 | ||
52 | enum plot_time_type { | 54 | enum plot_time_type { |
diff --git a/trace-plot-task.c b/trace-plot-task.c index ec0029d..4bfa038 100644 --- a/trace-plot-task.c +++ b/trace-plot-task.c | |||
@@ -700,7 +700,7 @@ void task_plot_destroy(struct graph_info *ginfo, struct graph_plot *plot) | |||
700 | free(task_info); | 700 | free(task_info); |
701 | } | 701 | } |
702 | 702 | ||
703 | static const struct plot_callbacks task_plot_cb = { | 703 | const struct plot_callbacks task_plot_cb = { |
704 | .match_time = task_plot_match_time, | 704 | .match_time = task_plot_match_time, |
705 | .plot_event = task_plot_event, | 705 | .plot_event = task_plot_event, |
706 | .start = task_plot_start, | 706 | .start = task_plot_start, |