aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2010-06-10 10:15:15 -0400
committerSteven Rostedt <rostedt@goodmis.org>2010-06-10 10:15:15 -0400
commit200cb94dd4a1f1f47c86a82c1dc665a67f426214 (patch)
treeff4c473da5835684cf9407506924b5cedf0266c1
parent77441ff111de0fb54e4d00df57532333915be2e9 (diff)
kernelshark: Add list and graph task filter menu
Add a list and graph task filter menu to the menu bar. The tasks added to this filter are enabled by default. This also adds a nice feature that you can pick and choose tasks to filter from a dialog box. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--kernel-shark.c208
-rw-r--r--kernel-shark.h2
-rw-r--r--trace-graph.c9
3 files changed, 198 insertions, 21 deletions
diff --git a/kernel-shark.c b/kernel-shark.c
index e591657..7b13bdc 100644
--- a/kernel-shark.c
+++ b/kernel-shark.c
@@ -126,6 +126,23 @@ static int trace_sync_select_menu(const gchar *title,
126 return result; 126 return result;
127} 127}
128 128
129static void update_tree_view_filters(struct shark_info *info,
130 struct filter_task *task_filter,
131 struct filter_task *hide_tasks)
132{
133 if (info->list_filter_enabled)
134 trace_view_update_filters(info->treeview,
135 task_filter, hide_tasks);
136
137 if (filter_task_count(task_filter) ||
138 filter_task_count(hide_tasks))
139 info->list_filter_available = 1;
140 else {
141 info->list_filter_enabled = 0;
142 info->list_filter_available = 0;
143 }
144}
145
129/* graph callbacks */ 146/* graph callbacks */
130 147
131/* convert_nano() and print_time() are copied from trace-graph.c for debugging 148/* convert_nano() and print_time() are copied from trace-graph.c for debugging
@@ -178,17 +195,7 @@ static void ks_graph_filter(struct graph_info *ginfo,
178 if (!info->sync_task_filters) 195 if (!info->sync_task_filters)
179 return; 196 return;
180 197
181 if (info->list_filter_enabled) 198 update_tree_view_filters(info, task_filter, hide_tasks);
182 trace_view_update_filters(info->treeview,
183 task_filter, hide_tasks);
184
185 if (filter_task_count(task_filter) ||
186 filter_task_count(hide_tasks))
187 info->list_filter_available = 1;
188 else {
189 info->list_filter_enabled = 0;
190 info->list_filter_available = 0;
191 }
192} 199}
193 200
194static void free_info(struct shark_info *info) 201static void free_info(struct shark_info *info)
@@ -342,6 +349,10 @@ sync_task_filter_clicked (GtkWidget *subitem, gpointer data)
342 gtk_menu_item_set_label(GTK_MENU_ITEM(info->task_sync_menu), 349 gtk_menu_item_set_label(GTK_MENU_ITEM(info->task_sync_menu),
343 "Sync Graph and List Task Filters"); 350 "Sync Graph and List Task Filters");
344 351
352 gtk_menu_item_set_label(GTK_MENU_ITEM(info->graph_task_menu),
353 "graph task filter");
354 gtk_widget_show(info->list_task_menu);
355
345 /* The list now uses its own hash */ 356 /* The list now uses its own hash */
346 info->list_task_filter = filter_task_hash_copy(info->ginfo->task_filter); 357 info->list_task_filter = filter_task_hash_copy(info->ginfo->task_filter);
347 info->list_hide_tasks = filter_task_hash_copy(info->ginfo->hide_tasks); 358 info->list_hide_tasks = filter_task_hash_copy(info->ginfo->hide_tasks);
@@ -375,16 +386,7 @@ sync_task_filter_clicked (GtkWidget *subitem, gpointer data)
375 info->list_hide_tasks = filter_task_hash_copy(hide_tasks); 386 info->list_hide_tasks = filter_task_hash_copy(hide_tasks);
376 } 387 }
377 388
378 if (info->list_filter_enabled) 389 update_tree_view_filters(info, task_filter, hide_tasks);
379 trace_view_update_filters(info->treeview,
380 task_filter, hide_tasks);
381
382 if (!filter_task_count(task_filter) &&
383 !filter_task_count(hide_tasks)) {
384 info->list_filter_enabled = 0;
385 info->list_filter_available = 0;
386 } else
387 info->list_filter_available = 1;
388 390
389 break; 391 break;
390 case 1: 392 case 1:
@@ -409,7 +411,136 @@ sync_task_filter_clicked (GtkWidget *subitem, gpointer data)
409 info->sync_task_filters = 1; 411 info->sync_task_filters = 1;
410 gtk_menu_item_set_label(GTK_MENU_ITEM(info->task_sync_menu), 412 gtk_menu_item_set_label(GTK_MENU_ITEM(info->task_sync_menu),
411 "Unsync Graph and List Task Filters"); 413 "Unsync Graph and List Task Filters");
414 gtk_menu_item_set_label(GTK_MENU_ITEM(info->graph_task_menu),
415 "task filter");
416 gtk_widget_hide(info->list_task_menu);
417 }
418}
419
420static void filter_list_enable_clicked (gpointer data);
421
422static void
423update_list_task_filter_callback(gboolean accept,
424 gint *selected,
425 gint *non_select,
426 gpointer data)
427{
428 struct shark_info *info = data;
429 GtkTreeView *trace_tree = GTK_TREE_VIEW(info->treeview);
430 GtkTreeModel *model;
431 TraceViewStore *store;
432 int i;
433
434 if (!accept)
435 return;
436
437 model = gtk_tree_view_get_model(trace_tree);
438 if (!model)
439 return;
440
441 store = TRACE_VIEW_STORE(model);
442
443 filter_task_clear(info->list_task_filter);
444
445 if (selected) {
446 for (i = 0; selected[i] >= 0; i++)
447 filter_task_add_pid(info->list_task_filter, selected[i]);
412 } 448 }
449
450 update_tree_view_filters(info, info->list_task_filter, info->list_hide_tasks);
451
452 /*
453 * The menu filters always enable the filters.
454 */
455 if (info->list_filter_available && !info->list_filter_enabled)
456 filter_list_enable_clicked(info);
457}
458
459/* Callback for the clicked signal of the List Tasks filter button */
460static void
461list_tasks_clicked (gpointer data)
462{
463 struct shark_info *info = data;
464 GtkTreeView *trace_tree = GTK_TREE_VIEW(info->treeview);
465 struct graph_info *ginfo = info->ginfo;
466 GtkTreeModel *model;
467 TraceViewStore *store;
468 gint *selected;
469 gint *tasks;
470
471 if (!ginfo->handle)
472 return;
473
474 model = gtk_tree_view_get_model(trace_tree);
475 if (!model)
476 return;
477
478 store = TRACE_VIEW_STORE(model);
479
480 tasks = trace_graph_task_list(ginfo);
481 selected = filter_task_pids(info->list_task_filter);
482
483 trace_task_dialog(info->handle, tasks, selected,
484 update_list_task_filter_callback, info);
485
486 free(tasks);
487 free(selected);
488}
489
490static void
491update_graph_task_filter_callback(gboolean accept,
492 gint *selected,
493 gint *non_select,
494 gpointer data)
495{
496 struct shark_info *info = data;
497 struct graph_info *ginfo = info->ginfo;
498 int i;
499
500 if (!accept)
501 return;
502
503 filter_task_clear(ginfo->task_filter);
504
505 if (selected) {
506 for (i = 0; selected[i] >= 0; i++)
507 filter_task_add_pid(ginfo->task_filter, selected[i]);
508 }
509
510 trace_graph_refresh_filters(ginfo);
511
512 /*
513 * The menu filters always enable the filters.
514 */
515 if (ginfo->filter_available) {
516 if (!ginfo->filter_enabled)
517 trace_graph_filter_toggle(info->ginfo);
518
519 if (info->sync_task_filters && !info->list_filter_enabled)
520 filter_list_enable_clicked(info);
521 }
522}
523
524/* Callback for the clicked signal of the Tasks filter button */
525static void
526graph_tasks_clicked (gpointer data)
527{
528 struct shark_info *info = data;
529 struct graph_info *ginfo = info->ginfo;
530 gint *selected;
531 gint *tasks;
532
533 if (!ginfo->handle)
534 return;
535
536 tasks = trace_graph_task_list(ginfo);
537 selected = filter_task_pids(ginfo->task_filter);
538
539 trace_task_dialog(ginfo->handle, tasks, selected,
540 update_graph_task_filter_callback, info);
541
542 free(tasks);
543 free(selected);
413} 544}
414 545
415/* Callback for the clicked signal of the Events filter button */ 546/* Callback for the clicked signal of the Events filter button */
@@ -1247,6 +1378,41 @@ void kernel_shark(int argc, char **argv)
1247 gtk_widget_show(sub_item); 1378 gtk_widget_show(sub_item);
1248 1379
1249 1380
1381 /* --- Filter - List Tasks Option --- */
1382
1383 sub_item = gtk_menu_item_new_with_label("list task filter");
1384
1385 /* Add them to the menu */
1386 gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item);
1387
1388 /* We can attach the Quit menu item to our exit function */
1389 g_signal_connect_swapped (G_OBJECT (sub_item), "activate",
1390 G_CALLBACK (list_tasks_clicked),
1391 (gpointer) info);
1392
1393 info->list_task_menu = sub_item;
1394
1395 /* Only show this item when list and graph tasks are not synced */
1396
1397
1398 /* --- Filter - Graph Tasks Option --- */
1399
1400 sub_item = gtk_menu_item_new_with_label("task filter");
1401
1402 /* Add them to the menu */
1403 gtk_menu_shell_append(GTK_MENU_SHELL (menu), sub_item);
1404
1405 /* We can attach the Quit menu item to our exit function */
1406 g_signal_connect_swapped (G_OBJECT (sub_item), "activate",
1407 G_CALLBACK (graph_tasks_clicked),
1408 (gpointer) info);
1409
1410 info->graph_task_menu = sub_item;
1411
1412 /* We do need to show menu items */
1413 gtk_widget_show(sub_item);
1414
1415
1250 /* --- Filter - List Events Option --- */ 1416 /* --- Filter - List Events Option --- */
1251 1417
1252 sub_item = gtk_menu_item_new_with_label("list events"); 1418 sub_item = gtk_menu_item_new_with_label("list events");
diff --git a/kernel-shark.h b/kernel-shark.h
index f931406..d537332 100644
--- a/kernel-shark.h
+++ b/kernel-shark.h
@@ -31,6 +31,8 @@ struct shark_info {
31 GtkWidget *treeview; 31 GtkWidget *treeview;
32 GtkWidget *spin; 32 GtkWidget *spin;
33 GtkWidget *task_sync_menu; 33 GtkWidget *task_sync_menu;
34 GtkWidget *list_task_menu;
35 GtkWidget *graph_task_menu;
34 struct graph_callbacks graph_cbs; 36 struct graph_callbacks graph_cbs;
35 gint selected_task; 37 gint selected_task;
36 gboolean list_filter_enabled; 38 gboolean list_filter_enabled;
diff --git a/trace-graph.c b/trace-graph.c
index 319b159..04e2439 100644
--- a/trace-graph.c
+++ b/trace-graph.c
@@ -569,6 +569,15 @@ void trace_graph_update_filters(struct graph_info *ginfo,
569 569
570 if (ginfo->filter_enabled) 570 if (ginfo->filter_enabled)
571 redraw_graph(ginfo); 571 redraw_graph(ginfo);
572
573 if (filter_task_count(ginfo->task_filter) ||
574 filter_task_count(ginfo->hide_tasks))
575 ginfo->filter_available = 1;
576 else {
577 ginfo->filter_enabled = 0;
578 ginfo->filter_available = 0;
579 }
580
572} 581}
573 582
574void trace_graph_refresh_filters(struct graph_info *ginfo) 583void trace_graph_refresh_filters(struct graph_info *ginfo)