diff options
author | Steven Rostedt <srostedt@redhat.com> | 2010-02-16 21:38:20 -0500 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2010-02-16 21:38:20 -0500 |
commit | ad813ef9fb16cf4510be274a04dfb37c9fadf6e3 (patch) | |
tree | aff765f316121d6623c27d1578d921d0485480ac | |
parent | 2f9d0898a306b35bed28eb1b455db7a69f058b5b (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.c | 31 | ||||
-rw-r--r-- | trace-filter.c | 130 | ||||
-rw-r--r-- | trace-filter.h | 7 | ||||
-rw-r--r-- | trace-graph-main.c | 6 | ||||
-rw-r--r-- | trace-graph.c | 110 | ||||
-rw-r--r-- | trace-graph.h | 5 | ||||
-rw-r--r-- | trace-view-main.c | 9 | ||||
-rw-r--r-- | trace-view-store.c | 165 | ||||
-rw-r--r-- | trace-view-store.h | 25 | ||||
-rw-r--r-- | trace-view.c | 12 |
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 | |||
192 | list_events_clicked (gpointer data) | 192 | list_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 | ||
217 | static void | 222 | static 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 | ||
235 | static void | 241 | static void |
236 | sync_graph_events_to_list_clicked (gpointer data) | 242 | sync_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 | */ |
591 | void trace_filter_event_dialog(struct tracecmd_input *handle, | 591 | void 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 | |||
886 | static 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 | |||
902 | static 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 | */ | ||
932 | void 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 | */ | ||
989 | void 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 | ||
57 | void trace_filter_convert_filter_to_names(struct event_filter *filter, | ||
58 | gchar ***systems, | ||
59 | gint **events); | ||
60 | |||
61 | void 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 | ||
117 | void trace_graph(int argc, char **argv) | 119 | void 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 | ||
181 | gboolean 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 | |||
197 | gboolean 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 | |||
213 | gboolean trace_graph_filter_on_event(struct graph_info *ginfo, struct record *record) | 181 | gboolean 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 | ||
238 | gboolean trace_graph_filter_on_task(struct graph_info *ginfo, gint pid) | 195 | gboolean 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 | ||
1769 | static 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 | |||
1784 | static 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 | |||
1791 | void trace_graph_event_filter_callback(gboolean accept, | 1726 | void 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) | |||
2040 | void trace_graph_free_info(struct graph_info *ginfo) | 1945 | void 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 | |||
99 | events_clicked (gpointer data) | 99 | events_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 | ||
523 | gboolean 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 | |||
541 | gboolean 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 | |||
562 | static void clear_all_events(TraceViewStore *store) | 524 | static 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 | ||
580 | void trace_view_store_clear_all_events_enabled(TraceViewStore *store) | 529 | void 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 | ||
605 | static 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 | |||
626 | void 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 | |||
657 | void 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, | |||
1361 | static void update_filter_tasks(TraceViewStore *store) | 1218 | static 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 | ||
158 | TraceViewRecord *trace_view_store_get_visible_row(TraceViewStore *store, gint row); | 155 | TraceViewRecord *trace_view_store_get_visible_row(TraceViewStore *store, gint row); |
159 | 156 | ||
160 | gboolean trace_view_store_system_enabled(TraceViewStore *store, const gchar *system); | ||
161 | |||
162 | gboolean trace_view_store_event_enabled(TraceViewStore *store, gint event_id); | 157 | gboolean trace_view_store_event_enabled(TraceViewStore *store, gint event_id); |
163 | 158 | ||
164 | void trace_view_store_set_all_events_enabled(TraceViewStore *store); | 159 | void trace_view_store_set_all_events_enabled(TraceViewStore *store); |
165 | 160 | ||
166 | void trace_view_store_set_system_enabled(TraceViewStore *store, const gchar *system); | ||
167 | |||
168 | void trace_view_store_set_event_enabled(TraceViewStore *store, gint event_id); | ||
169 | |||
170 | void trace_view_store_clear_all_events_enabled(TraceViewStore *store); | 161 | void trace_view_store_clear_all_events_enabled(TraceViewStore *store); |
171 | 162 | ||
172 | void trace_view_store_update_filter(TraceViewStore *store); | 163 | void 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 | ||
252 | static inline gchar **trace_view_store_get_systems_enabled(TraceViewStore *store) | 243 | static inline struct event_filter * |
253 | { | 244 | trace_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 | |||
258 | static 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 */ |