aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2010-02-16 21:38:20 -0500
committerSteven Rostedt <rostedt@goodmis.org>2010-02-16 21:38:20 -0500
commitad813ef9fb16cf4510be274a04dfb37c9fadf6e3 (patch)
treeaff765f316121d6623c27d1578d921d0485480ac
parent2f9d0898a306b35bed28eb1b455db7a69f058b5b (diff)
kernelshark: Convert to using event_filters for graph and list
Use the new pevent event_filter infrastructure to filter events. It removes a lot of specific graph and list code and is also faster. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--kernel-shark.c31
-rw-r--r--trace-filter.c130
-rw-r--r--trace-filter.h7
-rw-r--r--trace-graph-main.c6
-rw-r--r--trace-graph.c110
-rw-r--r--trace-graph.h5
-rw-r--r--trace-view-main.c9
-rw-r--r--trace-view-store.c165
-rw-r--r--trace-view-store.h25
-rw-r--r--trace-view.c12
10 files changed, 193 insertions, 307 deletions
diff --git a/kernel-shark.c b/kernel-shark.c
index d199e56..d13819d 100644
--- a/kernel-shark.c
+++ b/kernel-shark.c
@@ -192,6 +192,7 @@ static void
192list_events_clicked (gpointer data) 192list_events_clicked (gpointer data)
193{ 193{
194 struct shark_info *info = data; 194 struct shark_info *info = data;
195 struct event_filter *event_filter;
195 GtkTreeView *trace_tree = GTK_TREE_VIEW(info->treeview); 196 GtkTreeView *trace_tree = GTK_TREE_VIEW(info->treeview);
196 GtkTreeModel *model; 197 GtkTreeModel *model;
197 TraceViewStore *store; 198 TraceViewStore *store;
@@ -206,12 +207,16 @@ list_events_clicked (gpointer data)
206 store = TRACE_VIEW_STORE(model); 207 store = TRACE_VIEW_STORE(model);
207 208
208 all_events = trace_view_store_get_all_events_enabled(store); 209 all_events = trace_view_store_get_all_events_enabled(store);
209 systems = trace_view_store_get_systems_enabled(store); 210 event_filter = trace_view_store_get_event_filter(store);
210 events = trace_view_store_get_events_enabled(store); 211
212 trace_filter_convert_filter_to_names(event_filter,
213 &systems, &events);
211 214
212 trace_filter_event_dialog(store->handle, all_events, 215 trace_filter_event_dialog(store->handle, all_events,
213 systems, events, 216 systems, events,
214 trace_view_event_filter_callback, info->treeview); 217 trace_view_event_filter_callback, info->treeview);
218 free(systems);
219 free(events);
215} 220}
216 221
217static void 222static void
@@ -224,18 +229,20 @@ graph_events_clicked (gpointer data)
224 gint *events; 229 gint *events;
225 230
226 all_events = ginfo->all_events; 231 all_events = ginfo->all_events;
227 systems = ginfo->systems; 232 trace_filter_convert_filter_to_names(ginfo->event_filter,
228 events = ginfo->event_ids; 233 &systems, &events);
229
230 trace_filter_event_dialog(info->handle, all_events, 234 trace_filter_event_dialog(info->handle, all_events,
231 systems, events, 235 systems, events,
232 trace_graph_event_filter_callback, ginfo); 236 trace_graph_event_filter_callback, ginfo);
237 free(systems);
238 free(events);
233} 239}
234 240
235static void 241static void
236sync_graph_events_to_list_clicked (gpointer data) 242sync_graph_events_to_list_clicked (gpointer data)
237{ 243{
238 struct shark_info *info = data; 244 struct shark_info *info = data;
245 struct event_filter *event_filter;
239 GtkTreeView *trace_tree = GTK_TREE_VIEW(info->treeview); 246 GtkTreeView *trace_tree = GTK_TREE_VIEW(info->treeview);
240 GtkTreeModel *model; 247 GtkTreeModel *model;
241 TraceViewStore *store; 248 TraceViewStore *store;
@@ -250,11 +257,15 @@ sync_graph_events_to_list_clicked (gpointer data)
250 store = TRACE_VIEW_STORE(model); 257 store = TRACE_VIEW_STORE(model);
251 258
252 all_events = trace_view_store_get_all_events_enabled(store); 259 all_events = trace_view_store_get_all_events_enabled(store);
253 systems = trace_view_store_get_systems_enabled(store); 260 event_filter = trace_view_store_get_event_filter(store);
254 events = trace_view_store_get_events_enabled(store); 261
262 trace_filter_convert_filter_to_names(event_filter,
263 &systems, &events);
255 264
256 trace_graph_event_filter_callback(TRUE, all_events, systems, 265 trace_graph_event_filter_callback(TRUE, all_events, systems,
257 events, info->ginfo); 266 events, info->ginfo);
267 free(systems);
268 free(events);
258} 269}
259 270
260 271
@@ -268,11 +279,13 @@ sync_list_events_to_graph_clicked (gpointer data)
268 gint *events; 279 gint *events;
269 280
270 all_events = ginfo->all_events; 281 all_events = ginfo->all_events;
271 systems = ginfo->systems; 282 trace_filter_convert_filter_to_names(ginfo->event_filter,
272 events = ginfo->event_ids; 283 &systems, &events);
273 284
274 trace_view_event_filter_callback(TRUE, all_events, systems, 285 trace_view_event_filter_callback(TRUE, all_events, systems,
275 events, info->treeview); 286 events, info->treeview);
287 free(systems);
288 free(events);
276} 289}
277 290
278/* Callback for the clicked signal of the CPUs filter button */ 291/* Callback for the clicked signal of the CPUs filter button */
diff --git a/trace-filter.c b/trace-filter.c
index 126d181..7e5d37d 100644
--- a/trace-filter.c
+++ b/trace-filter.c
@@ -590,8 +590,7 @@ event_dialog_response (gpointer data, gint response_id)
590 */ 590 */
591void trace_filter_event_dialog(struct tracecmd_input *handle, 591void trace_filter_event_dialog(struct tracecmd_input *handle,
592 gboolean all_events, 592 gboolean all_events,
593 gchar **systems, 593 gchar **systems, gint *events,
594 gint *events,
595 trace_filter_event_cb_func func, 594 trace_filter_event_cb_func func,
596 gpointer data) 595 gpointer data)
597{ 596{
@@ -883,3 +882,130 @@ void trace_filter_cpu_dialog(gboolean all_cpus, guint64 *cpus_selected, gint cpu
883 882
884 gtk_widget_show_all(dialog); 883 gtk_widget_show_all(dialog);
885} 884}
885
886static void add_system_str(gchar ***systems, char *system, int count)
887{
888 if (!systems)
889 return;
890
891 if (!count)
892 *systems = malloc_or_die(sizeof(char *) * 2);
893 else
894 *systems = realloc(*systems, sizeof(char *) * (count + 2));
895 if (!*systems)
896 die("Can't allocate systems");
897
898 (*systems)[count] = system;
899 (*systems)[count+1] = NULL;
900}
901
902static void add_event_int(gint **events, gint event, int count)
903{
904 if (!events)
905 return;
906
907 if (!count)
908 *events = malloc_or_die(sizeof(gint) * 2);
909 else
910 *events = realloc(*events, sizeof(gint) * (count + 2));
911 if (!*events)
912 die("Can't allocate events");
913
914 (*events)[count] = event;
915 (*events)[count+1] = -1;
916}
917
918/* -- Helper functions -- */
919
920/**
921 * trace_filter_convert_filter_to_names - convert a filter to names.
922 * @filter: the filter to convert
923 * @systems: array of systems that the filter selects (may be NULL)
924 * @event_ids: array of event ids that the filter selects (may be NULL)
925 *
926 * @systems will be filled when the filter selects all events within
927 * its system. (may return NULL)
928 *
929 * @event_ids will be all events selected (not including those selected
930 * by @systems)
931 */
932void trace_filter_convert_filter_to_names(struct event_filter *filter,
933 gchar ***systems,
934 gint **event_ids)
935{
936 struct pevent *pevent = filter->pevent;
937 struct event_format **events;
938 struct event_format *event;
939 char *last_system = NULL;
940 int all_selected = 1;
941 int start_sys = 0;
942 int sys_count = 0;
943 int event_count = 0;
944 int i, x;
945
946 if (systems)
947 *systems = NULL;
948 if (event_ids)
949 *event_ids = NULL;
950
951 events = pevent_list_events(pevent, EVENT_SORT_SYSTEM);
952
953 for (i = 0; events[i]; i++) {
954 event = events[i];
955
956 if (systems && last_system &&
957 strcmp(last_system, events[i]->system) != 0) {
958 if (all_selected)
959 add_system_str(systems, last_system, sys_count++);
960 start_sys = i;
961 all_selected = 1;
962 }
963
964 if (pevent_event_filtered(filter, event->id)) {
965 if (!all_selected || !systems)
966 add_event_int(event_ids, event->id, event_count++);
967 } else {
968 if (all_selected && event_ids) {
969 for (x = start_sys; x < i; x++) {
970 add_event_int(event_ids,
971 events[x]->id, event_count++);
972 }
973 }
974 all_selected = 0;
975 }
976 last_system = event->system;
977 }
978
979 if (systems && last_system && all_selected)
980 add_system_str(systems, last_system, sys_count++);
981}
982
983/**
984 * trace_filter_convert_char_to_filter - convert the strings to the filter
985 * @filter: the filter to convert
986 * @systems: array of systems that will have its events selected in @filter
987 * @events: array of event ids that will be selected in @filter
988 */
989void trace_filter_convert_char_to_filter(struct event_filter *filter,
990 gchar **systems,
991 gint *events)
992{
993 struct event_format *event;
994 int i;
995
996 if (systems) {
997 for (i = 0; systems[i]; i++)
998 pevent_filter_add_filter_str(filter,
999 systems[i], NULL);
1000 }
1001
1002 if (events) {
1003 for (i = 0; events[i] >= 0; i++) {
1004 event = pevent_find_event(filter->pevent, events[i]);
1005 if (event)
1006 pevent_filter_add_filter_str(filter,
1007 event->name,
1008 NULL);
1009 }
1010 }
1011}
diff --git a/trace-filter.h b/trace-filter.h
index e20e742..73bdb67 100644
--- a/trace-filter.h
+++ b/trace-filter.h
@@ -54,6 +54,13 @@ void trace_filter_event_dialog(struct tracecmd_input *handle,
54 trace_filter_event_cb_func func, 54 trace_filter_event_cb_func func,
55 gpointer data); 55 gpointer data);
56 56
57void trace_filter_convert_filter_to_names(struct event_filter *filter,
58 gchar ***systems,
59 gint **events);
60
61void trace_filter_convert_char_to_filter(struct event_filter *filter,
62 gchar **systems,
63 gint *events);
57/** 64/**
58 * trace_filter_cpu_cb_func - callback type for CPU dialog 65 * trace_filter_cpu_cb_func - callback type for CPU dialog
59 * @accept: TRUE if the accept button was pressed, otherwise FALSE 66 * @accept: TRUE if the accept button was pressed, otherwise FALSE
diff --git a/trace-graph-main.c b/trace-graph-main.c
index e3e5b48..b31e118 100644
--- a/trace-graph-main.c
+++ b/trace-graph-main.c
@@ -106,12 +106,14 @@ events_clicked (gpointer data)
106 return; 106 return;
107 107
108 all_events = ginfo->all_events; 108 all_events = ginfo->all_events;
109 systems = ginfo->systems;
110 events = ginfo->event_ids;
111 109
110 trace_filter_convert_filter_to_names(ginfo->event_filter,
111 &systems, &events);
112 trace_filter_event_dialog(ginfo->handle, all_events, 112 trace_filter_event_dialog(ginfo->handle, all_events,
113 systems, events, 113 systems, events,
114 trace_graph_event_filter_callback, ginfo); 114 trace_graph_event_filter_callback, ginfo);
115 free(systems);
116 free(events);
115} 117}
116 118
117void trace_graph(int argc, char **argv) 119void trace_graph(int argc, char **argv)
diff --git a/trace-graph.c b/trace-graph.c
index 6f2661e..a440602 100644
--- a/trace-graph.c
+++ b/trace-graph.c
@@ -178,42 +178,9 @@ static void graph_filter_task_clear(struct graph_info *ginfo)
178 ginfo->filter_enabled = 0; 178 ginfo->filter_enabled = 0;
179} 179}
180 180
181gboolean graph_filter_system(struct graph_info *ginfo, const gchar *system)
182{
183 const gchar **sys = &system;
184
185 if (ginfo->all_events)
186 return TRUE;
187
188 if (!ginfo->systems)
189 return FALSE;
190
191 sys = bsearch(sys, ginfo->systems, ginfo->systems_size,
192 sizeof(system), str_cmp);
193
194 return sys != NULL;
195}
196
197gboolean graph_filter_event(struct graph_info *ginfo, gint event_id)
198{
199 gint *event = &event_id;
200
201 if (ginfo->all_events)
202 return TRUE;
203
204 if (!ginfo->event_ids)
205 return FALSE;
206
207 event = bsearch(event, ginfo->event_ids, ginfo->event_ids_size,
208 sizeof(event_id), id_cmp);
209
210 return event != NULL;
211}
212
213gboolean trace_graph_filter_on_event(struct graph_info *ginfo, struct record *record) 181gboolean trace_graph_filter_on_event(struct graph_info *ginfo, struct record *record)
214{ 182{
215 struct event_format *event; 183 int ret;
216 gint event_id;
217 184
218 if (!record) 185 if (!record)
219 return TRUE; 186 return TRUE;
@@ -221,18 +188,8 @@ gboolean trace_graph_filter_on_event(struct graph_info *ginfo, struct record *re
221 if (ginfo->all_events) 188 if (ginfo->all_events)
222 return FALSE; 189 return FALSE;
223 190
224 event_id = pevent_data_type(ginfo->pevent, record); 191 ret = pevent_filter_match(ginfo->event_filter, record);
225 event = pevent_data_event_from_type(ginfo->pevent, event_id); 192 return ret == FILTER_MATCH ? FALSE : TRUE;
226 if (!event)
227 return TRUE;
228
229 if (graph_filter_system(ginfo, event->system))
230 return FALSE;
231
232 if (graph_filter_event(ginfo, event_id))
233 return FALSE;
234
235 return TRUE;
236} 193}
237 194
238gboolean trace_graph_filter_on_task(struct graph_info *ginfo, gint pid) 195gboolean trace_graph_filter_on_task(struct graph_info *ginfo, gint pid)
@@ -1766,28 +1723,6 @@ void trace_graph_select_by_time(struct graph_info *ginfo, guint64 time)
1766 gtk_adjustment_set_value(vadj, (PLOT_BOTTOM(i) - view_width) + 10); 1723 gtk_adjustment_set_value(vadj, (PLOT_BOTTOM(i) - view_width) + 10);
1767} 1724}
1768 1725
1769static void graph_free_systems(struct graph_info *ginfo)
1770{
1771 gint i;
1772
1773 if (!ginfo->systems)
1774 return;
1775
1776 for (i = 0; ginfo->systems[i]; i++)
1777 g_free(ginfo->systems[i]);
1778
1779 g_free(ginfo->systems);
1780 ginfo->systems = NULL;
1781 ginfo->systems_size = 0;
1782}
1783
1784static void graph_free_events(struct graph_info *ginfo)
1785{
1786 g_free(ginfo->event_ids);
1787 ginfo->event_ids = NULL;
1788 ginfo->event_ids_size = 0;
1789}
1790
1791void trace_graph_event_filter_callback(gboolean accept, 1726void trace_graph_event_filter_callback(gboolean accept,
1792 gboolean all_events, 1727 gboolean all_events,
1793 gchar **systems, 1728 gchar **systems,
@@ -1795,14 +1730,10 @@ void trace_graph_event_filter_callback(gboolean accept,
1795 gpointer data) 1730 gpointer data)
1796{ 1731{
1797 struct graph_info *ginfo = data; 1732 struct graph_info *ginfo = data;
1798 gint i;
1799 1733
1800 if (!accept) 1734 if (!accept)
1801 return; 1735 return;
1802 1736
1803 graph_free_systems(ginfo);
1804 graph_free_events(ginfo);
1805
1806 if (all_events) { 1737 if (all_events) {
1807 ginfo->all_events = TRUE; 1738 ginfo->all_events = TRUE;
1808 redraw_graph(ginfo); 1739 redraw_graph(ginfo);
@@ -1811,33 +1742,10 @@ void trace_graph_event_filter_callback(gboolean accept,
1811 1742
1812 ginfo->all_events = FALSE; 1743 ginfo->all_events = FALSE;
1813 1744
1814 if (systems) { 1745 pevent_filter_reset(ginfo->event_filter);
1815 for (ginfo->systems_size = 0;
1816 systems[ginfo->systems_size];
1817 ginfo->systems_size++)
1818 ;
1819
1820 ginfo->systems = g_new(typeof(*systems), ginfo->systems_size + 1);
1821 for (i = 0; i < ginfo->systems_size; i++)
1822 ginfo->systems[i] = g_strdup(systems[i]);
1823 ginfo->systems[i] = NULL;
1824
1825 qsort(ginfo->systems, ginfo->systems_size, sizeof(gchar *), str_cmp);
1826 }
1827
1828 if (events) {
1829 for (ginfo->event_ids_size = 0;
1830 events[ginfo->event_ids_size] >= 0;
1831 ginfo->event_ids_size++)
1832 ;
1833
1834 ginfo->event_ids = g_new(typeof(*events), ginfo->event_ids_size + 1);
1835 for (i = 0; i < ginfo->event_ids_size; i++)
1836 ginfo->event_ids[i] = events[i];
1837 ginfo->event_ids[i] = -1;
1838 1746
1839 qsort(ginfo->event_ids, ginfo->event_ids_size, sizeof(gint), id_cmp); 1747 trace_filter_convert_char_to_filter(ginfo->event_filter,
1840 } 1748 systems, events);
1841 1749
1842 redraw_graph(ginfo); 1750 redraw_graph(ginfo);
1843} 1751}
@@ -1908,9 +1816,6 @@ destroy_event(GtkWidget *widget, gpointer data)
1908 1816
1909 trace_graph_free_info(ginfo); 1817 trace_graph_free_info(ginfo);
1910 1818
1911 graph_free_systems(ginfo);
1912 graph_free_events(ginfo);
1913
1914 filter_task_hash_free(ginfo->task_filter); 1819 filter_task_hash_free(ginfo->task_filter);
1915 filter_task_hash_free(ginfo->hide_tasks); 1820 filter_task_hash_free(ginfo->hide_tasks);
1916 1821
@@ -2040,6 +1945,7 @@ create_graph_info(struct graph_info *ginfo)
2040void trace_graph_free_info(struct graph_info *ginfo) 1945void trace_graph_free_info(struct graph_info *ginfo)
2041{ 1946{
2042 if (ginfo->handle) { 1947 if (ginfo->handle) {
1948 pevent_filter_free(ginfo->event_filter);
2043 trace_graph_plot_free(ginfo); 1949 trace_graph_plot_free(ginfo);
2044 tracecmd_close(ginfo->handle); 1950 tracecmd_close(ginfo->handle);
2045 } 1951 }
@@ -2068,6 +1974,8 @@ static int load_handle(struct graph_info *ginfo,
2068 ginfo->cpus = tracecmd_cpus(handle); 1974 ginfo->cpus = tracecmd_cpus(handle);
2069 ginfo->all_events = TRUE; 1975 ginfo->all_events = TRUE;
2070 1976
1977 ginfo->event_filter = pevent_filter_alloc(ginfo->pevent);
1978
2071 ginfo->start_time = -1ULL; 1979 ginfo->start_time = -1ULL;
2072 ginfo->end_time = 0; 1980 ginfo->end_time = 0;
2073 1981
diff --git a/trace-graph.h b/trace-graph.h
index 1bbe4d5..411e750 100644
--- a/trace-graph.h
+++ b/trace-graph.h
@@ -187,10 +187,7 @@ struct graph_info {
187 gboolean filter_available; 187 gboolean filter_available;
188 188
189 gboolean all_events; /* all events enabled */ 189 gboolean all_events; /* all events enabled */
190 gchar **systems; /* event systems to filter on */ 190 struct event_filter *event_filter; /* filtered events */
191 gint *event_ids; /* events to filter on */
192 gint systems_size;
193 gint event_ids_size;
194 191
195 /* cache of event fields */ 192 /* cache of event fields */
196 gint ftrace_sched_switch_id; 193 gint ftrace_sched_switch_id;
diff --git a/trace-view-main.c b/trace-view-main.c
index e04fd05..2bbfd42 100644
--- a/trace-view-main.c
+++ b/trace-view-main.c
@@ -99,6 +99,7 @@ static void
99events_clicked (gpointer data) 99events_clicked (gpointer data)
100{ 100{
101 struct trace_tree_info *info = data; 101 struct trace_tree_info *info = data;
102 struct event_filter *event_filter;
102 GtkTreeView *trace_tree = GTK_TREE_VIEW(info->trace_tree); 103 GtkTreeView *trace_tree = GTK_TREE_VIEW(info->trace_tree);
103 GtkTreeModel *model; 104 GtkTreeModel *model;
104 TraceViewStore *store; 105 TraceViewStore *store;
@@ -113,12 +114,16 @@ events_clicked (gpointer data)
113 store = TRACE_VIEW_STORE(model); 114 store = TRACE_VIEW_STORE(model);
114 115
115 all_events = trace_view_store_get_all_events_enabled(store); 116 all_events = trace_view_store_get_all_events_enabled(store);
116 systems = trace_view_store_get_systems_enabled(store); 117 event_filter = trace_view_store_get_event_filter(store);
117 events = trace_view_store_get_events_enabled(store); 118
119 trace_filter_convert_filter_to_names(event_filter,
120 &systems, &events);
118 121
119 trace_filter_event_dialog(store->handle, all_events, 122 trace_filter_event_dialog(store->handle, all_events,
120 systems, events, 123 systems, events,
121 trace_view_event_filter_callback, trace_tree); 124 trace_view_event_filter_callback, trace_tree);
125 free(systems);
126 free(events);
122} 127}
123 128
124/* Callback for the clicked signal of the CPUs filter button */ 129/* Callback for the clicked signal of the CPUs filter button */
diff --git a/trace-view-store.c b/trace-view-store.c
index 366571f..e148f67 100644
--- a/trace-view-store.c
+++ b/trace-view-store.c
@@ -239,6 +239,7 @@ trace_view_store_finalize (GObject *object)
239 store->spin = NULL; 239 store->spin = NULL;
240 } 240 }
241 241
242 pevent_filter_free(store->event_filter);
242 tracecmd_close(store->handle); 243 tracecmd_close(store->handle);
243 244
244 /* must chain up - finalize parent */ 245 /* must chain up - finalize parent */
@@ -520,61 +521,9 @@ trace_view_store_get_value (GtkTreeModel *tree_model,
520 } 521 }
521} 522}
522 523
523gboolean trace_view_store_system_enabled(TraceViewStore *store, const gchar *system)
524{
525 const gchar **sys = &system;
526
527 g_return_val_if_fail (TRACE_VIEW_IS_LIST (store), FALSE);
528
529 if (store->all_events)
530 return TRUE;
531
532 if (!store->systems)
533 return FALSE;
534
535 sys = bsearch(sys, store->systems, store->systems_size,
536 sizeof(system), str_cmp);
537
538 return sys != NULL;
539}
540
541gboolean trace_view_store_event_enabled(TraceViewStore *store, gint event_id)
542{
543 gint key = event_id;
544 gint *ret;
545
546 g_return_val_if_fail (TRACE_VIEW_IS_LIST (store), FALSE);
547
548 if (store->all_events)
549 return TRUE;
550
551 /* TODO: search for the system of the event? */
552
553 if (!store->event_types)
554 return FALSE;
555
556 ret = bsearch(&key, store->event_types, store->event_types_size,
557 sizeof(gint), id_cmp);
558
559 return ret != NULL;
560}
561
562static void clear_all_events(TraceViewStore *store) 524static void clear_all_events(TraceViewStore *store)
563{ 525{
564 gint i; 526 pevent_filter_reset(store->event_filter);
565
566 if (store->systems_size) {
567 for (i = 0; i < store->systems_size; i++)
568 g_free(store->systems[i]);
569
570 g_free(store->systems);
571 store->systems = NULL;
572 store->systems_size = 0;
573 }
574
575 g_free(store->event_types);
576 store->event_types = NULL;
577 store->event_types_size = 0;
578} 527}
579 528
580void trace_view_store_clear_all_events_enabled(TraceViewStore *store) 529void trace_view_store_clear_all_events_enabled(TraceViewStore *store)
@@ -602,99 +551,6 @@ void trace_view_store_set_all_events_enabled(TraceViewStore *store)
602 store->all_events = 1; 551 store->all_events = 1;
603} 552}
604 553
605static void remove_system(TraceViewStore *store, const gchar *system)
606{
607 const gchar **sys = &system;
608
609 if (!store->systems)
610 return;
611
612 sys = bsearch(sys, store->systems, store->systems_size,
613 sizeof(system), str_cmp);
614
615 if (!sys)
616 return;
617
618 g_free(*((gchar **)sys));
619
620 g_memmove(sys, sys+1, sizeof(*sys) * (store->systems_size -
621 ((gchar **)sys - store->systems)));
622 store->systems_size--;
623 store->systems[store->systems_size] = NULL;
624}
625
626void trace_view_store_set_system_enabled(TraceViewStore *store, const gchar *system)
627{
628 g_return_if_fail (TRACE_VIEW_IS_LIST (store));
629
630 if (store->all_events)
631 /*
632 * We are adding a new filter, so this is the
633 * only system enabled.
634 */
635 store->all_events = 0;
636
637 if (trace_view_store_system_enabled(store, system))
638 return;
639
640 if (!store->systems) {
641 store->systems = g_new0(gchar *, 2);
642 store->systems[0] = g_strdup(system);
643 store->systems_size++;
644 return;
645 }
646
647 store->systems_size++;
648 store->systems = g_realloc(store->systems,
649 sizeof(*store->systems) * (store->systems_size+1));
650 store->systems[store->systems_size - 1] = g_strdup(system);
651 store->systems[store->systems_size] = NULL;
652
653 qsort(store->systems, store->systems_size, sizeof(gchar *), str_cmp);
654}
655
656
657void trace_view_store_set_event_enabled(TraceViewStore *store, gint event_id)
658{
659 struct pevent *pevent;
660 struct event_format *event;
661
662 g_return_if_fail (TRACE_VIEW_IS_LIST (store));
663
664 pevent = tracecmd_get_pevent(store->handle);
665 event = pevent_find_event(pevent, event_id);
666 if (!event)
667 return;
668
669 if (store->all_events)
670 /*
671 * We are adding a new filter, so this is the
672 * only system enabled.
673 */
674 store->all_events = 0;
675
676 remove_system(store, event->system);
677
678 if (trace_view_store_event_enabled(store, event_id))
679 return;
680
681 if (!store->event_types) {
682 store->event_types = g_new0(gint, 2);
683 store->event_types[0] = event_id;
684 store->event_types[1] = -1;
685 store->event_types_size++;
686 return;
687 }
688
689 store->event_types_size++;
690 store->event_types = g_realloc(store->event_types,
691 sizeof(*store->event_types) * (store->event_types_size+1));
692 store->event_types[store->event_types_size - 1] = event_id;
693 store->event_types[store->event_types_size] = -1;
694
695 qsort(store->event_types, store->event_types_size, sizeof(gint), id_cmp);
696}
697
698 554
699/***************************************************************************** 555/*****************************************************************************
700 * 556 *
@@ -1018,6 +874,7 @@ trace_view_store_new (struct tracecmd_input *handle)
1018 newstore->handle = handle; 874 newstore->handle = handle;
1019 newstore->cpus = tracecmd_cpus(handle); 875 newstore->cpus = tracecmd_cpus(handle);
1020 tracecmd_ref(handle); 876 tracecmd_ref(handle);
877 newstore->event_filter = pevent_filter_alloc(tracecmd_get_pevent(handle));
1021 878
1022 newstore->cpu_list = g_new(TraceViewRecord *, newstore->cpus); 879 newstore->cpu_list = g_new(TraceViewRecord *, newstore->cpus);
1023 g_assert(newstore->cpu_list != NULL); 880 g_assert(newstore->cpu_list != NULL);
@@ -1361,11 +1218,8 @@ static gboolean show_task(TraceViewStore *store, struct pevent *pevent,
1361static void update_filter_tasks(TraceViewStore *store) 1218static void update_filter_tasks(TraceViewStore *store)
1362{ 1219{
1363 struct tracecmd_input *handle; 1220 struct tracecmd_input *handle;
1364 struct event_format *event;
1365 struct pevent *pevent; 1221 struct pevent *pevent;
1366 struct record *record; 1222 struct record *record;
1367 gint last_event_id = -1;
1368 gint event_id;
1369 gint pid; 1223 gint pid;
1370 gint cpu; 1224 gint cpu;
1371 gint i; 1225 gint i;
@@ -1404,15 +1258,10 @@ static void update_filter_tasks(TraceViewStore *store)
1404 1258
1405 /* The record may be filtered by the events */ 1259 /* The record may be filtered by the events */
1406 if (!store->all_events) { 1260 if (!store->all_events) {
1407 event_id = pevent_data_type(pevent, record); 1261 int ret;
1408 if (last_event_id != event_id) { 1262 ret = pevent_filter_match(store->event_filter,
1409 /* optimize: only search event when new */ 1263 record);
1410 event = pevent_find_event(pevent, event_id); 1264 if (ret != FILTER_MATCH) {
1411 g_assert(event);
1412 }
1413 last_event_id = event_id;
1414 if (!trace_view_store_system_enabled(store, event->system) &&
1415 !trace_view_store_event_enabled(store, event_id)) {
1416 store->cpu_list[cpu][i].visible = 0; 1265 store->cpu_list[cpu][i].visible = 0;
1417 goto skip; 1266 goto skip;
1418 } 1267 }
diff --git a/trace-view-store.h b/trace-view-store.h
index 5a57cd9..ac907e0 100644
--- a/trace-view-store.h
+++ b/trace-view-store.h
@@ -117,10 +117,7 @@ struct trace_view_store
117 /* filters */ 117 /* filters */
118 gint all_events; /* set 1 when all events are enabled */ 118 gint all_events; /* set 1 when all events are enabled */
119 /* else */ 119 /* else */
120 gchar **systems; /* sorted list of systems that are enabled */ 120 struct event_filter *event_filter; /* Filtered events */
121 gint *event_types; /* sorted list of events that are enabled */
122 gint systems_size; /* size of systems array */
123 gint event_types_size; /* size of event_types array */
124 struct filter_task *task_filter; /* hash of tasks to filter on */ 121 struct filter_task *task_filter; /* hash of tasks to filter on */
125 struct filter_task *hide_tasks; /* hash of tasks to not display */ 122 struct filter_task *hide_tasks; /* hash of tasks to not display */
126 123
@@ -157,16 +154,10 @@ TraceViewRecord *trace_view_store_get_row(TraceViewStore *store, gint row);
157 154
158TraceViewRecord *trace_view_store_get_visible_row(TraceViewStore *store, gint row); 155TraceViewRecord *trace_view_store_get_visible_row(TraceViewStore *store, gint row);
159 156
160gboolean trace_view_store_system_enabled(TraceViewStore *store, const gchar *system);
161
162gboolean trace_view_store_event_enabled(TraceViewStore *store, gint event_id); 157gboolean trace_view_store_event_enabled(TraceViewStore *store, gint event_id);
163 158
164void trace_view_store_set_all_events_enabled(TraceViewStore *store); 159void trace_view_store_set_all_events_enabled(TraceViewStore *store);
165 160
166void trace_view_store_set_system_enabled(TraceViewStore *store, const gchar *system);
167
168void trace_view_store_set_event_enabled(TraceViewStore *store, gint event_id);
169
170void trace_view_store_clear_all_events_enabled(TraceViewStore *store); 161void trace_view_store_clear_all_events_enabled(TraceViewStore *store);
171 162
172void trace_view_store_update_filter(TraceViewStore *store); 163void trace_view_store_update_filter(TraceViewStore *store);
@@ -249,16 +240,10 @@ static inline gboolean trace_view_store_get_all_events_enabled(TraceViewStore *s
249 return store->all_events; 240 return store->all_events;
250} 241}
251 242
252static inline gchar **trace_view_store_get_systems_enabled(TraceViewStore *store) 243static inline struct event_filter *
253{ 244trace_view_store_get_event_filter(TraceViewStore *store)
254 g_return_val_if_fail (TRACE_VIEW_IS_LIST (store), NULL);
255 return store->systems;
256}
257
258static inline gint *trace_view_store_get_events_enabled(TraceViewStore *store)
259{ 245{
260 g_return_val_if_fail (TRACE_VIEW_IS_LIST (store), NULL); 246 g_return_val_if_fail (TRACE_VIEW_IS_LIST (store), FALSE);
261 return store->event_types; 247 return store->event_filter;
262} 248}
263
264#endif /* _trace_view_store_h_included_ */ 249#endif /* _trace_view_store_h_included_ */
diff --git a/trace-view.c b/trace-view.c
index 75605a5..5de5f51 100644
--- a/trace-view.c
+++ b/trace-view.c
@@ -384,13 +384,13 @@ void trace_view_event_filter_callback(gboolean accept,
384 gint *events, 384 gint *events,
385 gpointer data) 385 gpointer data)
386{ 386{
387 struct event_filter *event_filter;
387 GtkTreeView *trace_tree = data; 388 GtkTreeView *trace_tree = data;
388 GtkTreeModel *model; 389 GtkTreeModel *model;
389 TraceViewStore *store; 390 TraceViewStore *store;
390 TraceViewRecord *vrec; 391 TraceViewRecord *vrec;
391 guint64 time; 392 guint64 time;
392 gint row; 393 gint row;
393 gint i;
394 394
395 if (!accept) 395 if (!accept)
396 return; 396 return;
@@ -409,15 +409,9 @@ void trace_view_event_filter_callback(gboolean accept,
409 } else { 409 } else {
410 trace_view_store_clear_all_events_enabled(store); 410 trace_view_store_clear_all_events_enabled(store);
411 411
412 if (systems) { 412 event_filter = trace_view_store_get_event_filter(store);
413 for (i = 0; systems[i]; i++)
414 trace_view_store_set_system_enabled(store, systems[i]);
415 }
416 413
417 if (events) { 414 trace_filter_convert_char_to_filter(event_filter, systems, events);
418 for (i = 0; events[i] >= 0; i++)
419 trace_view_store_set_event_enabled(store, events[i]);
420 }
421 } 415 }
422 416
423 /* Keep track of the currently selected row */ 417 /* Keep track of the currently selected row */