aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2010-01-04 11:52:51 -0500
committerSteven Rostedt <rostedt@goodmis.org>2010-01-04 11:52:51 -0500
commit7d2d3fd2241384f6549bb1533345fcd21267c497 (patch)
tree1723b36eee305775d877d4854a7f4e1559474fe9
parent2bd6ed2cacaa77311cc9d9897ecc00858c895166 (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.c2
-rw-r--r--trace-graph.c99
-rw-r--r--trace-graph.h11
-rw-r--r--trace-hash.c87
-rw-r--r--trace-hash.h22
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
61static gint ftrace_sched_switch_id = -1; 59static gint ftrace_sched_switch_id = -1;
62static gint event_sched_switch_id = -1; 60static 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
86struct filter_task * 84struct filter_task_item *
87trace_graph_filter_task_find_pid(struct graph_info *ginfo, gint pid) 85trace_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
100static void filter_task_add_pid(struct graph_info *ginfo, gint pid) 90static 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
116static void filter_task_remove_pid(struct graph_info *ginfo, gint pid) 97static 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
143static void filter_task_clear(struct graph_info *ginfo) 107static 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
169gboolean filter_on_task(struct graph_info *ginfo, gint pid) 115gboolean 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
6struct graph_info; 7struct 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
14struct filter_task {
15 struct filter_task *next;
16 gint pid;
17};
18
19struct graph_info { 15struct 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
99struct filter_task * 94struct filter_task_item *
100trace_graph_filter_task_find_pid(struct graph_info *ginfo, gint pid); 95trace_graph_filter_task_find_pid(struct graph_info *ginfo, gint pid);
101void trace_graph_filter_toggle(struct graph_info *ginfo); 96void trace_graph_filter_toggle(struct graph_info *ginfo);
102void trace_graph_filter_add_remove_task(struct graph_info *info, 97void 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
7guint trace_hash(gint val) 9guint 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
35struct filter_task_item *
36filter_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
49void 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
64void 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
88void 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
109struct 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
6struct filter_task_item {
7 struct filter_task_item *next;
8 gint pid;
9};
10
11struct filter_task {
12 struct filter_task_item **hash;
13 gint count;
14};
15
6guint trace_hash(gint val); 16guint trace_hash(gint val);
7 17
18struct filter_task_item *
19filter_task_find_pid(struct filter_task *hash, gint pid);
20void filter_task_add_pid(struct filter_task *hash, gint pid);
21void filter_task_remove_pid(struct filter_task *hash, gint pid);
22void filter_task_clear(struct filter_task *hash);
23struct filter_task *filter_task_hash_alloc(void);
24
25static 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 */