aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-10-12 12:39:27 -0400
committerSteven Rostedt <rostedt@goodmis.org>2009-12-17 21:43:46 -0500
commitab91bd24b899d73d7552c5d1947656a3b446660e (patch)
tree7368767744c5af3d97c5f98e6d19b2ff2021feac
parentbed6e5c19bf745300dc045aa2242790cd6cc062b (diff)
Add GTK viewer for reading trace data
This is the start of adding a GTK front end to read the trace data. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--Makefile18
-rw-r--r--trace-cmd.c3
-rw-r--r--trace-local.h2
-rw-r--r--trace-view.c366
4 files changed, 385 insertions, 4 deletions
diff --git a/Makefile b/Makefile
index dbc79bf..848a6aa 100644
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,17 @@
1CC = gcc 1CC = gcc
2AR = ar 2AR = ar
3EXT = -std=gnu99 3EXT = -std=gnu99
4CFLAGS = -g -Wall # -O2
5INCLUDES = -I. -I/usr/local/include 4INCLUDES = -I. -I/usr/local/include
6 5
7LIBS = -L. -ltracecmd -ldl 6LIBS = -L. -ltracecmd -ldl
8 7
8PACKAGES= gtk+-2.0 libgnome-2.0 libgnomecanvas-2.0 libgnomeui-2.0 libxml-2.0
9
10CONFIG_FLAGS = $(shell pkg-config --cflags $(PACKAGES))
11CONFIG_LIBS = $(shell pkg-config --libs $(PACKAGES))
12
13CFLAGS = -g -Wall $(CONFIG_FLAGS)
14
9%.o: %.c 15%.o: %.c
10 $(CC) -c $(CFLAGS) $(EXT) $(INCLUDES) $< -o $@ 16 $(CC) -c $(CFLAGS) $(EXT) $(INCLUDES) $< -o $@
11 17
@@ -24,8 +30,14 @@ trace-util.o:: $(HEADERS)
24trace-ftrace.o:: $(HEADERS) 30trace-ftrace.o:: $(HEADERS)
25trace-input.o:: $(HEADERS) 31trace-input.o:: $(HEADERS)
26 32
27trace-cmd:: trace-cmd.o trace-read.o 33trace-cmd:: trace-cmd.o trace-read.o trace-view.o
28 $(CC) $^ $(LIBS) -rdynamic -o $@ 34 $(CC) $^ -rdynamic -o $@ $(CONFIG_LIBS) $(LIBS)
35
36.PHONY: view_depends
37view_depends:
38 @pkg-config --cflags $(PACKAGES)
39
40trace-view.o:: parse-events.h view_depends
29 41
30parse-events.o: parse-events.c parse-events.h 42parse-events.o: parse-events.c parse-events.h
31 $(CC) -c $(CFLAGS) $(EXT) $(INCLUDES) -fPIC $< -o $@ 43 $(CC) -c $(CFLAGS) $(EXT) $(INCLUDES) -fPIC $< -o $@
diff --git a/trace-cmd.c b/trace-cmd.c
index ac14a61..cfd8ba5 100644
--- a/trace-cmd.c
+++ b/trace-cmd.c
@@ -720,6 +720,9 @@ int main (int argc, char **argv)
720 if (strcmp(argv[1], "report") == 0) { 720 if (strcmp(argv[1], "report") == 0) {
721 trace_report(argc, argv); 721 trace_report(argc, argv);
722 exit(0); 722 exit(0);
723 } else if (strcmp(argv[1], "view") == 0) {
724 trace_view(argc, argv);
725 exit(0);
723 } else if ((record = (strcmp(argv[1], "record") == 0)) || 726 } else if ((record = (strcmp(argv[1], "record") == 0)) ||
724 (strcmp(argv[1], "start") == 0)) { 727 (strcmp(argv[1], "start") == 0)) {
725 728
diff --git a/trace-local.h b/trace-local.h
index 2fab032..4b3deff 100644
--- a/trace-local.h
+++ b/trace-local.h
@@ -11,6 +11,6 @@ struct tracecmd_input *read_trace_header(void);
11int read_trace_files(void); 11int read_trace_files(void);
12 12
13void trace_report(int argc, char **argv); 13void trace_report(int argc, char **argv);
14 14void trace_view(int argc, char **argv);
15 15
16#endif /* __TRACE_LOCAL_H */ 16#endif /* __TRACE_LOCAL_H */
diff --git a/trace-view.c b/trace-view.c
new file mode 100644
index 0000000..744f9a2
--- /dev/null
+++ b/trace-view.c
@@ -0,0 +1,366 @@
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 <gnome.h>
25
26#include "trace-cmd.h"
27#include "trace-local.h"
28
29#define version "0.1.1"
30
31enum {
32 COL_CPU,
33 COL_TS,
34 COL_COMM,
35 COL_PID,
36 COL_LAT,
37 COL_EVENT,
38 COL_INFO,
39 NUM_COLS
40};
41
42struct tracecmd_input *trace_handle;
43
44GtkWidget *trace_tree;
45
46static void add_data_to_model(GtkTreeModel *model,
47 struct tracecmd_input *handle,
48 int cpu)
49{
50 struct pevent *pevent;
51 GtkTreeIter iter;
52 struct record *record;
53 struct event *event;
54 struct trace_seq s;
55 struct trace_seq l;
56 unsigned long secs;
57 unsigned long usecs;
58 unsigned long nsecs;
59 const char *comm;
60 int pid, type;
61 char *print;
62 char buf[100];
63
64 pevent = tracecmd_get_pevent(handle);
65
66 record = tracecmd_read_data(handle, cpu);
67 nsecs = record->ts;
68
69 type = pevent_data_type(pevent, record->data);
70 event = pevent_data_event_from_type(pevent, type);
71 if (!event)
72 return;
73
74 pid = pevent_data_pid(pevent, record->data);
75 comm = pevent_data_comm_from_pid(pevent, pid);
76
77 trace_seq_init(&l);
78 pevent_data_lat_fmt(pevent, &l, record->data, record->size);
79 l.buffer[l.len] = 0;
80
81 trace_seq_init(&s);
82 pevent_event_info(&s, event, cpu, record->data, record->size, nsecs);
83 if (s.full) {
84 print = malloc(s.len + 1);
85 memcpy(print, s.buffer, s.len);
86 } else
87 print = s.buffer;
88 print[s.len] = 0;
89
90 secs = nsecs / NSECS_PER_SEC;
91 usecs = nsecs - secs * NSECS_PER_SEC;
92 usecs = usecs / NSECS_PER_USEC;
93
94 sprintf(buf, "%5lu.%06lu", secs, usecs);
95
96 gtk_list_store_append(GTK_LIST_STORE(model), &iter);
97 gtk_list_store_set(GTK_LIST_STORE(model), &iter,
98 COL_CPU, cpu,
99 COL_TS, buf,
100 COL_COMM, comm,
101 COL_PID, pid,
102 COL_LAT, l.buffer,
103 COL_EVENT, event->name,
104 COL_INFO, print,
105 -1);
106 if (s.full)
107 free(print);
108
109 free(record);
110}
111
112static void trace_load_tree(struct tracecmd_input *handle, GtkWidget *trace_tree)
113{
114 GtkTreeModel *model;
115 unsigned long long ts;
116 struct record *data;
117 int cpus;
118 int next;
119 int cpu;
120 int filter_cpu = -1; /* TODO */
121
122 cpus = tracecmd_cpus(handle);
123
124 model = gtk_tree_view_get_model(GTK_TREE_VIEW(trace_tree));
125 g_object_ref(model);
126 gtk_tree_view_set_model(GTK_TREE_VIEW(trace_tree), NULL);
127
128 do {
129 next = -1;
130 ts = 0;
131 if (filter_cpu >= 0) {
132 cpu = filter_cpu;
133 data = tracecmd_peek_data(handle, cpu);
134 if (data)
135 next = cpu;
136 } else {
137 for (cpu = 0; cpu < cpus; cpu++) {
138 data = tracecmd_peek_data(handle, cpu);
139 if (data && (!ts || data->ts < ts)) {
140 ts = data->ts;
141 next = cpu;
142 }
143 }
144 }
145 if (next >= 0)
146 add_data_to_model(model, handle, next);
147
148 } while (next >= 0);
149
150 gtk_tree_view_set_model(GTK_TREE_VIEW(trace_tree), model);
151 g_object_unref(model);
152}
153
154/* Callback for the clicked signal of the Exit button */
155static void
156exit_clicked (GtkWidget *widget, gpointer data)
157{
158 gtk_widget_destroy (GTK_WIDGET (data)); /* the user data points to the main window */
159 gtk_main_quit ();
160}
161
162/* Callback for the delete_event signal of the main application window */
163static gint
164delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
165{
166 gtk_widget_destroy (widget); /* destroy the main window */
167 gtk_main_quit ();
168 return TRUE;
169}
170
171static GtkTreeModel *
172create_trace_view_model(void)
173{
174 GtkListStore *store;
175
176 store = gtk_list_store_new(NUM_COLS,
177 G_TYPE_UINT,
178 G_TYPE_STRING,
179 G_TYPE_STRING,
180 G_TYPE_UINT,
181 G_TYPE_STRING,
182 G_TYPE_STRING,
183 G_TYPE_STRING);
184
185 return GTK_TREE_MODEL(store);
186}
187
188static GtkWidget *
189create_trace_view(void)
190{
191 GtkTreeViewColumn *col;
192 GtkCellRenderer *renderer;
193 GtkWidget *view;
194 GtkTreeModel *model;
195
196 view = gtk_tree_view_new();
197
198 /* --- CPU column --- */
199
200 col = gtk_tree_view_column_new();
201
202 renderer = gtk_cell_renderer_text_new();
203
204 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
205 -1,
206 "CPU",
207 renderer,
208 "text", COL_CPU,
209 NULL);
210
211 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
212 -1,
213 "Time Stamp",
214 renderer,
215 "text", COL_TS,
216 NULL);
217
218 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
219 -1,
220 "Task",
221 renderer,
222 "text", COL_COMM,
223 NULL);
224
225 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
226 -1,
227 "PID",
228 renderer,
229 "text", COL_PID,
230 NULL);
231
232 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
233 -1,
234 "Latency",
235 renderer,
236 "text", COL_LAT,
237 NULL);
238
239 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
240 -1,
241 "Event",
242 renderer,
243 "text", COL_EVENT,
244 NULL);
245
246 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
247 -1,
248 "Info",
249 renderer,
250 "text", COL_INFO,
251 NULL);
252
253 model = create_trace_view_model();
254
255 gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
256
257 g_object_unref(model); /* destroy model automatically with view */
258
259 return view;
260}
261
262void trace_view(int argc, char **argv)
263{
264 struct tracecmd_input *handle;
265 GtkWidget *window;
266 GtkWidget *vbox;
267 GtkWidget *hbox;
268 GtkWidget *menu_bar;
269 GtkWidget *menu;
270 GtkWidget *menu_item;
271 GtkWidget *quit_item;
272 GtkWidget *scrollwin;
273
274 handle = read_trace_header();
275 if (!handle)
276 die("error reading header");
277
278 if (tracecmd_read_headers(handle) < 0)
279 return;
280
281 if (tracecmd_init_data(handle) < 0)
282 die("failed to init data");
283
284 trace_handle = handle;
285
286 gnome_init("trace-cmd", version, argc, argv);
287
288 /* --- Main window --- */
289
290 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
291
292 /* --- Top Level Vbox --- */
293
294 vbox = gtk_vbox_new(FALSE, 0);
295 gtk_container_add(GTK_CONTAINER (window), vbox);
296 gtk_widget_show(vbox);
297
298 /* --- Menu Bar --- */
299
300 menu_bar = gtk_menu_bar_new();
301 gtk_box_pack_start(GTK_BOX (vbox), menu_bar, FALSE, FALSE, 0);
302 gtk_widget_show(menu_bar);
303
304 /* --- File Option --- */
305
306 menu_item = gtk_menu_item_new_with_label("File");
307 gtk_widget_show(menu_item);
308
309 gtk_menu_bar_append(GTK_MENU_BAR (menu_bar), menu_item);
310
311 menu = gtk_menu_new(); /* Don't need to show menus */
312
313
314 /* --- Quit Option --- */
315
316 quit_item = gtk_menu_item_new_with_label("Quit");
317
318 /* Add them to the menu */
319 gtk_menu_shell_append(GTK_MENU_SHELL (menu), quit_item);
320
321 /* We can attach the Quit menu item to our exit function */
322 g_signal_connect_swapped (G_OBJECT (quit_item), "activate",
323 G_CALLBACK (exit_clicked),
324 (gpointer) window);
325
326 /* We do need to show menu items */
327 gtk_widget_show(quit_item);
328
329
330 gtk_menu_item_set_submenu(GTK_MENU_ITEM (menu_item), menu);
331 /* --- Top Level Hbox --- */
332
333 hbox = gtk_hbox_new(FALSE, 0);
334 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
335 gtk_widget_show(hbox);
336
337 /* --- Scroll Window --- */
338 scrollwin = gtk_scrolled_window_new(NULL, NULL);
339 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin),
340 GTK_POLICY_AUTOMATIC,
341 GTK_POLICY_AUTOMATIC);
342 gtk_box_pack_start(GTK_BOX (hbox), scrollwin, TRUE, TRUE, 0);
343 gtk_widget_show(scrollwin);
344
345 /* --- Trace Tree --- */
346
347 trace_tree = create_trace_view();
348 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrollwin),
349 trace_tree);
350 gtk_widget_show(trace_tree);
351
352 trace_load_tree(handle, trace_tree);
353
354 /**********************************************
355 * Main Window
356 **********************************************/
357
358 /* Connect to the delete_event signal and Run the application */
359
360 gtk_signal_connect (GTK_OBJECT (window), "delete_event",
361 (GtkSignalFunc) delete_event,
362 NULL);
363
364 gtk_widget_show (window);
365 gtk_main ();
366}