aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile10
-rw-r--r--kernel-shark.c285
-rw-r--r--kernel-shark.h12
-rw-r--r--trace-view-store.c8
4 files changed, 308 insertions, 7 deletions
diff --git a/Makefile b/Makefile
index 0d81f17..9975f2f 100644
--- a/Makefile
+++ b/Makefile
@@ -19,7 +19,7 @@ CFLAGS = -g -Wall $(CONFIG_FLAGS)
19 $(CC) -c $(CFLAGS) $(EXT) $(INCLUDES) $< -o $@ 19 $(CC) -c $(CFLAGS) $(EXT) $(INCLUDES) $< -o $@
20 20
21TARGETS = libparsevent.a libtracecmd.a trace-cmd plugin_hrtimer.so plugin_mac80211.so \ 21TARGETS = libparsevent.a libtracecmd.a trace-cmd plugin_hrtimer.so plugin_mac80211.so \
22 plugin_sched_switch.so trace-graph trace-view 22 plugin_sched_switch.so trace-graph trace-view kernelshark
23 23
24all: $(TARGETS) 24all: $(TARGETS)
25 25
@@ -38,16 +38,22 @@ trace-view-main.o:: $(HEADERS) trace-view-store.h trace-view.h
38trace-filter.o:: $(HEADERS) 38trace-filter.o:: $(HEADERS)
39trace-graph.o:: $(HEADERS) trace-graph.h 39trace-graph.o:: $(HEADERS) trace-graph.h
40trace-graph-main.o:: $(HEADERS) trace-graph.h 40trace-graph-main.o:: $(HEADERS) trace-graph.h
41kernel-shark.o:: $(HEADERS)
42
43TRACE_VIEW_OBJS = trace-view.o trace-view-store.o trace-filter.o
41 44
42trace-cmd:: trace-cmd.o trace-read.o 45trace-cmd:: trace-cmd.o trace-read.o
43 $(CC) $^ -rdynamic -o $@ $(LIBS) 46 $(CC) $^ -rdynamic -o $@ $(LIBS)
44 47
45trace-view:: trace-view-main.o trace-view.o trace-view-store.o trace-filter.o 48trace-view:: trace-view-main.o $(TRACE_VIEW_OBJS)
46 $(CC) $^ -rdynamic -o $@ $(CONFIG_LIBS) $(LIBS) 49 $(CC) $^ -rdynamic -o $@ $(CONFIG_LIBS) $(LIBS)
47 50
48trace-graph:: trace-graph-main.o trace-graph.o trace-compat.o 51trace-graph:: trace-graph-main.o trace-graph.o trace-compat.o
49 $(CC) $^ -rdynamic -o $@ $(CONFIG_LIBS) $(LIBS) 52 $(CC) $^ -rdynamic -o $@ $(CONFIG_LIBS) $(LIBS)
50 53
54kernelshark:: kernel-shark.o trace-compat.o $(TRACE_VIEW_OBJS) trace-graph.o
55 $(CC) $^ -rdynamic -o $@ $(CONFIG_LIBS) $(LIBS)
56
51.PHONY: gtk_depends 57.PHONY: gtk_depends
52view_depends: 58view_depends:
53 @pkg-config --cflags $(PACKAGES) 59 @pkg-config --cflags $(PACKAGES)
diff --git a/kernel-shark.c b/kernel-shark.c
new file mode 100644
index 0000000..8fd16c9
--- /dev/null
+++ b/kernel-shark.c
@@ -0,0 +1,285 @@
1/*
2 * Copyright (C) 2009, Steven Rostedt <srostedt@redhat.com>
3 *
4 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License (not later!)
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20 */
21#include <stdio.h>
22#include <string.h>
23#include <stdarg.h>
24#include <fcntl.h>
25#include <unistd.h>
26#include <gtk/gtk.h>
27
28#include "trace-compat.h"
29#include "trace-cmd.h"
30#include "kernel-shark.h"
31
32#define version "0.1.1"
33
34#define TRACE_WIDTH 800
35#define TRACE_HEIGHT 600
36
37#define input_file "trace.dat"
38
39
40/* Callback for the clicked signal of the Exit button */
41static void
42exit_clicked (GtkWidget *widget, gpointer data)
43{
44 gtk_widget_destroy (GTK_WIDGET (data)); /* the user data points to the main window */
45 gtk_main_quit ();
46}
47
48/* Callback for the delete_event signal of the main application window */
49static gint
50delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
51{
52 gtk_widget_destroy (widget); /* destroy the main window */
53 gtk_main_quit ();
54 return TRUE;
55}
56
57/* Callback for the clicked signal of the Events filter button */
58static void
59events_clicked (gpointer data)
60{
61 struct shark_info *info = data;
62
63 trace_filter_event_dialog(info->treeview);
64}
65
66/* Callback for the clicked signal of the CPUs filter button */
67static void
68cpus_clicked (gpointer data)
69{
70 struct shark_info *info = data;
71
72 trace_filter_cpu_dialog(info->treeview);
73}
74
75void kernel_shark(int argc, char **argv)
76{
77 struct tracecmd_input *handle;
78 struct shark_info *info;
79 GtkWidget *window;
80 GtkWidget *vbox;
81 GtkWidget *hbox;
82 GtkWidget *menu_bar;
83 GtkWidget *menu;
84 GtkWidget *menu_item;
85 GtkWidget *sub_item;
86 GtkWidget *scrollwin;
87 GtkWidget *draw;
88 GtkWidget *label;
89 GtkWidget *spin;
90
91 info = g_new0(typeof(*info), 1);
92 if (!info)
93 die("Unable to allocate info");
94
95 handle = tracecmd_open(input_file);
96
97 if (!handle)
98 die("error reading header");
99
100 if (tracecmd_read_headers(handle) < 0)
101 return;
102
103 if (tracecmd_init_data(handle) < 0)
104 die("failed to init data");
105
106 gtk_init(&argc, &argv);
107
108 /* --- Main window --- */
109
110 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
111
112 /* --- Top Level Vbox --- */
113
114 vbox = gtk_vbox_new(FALSE, 0);
115 gtk_container_add(GTK_CONTAINER (window), vbox);
116 gtk_widget_show(vbox);
117
118 /* --- Menu Bar --- */
119
120 menu_bar = gtk_menu_bar_new();
121 gtk_box_pack_start(GTK_BOX (vbox), menu_bar, FALSE, FALSE, 0);
122 gtk_widget_show(menu_bar);
123
124 /* --- File Option --- */
125
126 menu_item = gtk_menu_item_new_with_label("File");
127 gtk_widget_show(menu_item);
128
129 gtk_menu_bar_append(GTK_MENU_BAR (menu_bar), menu_item);
130
131 menu = gtk_menu_new(); /* Don't need to show menus */
132
133
134 /* --- File - Quit Option --- */
135
136 sub_item = gtk_menu_item_new_with_label("Quit");
137
138 /* Add them to the menu */
139 gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item);
140
141 /* We can attach the Quit menu item to our exit function */
142 g_signal_connect_swapped (G_OBJECT (sub_item), "activate",
143 G_CALLBACK (exit_clicked),
144 (gpointer) window);
145
146 /* We do need to show menu items */
147 gtk_widget_show(sub_item);
148
149 gtk_menu_item_set_submenu(GTK_MENU_ITEM (menu_item), menu);
150
151 /* --- end File options --- */
152
153 /* --- Filter Option --- */
154
155 menu_item = gtk_menu_item_new_with_label("Filter");
156 gtk_widget_show(menu_item);
157
158 gtk_menu_bar_append(GTK_MENU_BAR (menu_bar), menu_item);
159
160 menu = gtk_menu_new(); /* Don't need to show menus */
161
162
163 /* --- Filter - Events Option --- */
164
165 sub_item = gtk_menu_item_new_with_label("events");
166
167 /* Add them to the menu */
168 gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item);
169
170 /* We can attach the Quit menu item to our exit function */
171 g_signal_connect_swapped (G_OBJECT (sub_item), "activate",
172 G_CALLBACK (events_clicked),
173 (gpointer) info);
174
175 /* We do need to show menu items */
176 gtk_widget_show(sub_item);
177
178
179 /* --- Filter - CPUs Option --- */
180
181 sub_item = gtk_menu_item_new_with_label("CPUs");
182
183 /* Add them to the menu */
184 gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item);
185
186 /* We can attach the Quit menu item to our exit function */
187 g_signal_connect_swapped (G_OBJECT (sub_item), "activate",
188 G_CALLBACK (cpus_clicked),
189 (gpointer) info);
190
191 /* We do need to show menu items */
192 gtk_widget_show(sub_item);
193
194
195 /* --- End Filter Options --- */
196 gtk_menu_item_set_submenu(GTK_MENU_ITEM (menu_item), menu);
197
198 /* --- Top Level Hbox --- */
199
200 hbox = gtk_hbox_new(FALSE, 0);
201 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
202 gtk_widget_show(hbox);
203
204 /* --- Scroll Window --- */
205 scrollwin = gtk_scrolled_window_new(NULL, NULL);
206 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
207 GTK_POLICY_AUTOMATIC,
208 GTK_POLICY_AUTOMATIC);
209 gtk_box_pack_start(GTK_BOX (hbox), scrollwin, TRUE, TRUE, 0);
210 gtk_widget_show(scrollwin);
211
212 /* --- Set up Drawing --- */
213
214 info->ginfo = trace_graph_create(handle, GTK_SCROLLED_WINDOW(scrollwin));
215 draw = trace_graph_get_draw(info->ginfo);
216
217 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrollwin),
218 draw);
219 gtk_widget_show(draw);
220
221
222
223 /* --- Paging Hbox --- */
224
225 hbox = gtk_hbox_new(FALSE, 0);
226 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
227 gtk_widget_show(hbox);
228
229 /* --- Page Spin Button --- */
230
231 label = gtk_label_new("Page");
232 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
233 gtk_widget_show(label);
234
235 spin = gtk_spin_button_new(NULL, 1.0, 0);
236 gtk_spin_button_set_range(GTK_SPIN_BUTTON(spin), 1, 1);
237 gtk_box_pack_start(GTK_BOX(hbox), spin, FALSE, FALSE, 0);
238 gtk_widget_show(spin);
239
240 /* --- Top Level Trace View Paging Hbox --- */
241
242 hbox = gtk_hbox_new(FALSE, 0);
243 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
244 gtk_widget_show(hbox);
245
246 /* --- Scroll Window --- */
247 scrollwin = gtk_scrolled_window_new(NULL, NULL);
248 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
249 GTK_POLICY_AUTOMATIC,
250 GTK_POLICY_AUTOMATIC);
251 gtk_box_pack_start(GTK_BOX (hbox), scrollwin, TRUE, TRUE, 0);
252 gtk_widget_show(scrollwin);
253
254 /* --- Set up Trace Tree --- */
255
256 info->treeview = gtk_tree_view_new();
257
258 trace_view_load(info->treeview, handle, spin);
259
260 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrollwin),
261 info->treeview);
262 gtk_widget_show(info->treeview);
263
264
265 /**********************************************
266 * Main Window
267 **********************************************/
268
269 /* Connect to the delete_event signal and Run the application */
270
271 gtk_signal_connect (GTK_OBJECT (window), "delete_event",
272 (GtkSignalFunc) delete_event,
273 NULL);
274
275 gtk_widget_set_size_request(window, TRACE_WIDTH, TRACE_HEIGHT);
276
277 gtk_widget_show (window);
278 gtk_main ();
279}
280
281int main(int argc, char **argv)
282{
283 kernel_shark(argc, argv);
284 return 0;
285}
diff --git a/kernel-shark.h b/kernel-shark.h
new file mode 100644
index 0000000..58761b0
--- /dev/null
+++ b/kernel-shark.h
@@ -0,0 +1,12 @@
1#ifndef _KERNEL_SHARK_H
2#define _KERNEL_SHARK_H
3
4#include "trace-graph.h"
5#include "trace-view.h"
6
7struct shark_info {
8 struct graph_info *ginfo;
9 GtkWidget *treeview;
10};
11
12#endif /* _KERNEL_SHARK_H */
diff --git a/trace-view-store.c b/trace-view-store.c
index f26351a..4c96336 100644
--- a/trace-view-store.c
+++ b/trace-view-store.c
@@ -854,11 +854,8 @@ trace_view_store_new (struct tracecmd_input *handle)
854 list = NULL; 854 list = NULL;
855 next = &list; 855 next = &list;
856 856
857 for (;;) { 857 data = tracecmd_read_cpu_first(handle, cpu);
858 data = tracecmd_read_data(handle, cpu); 858 while (data) {
859 if (!data)
860 break;
861
862 *next = rec = g_malloc(sizeof(*rec)); 859 *next = rec = g_malloc(sizeof(*rec));
863 g_assert(rec != NULL); 860 g_assert(rec != NULL);
864 rec->offset = data->offset; 861 rec->offset = data->offset;
@@ -867,6 +864,7 @@ trace_view_store_new (struct tracecmd_input *handle)
867 next = &rec->next; 864 next = &rec->next;
868 free(data); 865 free(data);
869 count++; 866 count++;
867 data = tracecmd_read_data(handle, cpu);
870 } 868 }
871 869
872 if (count) { 870 if (count) {