diff options
author | Steven Rostedt <srostedt@redhat.com> | 2010-01-04 11:52:51 -0500 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2010-01-04 11:52:51 -0500 |
commit | 7d2d3fd2241384f6549bb1533345fcd21267c497 (patch) | |
tree | 1723b36eee305775d877d4854a7f4e1559474fe9 | |
parent | 2bd6ed2cacaa77311cc9d9897ecc00858c895166 (diff) |
trace-graph: Move task filter code to trace-hash.[ch]
In order to make the trace tree of kernelshark work better with
the trace-graph, move the filtering code of tasks out of trace-graph.c
into trace-hash.c. This will allow the trace-tree to be more flexible
in its filtering too.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r-- | kernel-shark.c | 2 | ||||
-rw-r--r-- | trace-graph.c | 99 | ||||
-rw-r--r-- | trace-graph.h | 11 | ||||
-rw-r--r-- | trace-hash.c | 87 | ||||
-rw-r--r-- | trace-hash.h | 22 |
5 files changed, 135 insertions, 86 deletions
diff --git a/kernel-shark.c b/kernel-shark.c index 6e92730..9cbc45a 100644 --- a/kernel-shark.c +++ b/kernel-shark.c | |||
@@ -287,7 +287,7 @@ do_tree_popup(GtkWidget *widget, GdkEventButton *event, gpointer data) | |||
287 | else | 287 | else |
288 | gtk_widget_set_sensitive(menu_filter_enable, FALSE); | 288 | gtk_widget_set_sensitive(menu_filter_enable, FALSE); |
289 | 289 | ||
290 | if (ginfo->filter_task_count) | 290 | if (filter_task_count(ginfo->task_filter)) |
291 | gtk_widget_set_sensitive(menu_filter_clear_tasks, TRUE); | 291 | gtk_widget_set_sensitive(menu_filter_clear_tasks, TRUE); |
292 | else | 292 | else |
293 | gtk_widget_set_sensitive(menu_filter_clear_tasks, FALSE); | 293 | gtk_widget_set_sensitive(menu_filter_clear_tasks, FALSE); |
diff --git a/trace-graph.c b/trace-graph.c index 839aab6..0500e35 100644 --- a/trace-graph.c +++ b/trace-graph.c | |||
@@ -56,8 +56,6 @@ | |||
56 | #define CPU_LABEL(cpu) (CPU_TOP(cpu)) | 56 | #define CPU_LABEL(cpu) (CPU_TOP(cpu)) |
57 | #define CPU_X 5 | 57 | #define CPU_X 5 |
58 | 58 | ||
59 | #define FILTER_TASK_HASH_SIZE 256 | ||
60 | |||
61 | static gint ftrace_sched_switch_id = -1; | 59 | static gint ftrace_sched_switch_id = -1; |
62 | static gint event_sched_switch_id = -1; | 60 | static gint event_sched_switch_id = -1; |
63 | 61 | ||
@@ -83,97 +81,45 @@ static void print_time(unsigned long long time) | |||
83 | printf("%lu.%06lu", sec, usec); | 81 | printf("%lu.%06lu", sec, usec); |
84 | } | 82 | } |
85 | 83 | ||
86 | struct filter_task * | 84 | struct filter_task_item * |
87 | trace_graph_filter_task_find_pid(struct graph_info *ginfo, gint pid) | 85 | trace_graph_filter_task_find_pid(struct graph_info *ginfo, gint pid) |
88 | { | 86 | { |
89 | gint key = trace_hash(pid) % FILTER_TASK_HASH_SIZE; | 87 | return filter_task_find_pid(ginfo->task_filter, pid); |
90 | struct filter_task *task = ginfo->filter_task_hash[key]; | ||
91 | |||
92 | while (task) { | ||
93 | if (task->pid == pid) | ||
94 | break; | ||
95 | task = task->next; | ||
96 | } | ||
97 | return task; | ||
98 | } | 88 | } |
99 | 89 | ||
100 | static void filter_task_add_pid(struct graph_info *ginfo, gint pid) | 90 | static void graph_filter_task_add_pid(struct graph_info *ginfo, gint pid) |
101 | { | 91 | { |
102 | gint key = trace_hash(pid) % FILTER_TASK_HASH_SIZE; | 92 | filter_task_add_pid(ginfo->task_filter, pid); |
103 | struct filter_task *task; | ||
104 | |||
105 | task = g_new0(typeof(*task), 1); | ||
106 | g_assert(task); | ||
107 | |||
108 | task->pid = pid; | ||
109 | task->next = ginfo->filter_task_hash[key]; | ||
110 | ginfo->filter_task_hash[key] = task; | ||
111 | 93 | ||
112 | ginfo->filter_task_count++; | ||
113 | ginfo->filter_available = 1; | 94 | ginfo->filter_available = 1; |
114 | } | 95 | } |
115 | 96 | ||
116 | static void filter_task_remove_pid(struct graph_info *ginfo, gint pid) | 97 | static void graph_filter_task_remove_pid(struct graph_info *ginfo, gint pid) |
117 | { | 98 | { |
118 | gint key = trace_hash(pid) % FILTER_TASK_HASH_SIZE; | 99 | filter_task_remove_pid(ginfo->task_filter, pid); |
119 | struct filter_task **next = &ginfo->filter_task_hash[key]; | ||
120 | struct filter_task *task; | ||
121 | 100 | ||
122 | while (*next) { | 101 | if (!filter_task_count(ginfo->task_filter)) { |
123 | if ((*next)->pid == pid) | 102 | ginfo->filter_available = 0; |
124 | break; | 103 | ginfo->filter_enabled = 0; |
125 | next = &(*next)->next; | ||
126 | } | 104 | } |
127 | if (!*next) | ||
128 | return; | ||
129 | |||
130 | task = *next; | ||
131 | |||
132 | *next = task->next; | ||
133 | |||
134 | g_free(task); | ||
135 | |||
136 | if (--ginfo->filter_task_count) | ||
137 | return; | ||
138 | |||
139 | ginfo->filter_available = 0; | ||
140 | ginfo->filter_enabled = 0; | ||
141 | } | 105 | } |
142 | 106 | ||
143 | static void filter_task_clear(struct graph_info *ginfo) | 107 | static void graph_filter_task_clear(struct graph_info *ginfo) |
144 | { | 108 | { |
145 | struct filter_task *task, *next;; | 109 | filter_task_clear(ginfo->task_filter); |
146 | gint i; | ||
147 | |||
148 | if (!ginfo->filter_task_count) | ||
149 | return; | ||
150 | |||
151 | for (i = 0; i < FILTER_TASK_HASH_SIZE; i++) { | ||
152 | next = ginfo->filter_task_hash[i]; | ||
153 | if (!next) | ||
154 | continue; | ||
155 | |||
156 | ginfo->filter_task_hash[i] = NULL; | ||
157 | while (next) { | ||
158 | task = next; | ||
159 | next = task->next; | ||
160 | g_free(task); | ||
161 | } | ||
162 | } | ||
163 | 110 | ||
164 | ginfo->filter_task_count = 0; | ||
165 | ginfo->filter_available = 0; | 111 | ginfo->filter_available = 0; |
166 | ginfo->filter_enabled = 0; | 112 | ginfo->filter_enabled = 0; |
167 | } | 113 | } |
168 | 114 | ||
169 | gboolean filter_on_task(struct graph_info *ginfo, gint pid) | 115 | gboolean graph_filter_on_task(struct graph_info *ginfo, gint pid) |
170 | { | 116 | { |
171 | gboolean filter; | 117 | gboolean filter; |
172 | 118 | ||
173 | filter = FALSE; | 119 | filter = FALSE; |
174 | 120 | ||
175 | if (ginfo->filter_enabled && | 121 | if (ginfo->filter_enabled && |
176 | ginfo->filter_task_count && | 122 | filter_task_count(ginfo->task_filter) && |
177 | !trace_graph_filter_task_find_pid(ginfo, pid)) | 123 | !trace_graph_filter_task_find_pid(ginfo, pid)) |
178 | filter = TRUE; | 124 | filter = TRUE; |
179 | 125 | ||
@@ -303,14 +249,14 @@ void trace_graph_filter_add_remove_task(struct graph_info *ginfo, | |||
303 | gint pid) | 249 | gint pid) |
304 | { | 250 | { |
305 | gint filter_enabled = ginfo->filter_enabled; | 251 | gint filter_enabled = ginfo->filter_enabled; |
306 | struct filter_task *task; | 252 | struct filter_task_item *task; |
307 | 253 | ||
308 | task = trace_graph_filter_task_find_pid(ginfo, pid); | 254 | task = trace_graph_filter_task_find_pid(ginfo, pid); |
309 | 255 | ||
310 | if (task) | 256 | if (task) |
311 | filter_task_remove_pid(ginfo, task->pid); | 257 | graph_filter_task_remove_pid(ginfo, task->pid); |
312 | else | 258 | else |
313 | filter_task_add_pid(ginfo, pid); | 259 | graph_filter_task_add_pid(ginfo, pid); |
314 | 260 | ||
315 | if (filter_enabled) | 261 | if (filter_enabled) |
316 | redraw_graph(ginfo); | 262 | redraw_graph(ginfo); |
@@ -328,7 +274,7 @@ void trace_graph_clear_tasks(struct graph_info *ginfo) | |||
328 | { | 274 | { |
329 | gint filter_enabled = ginfo->filter_enabled; | 275 | gint filter_enabled = ginfo->filter_enabled; |
330 | 276 | ||
331 | filter_task_clear(ginfo); | 277 | graph_filter_task_clear(ginfo); |
332 | 278 | ||
333 | if (filter_enabled) | 279 | if (filter_enabled) |
334 | redraw_graph(ginfo); | 280 | redraw_graph(ginfo); |
@@ -402,7 +348,7 @@ do_pop_up(GtkWidget *widget, GdkEventButton *event, gpointer data) | |||
402 | else | 348 | else |
403 | gtk_widget_set_sensitive(menu_filter_enable, FALSE); | 349 | gtk_widget_set_sensitive(menu_filter_enable, FALSE); |
404 | 350 | ||
405 | if (ginfo->filter_task_count) | 351 | if (filter_task_count(ginfo->task_filter)) |
406 | gtk_widget_set_sensitive(menu_filter_clear_tasks, TRUE); | 352 | gtk_widget_set_sensitive(menu_filter_clear_tasks, TRUE); |
407 | else | 353 | else |
408 | gtk_widget_set_sensitive(menu_filter_clear_tasks, FALSE); | 354 | gtk_widget_set_sensitive(menu_filter_clear_tasks, FALSE); |
@@ -1195,7 +1141,7 @@ static void draw_cpu(struct graph_info *ginfo, gint cpu, | |||
1195 | set_color_by_pid(ginfo->draw, gc, pid); | 1141 | set_color_by_pid(ginfo->draw, gc, pid); |
1196 | } | 1142 | } |
1197 | 1143 | ||
1198 | filter = filter_on_task(ginfo, last_pid); | 1144 | filter = graph_filter_on_task(ginfo, last_pid); |
1199 | 1145 | ||
1200 | if (!filter && last_pid) | 1146 | if (!filter && last_pid) |
1201 | 1147 | ||
@@ -1210,7 +1156,7 @@ static void draw_cpu(struct graph_info *ginfo, gint cpu, | |||
1210 | set_color_by_pid(ginfo->draw, gc, pid); | 1156 | set_color_by_pid(ginfo->draw, gc, pid); |
1211 | } | 1157 | } |
1212 | 1158 | ||
1213 | filter = filter_on_task(ginfo, pid); | 1159 | filter = graph_filter_on_task(ginfo, pid); |
1214 | 1160 | ||
1215 | if (!filter) | 1161 | if (!filter) |
1216 | gdk_draw_line(ginfo->curr_pixmap, gc, // ginfo->draw->style->black_gc, | 1162 | gdk_draw_line(ginfo->curr_pixmap, gc, // ginfo->draw->style->black_gc, |
@@ -1244,7 +1190,7 @@ static void draw_cpu(struct graph_info *ginfo, gint cpu, | |||
1244 | p1, p2, ginfo->draw_width, width_16, font); | 1190 | p1, p2, ginfo->draw_width, width_16, font); |
1245 | 1191 | ||
1246 | if (last_pid > 0 && | 1192 | if (last_pid > 0 && |
1247 | !filter_on_task(ginfo, last_pid)) { | 1193 | !graph_filter_on_task(ginfo, last_pid)) { |
1248 | 1194 | ||
1249 | x = ginfo->draw_width; | 1195 | x = ginfo->draw_width; |
1250 | 1196 | ||
@@ -1607,8 +1553,7 @@ trace_graph_create_with_callbacks(struct tracecmd_input *handle, | |||
1607 | ginfo->start_time = -1ULL; | 1553 | ginfo->start_time = -1ULL; |
1608 | ginfo->end_time = 0; | 1554 | ginfo->end_time = 0; |
1609 | 1555 | ||
1610 | ginfo->filter_task_hash = g_new0(typeof(*ginfo->filter_task_hash), | 1556 | ginfo->task_filter = filter_task_hash_alloc(); |
1611 | FILTER_TASK_HASH_SIZE); | ||
1612 | 1557 | ||
1613 | ginfo->widget = gtk_hbox_new(FALSE, 0); | 1558 | ginfo->widget = gtk_hbox_new(FALSE, 0); |
1614 | gtk_widget_show(ginfo->widget); | 1559 | gtk_widget_show(ginfo->widget); |
diff --git a/trace-graph.h b/trace-graph.h index ac52003..61d17db 100644 --- a/trace-graph.h +++ b/trace-graph.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define _TRACE_GRAPH_H | 2 | #define _TRACE_GRAPH_H |
3 | 3 | ||
4 | #include "trace-cmd.h" | 4 | #include "trace-cmd.h" |
5 | #include "trace-hash.h" | ||
5 | 6 | ||
6 | struct graph_info; | 7 | struct graph_info; |
7 | 8 | ||
@@ -11,11 +12,6 @@ struct graph_callbacks { | |||
11 | graph_select_cb *select; | 12 | graph_select_cb *select; |
12 | }; | 13 | }; |
13 | 14 | ||
14 | struct filter_task { | ||
15 | struct filter_task *next; | ||
16 | gint pid; | ||
17 | }; | ||
18 | |||
19 | struct graph_info { | 15 | struct graph_info { |
20 | struct tracecmd_input *handle; | 16 | struct tracecmd_input *handle; |
21 | struct pevent *pevent; | 17 | struct pevent *pevent; |
@@ -55,8 +51,7 @@ struct graph_info { | |||
55 | int filter_enabled; | 51 | int filter_enabled; |
56 | int filter_available; | 52 | int filter_available; |
57 | 53 | ||
58 | struct filter_task **filter_task_hash; | 54 | struct filter_task *task_filter; |
59 | gint filter_task_count; | ||
60 | gint filter_task_selected; | 55 | gint filter_task_selected; |
61 | 56 | ||
62 | 57 | ||
@@ -96,7 +91,7 @@ static inline GtkWidget *trace_graph_get_window(struct graph_info *ginfo) | |||
96 | return ginfo->widget; | 91 | return ginfo->widget; |
97 | } | 92 | } |
98 | 93 | ||
99 | struct filter_task * | 94 | struct filter_task_item * |
100 | trace_graph_filter_task_find_pid(struct graph_info *ginfo, gint pid); | 95 | trace_graph_filter_task_find_pid(struct graph_info *ginfo, gint pid); |
101 | void trace_graph_filter_toggle(struct graph_info *ginfo); | 96 | void trace_graph_filter_toggle(struct graph_info *ginfo); |
102 | void trace_graph_filter_add_remove_task(struct graph_info *info, | 97 | void trace_graph_filter_add_remove_task(struct graph_info *info, |
diff --git a/trace-hash.c b/trace-hash.c index 9d830e2..99b9feb 100644 --- a/trace-hash.c +++ b/trace-hash.c | |||
@@ -4,6 +4,8 @@ | |||
4 | 4 | ||
5 | #include "trace-hash.h" | 5 | #include "trace-hash.h" |
6 | 6 | ||
7 | #define FILTER_TASK_HASH_SIZE 256 | ||
8 | |||
7 | guint trace_hash(gint val) | 9 | guint trace_hash(gint val) |
8 | { | 10 | { |
9 | gint hash, tmp; | 11 | gint hash, tmp; |
@@ -29,3 +31,88 @@ guint trace_hash(gint val) | |||
29 | 31 | ||
30 | return hash; | 32 | return hash; |
31 | } | 33 | } |
34 | |||
35 | struct filter_task_item * | ||
36 | filter_task_find_pid(struct filter_task *hash, gint pid) | ||
37 | { | ||
38 | gint key = trace_hash(pid) % FILTER_TASK_HASH_SIZE; | ||
39 | struct filter_task_item *task = hash->hash[key]; | ||
40 | |||
41 | while (task) { | ||
42 | if (task->pid == pid) | ||
43 | break; | ||
44 | task = task->next; | ||
45 | } | ||
46 | return task; | ||
47 | } | ||
48 | |||
49 | void filter_task_add_pid(struct filter_task *hash, gint pid) | ||
50 | { | ||
51 | gint key = trace_hash(pid) % FILTER_TASK_HASH_SIZE; | ||
52 | struct filter_task_item *task; | ||
53 | |||
54 | task = g_new0(typeof(*task), 1); | ||
55 | g_assert(task); | ||
56 | |||
57 | task->pid = pid; | ||
58 | task->next = hash->hash[key]; | ||
59 | hash->hash[key] = task; | ||
60 | |||
61 | hash->count++; | ||
62 | } | ||
63 | |||
64 | void filter_task_remove_pid(struct filter_task *hash, gint pid) | ||
65 | { | ||
66 | gint key = trace_hash(pid) % FILTER_TASK_HASH_SIZE; | ||
67 | struct filter_task_item **next = &hash->hash[key]; | ||
68 | struct filter_task_item *task; | ||
69 | |||
70 | while (*next) { | ||
71 | if ((*next)->pid == pid) | ||
72 | break; | ||
73 | next = &(*next)->next; | ||
74 | } | ||
75 | if (!*next) | ||
76 | return; | ||
77 | |||
78 | g_assert(hash->count); | ||
79 | hash->count--; | ||
80 | |||
81 | task = *next; | ||
82 | |||
83 | *next = task->next; | ||
84 | |||
85 | g_free(task); | ||
86 | } | ||
87 | |||
88 | void filter_task_clear(struct filter_task *hash) | ||
89 | { | ||
90 | struct filter_task_item *task, *next;; | ||
91 | gint i; | ||
92 | |||
93 | for (i = 0; i < FILTER_TASK_HASH_SIZE; i++) { | ||
94 | next = hash->hash[i]; | ||
95 | if (!next) | ||
96 | continue; | ||
97 | |||
98 | hash->hash[i] = NULL; | ||
99 | while (next) { | ||
100 | task = next; | ||
101 | next = task->next; | ||
102 | g_free(task); | ||
103 | } | ||
104 | } | ||
105 | |||
106 | hash->count = 0; | ||
107 | } | ||
108 | |||
109 | struct filter_task *filter_task_hash_alloc(void) | ||
110 | { | ||
111 | struct filter_task *hash; | ||
112 | |||
113 | hash = g_new0(typeof(*hash), 1); | ||
114 | g_assert(hash); | ||
115 | hash->hash = g_new0(typeof(*hash->hash), FILTER_TASK_HASH_SIZE); | ||
116 | |||
117 | return hash; | ||
118 | } | ||
diff --git a/trace-hash.h b/trace-hash.h index 8a22044..cab6195 100644 --- a/trace-hash.h +++ b/trace-hash.h | |||
@@ -3,6 +3,28 @@ | |||
3 | 3 | ||
4 | #include <glib.h> | 4 | #include <glib.h> |
5 | 5 | ||
6 | struct filter_task_item { | ||
7 | struct filter_task_item *next; | ||
8 | gint pid; | ||
9 | }; | ||
10 | |||
11 | struct filter_task { | ||
12 | struct filter_task_item **hash; | ||
13 | gint count; | ||
14 | }; | ||
15 | |||
6 | guint trace_hash(gint val); | 16 | guint trace_hash(gint val); |
7 | 17 | ||
18 | struct filter_task_item * | ||
19 | filter_task_find_pid(struct filter_task *hash, gint pid); | ||
20 | void filter_task_add_pid(struct filter_task *hash, gint pid); | ||
21 | void filter_task_remove_pid(struct filter_task *hash, gint pid); | ||
22 | void filter_task_clear(struct filter_task *hash); | ||
23 | struct filter_task *filter_task_hash_alloc(void); | ||
24 | |||
25 | static inline gint filter_task_count(struct filter_task *hash) | ||
26 | { | ||
27 | return hash->count; | ||
28 | } | ||
29 | |||
8 | #endif /* _TRACE_HASH_H */ | 30 | #endif /* _TRACE_HASH_H */ |