aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung@kernel.org>2015-11-09 00:45:45 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-11-19 11:19:25 -0500
commit3cd99dfd1c87067fb28a19fee76500aed56d7c8f (patch)
treed6755e80449d4c8da9d2ed7bece23c829b92651c /tools/perf
parent8c430a34869946f1f5852f02d910ceef80040be5 (diff)
perf ui/gtk: Support flat callchains
The flat callchain mode is to print all chains in a simple flat hierarchy so make it easy to see. Currently perf report --gtk doesn't show flat callchains properly. With flat callchains, only leaf nodes are added to the final rbtree so it should show entries in parent nodes. To do that, add parent_val list to struct callchain_node and show them along with the (normal) val list. See the previous commit on TUI support for more information. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Tested-by: Brendan Gregg <brendan.d.gregg@gmail.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Kan Liang <kan.liang@intel.com> Cc: Pekka Enberg <penberg@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1447047946-1691-10-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/ui/gtk/hists.c80
1 files changed, 76 insertions, 4 deletions
diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c
index cff7bb9d9632..0b24cd6d38a4 100644
--- a/tools/perf/ui/gtk/hists.c
+++ b/tools/perf/ui/gtk/hists.c
@@ -89,8 +89,71 @@ void perf_gtk__init_hpp(void)
89 perf_gtk__hpp_color_overhead_acc; 89 perf_gtk__hpp_color_overhead_acc;
90} 90}
91 91
92static void perf_gtk__add_callchain(struct rb_root *root, GtkTreeStore *store, 92static void perf_gtk__add_callchain_flat(struct rb_root *root, GtkTreeStore *store,
93 GtkTreeIter *parent, int col, u64 total) 93 GtkTreeIter *parent, int col, u64 total)
94{
95 struct rb_node *nd;
96 bool has_single_node = (rb_first(root) == rb_last(root));
97
98 for (nd = rb_first(root); nd; nd = rb_next(nd)) {
99 struct callchain_node *node;
100 struct callchain_list *chain;
101 GtkTreeIter iter, new_parent;
102 bool need_new_parent;
103
104 node = rb_entry(nd, struct callchain_node, rb_node);
105
106 new_parent = *parent;
107 need_new_parent = !has_single_node;
108
109 callchain_node__make_parent_list(node);
110
111 list_for_each_entry(chain, &node->parent_val, list) {
112 char buf[128];
113
114 gtk_tree_store_append(store, &iter, &new_parent);
115
116 callchain_node__scnprintf_value(node, buf, sizeof(buf), total);
117 gtk_tree_store_set(store, &iter, 0, buf, -1);
118
119 callchain_list__sym_name(chain, buf, sizeof(buf), false);
120 gtk_tree_store_set(store, &iter, col, buf, -1);
121
122 if (need_new_parent) {
123 /*
124 * Only show the top-most symbol in a callchain
125 * if it's not the only callchain.
126 */
127 new_parent = iter;
128 need_new_parent = false;
129 }
130 }
131
132 list_for_each_entry(chain, &node->val, list) {
133 char buf[128];
134
135 gtk_tree_store_append(store, &iter, &new_parent);
136
137 callchain_node__scnprintf_value(node, buf, sizeof(buf), total);
138 gtk_tree_store_set(store, &iter, 0, buf, -1);
139
140 callchain_list__sym_name(chain, buf, sizeof(buf), false);
141 gtk_tree_store_set(store, &iter, col, buf, -1);
142
143 if (need_new_parent) {
144 /*
145 * Only show the top-most symbol in a callchain
146 * if it's not the only callchain.
147 */
148 new_parent = iter;
149 need_new_parent = false;
150 }
151 }
152 }
153}
154
155static void perf_gtk__add_callchain_graph(struct rb_root *root, GtkTreeStore *store,
156 GtkTreeIter *parent, int col, u64 total)
94{ 157{
95 struct rb_node *nd; 158 struct rb_node *nd;
96 bool has_single_node = (rb_first(root) == rb_last(root)); 159 bool has_single_node = (rb_first(root) == rb_last(root));
@@ -134,11 +197,20 @@ static void perf_gtk__add_callchain(struct rb_root *root, GtkTreeStore *store,
134 child_total = total; 197 child_total = total;
135 198
136 /* Now 'iter' contains info of the last callchain_list */ 199 /* Now 'iter' contains info of the last callchain_list */
137 perf_gtk__add_callchain(&node->rb_root, store, &iter, col, 200 perf_gtk__add_callchain_graph(&node->rb_root, store, &iter, col,
138 child_total); 201 child_total);
139 } 202 }
140} 203}
141 204
205static void perf_gtk__add_callchain(struct rb_root *root, GtkTreeStore *store,
206 GtkTreeIter *parent, int col, u64 total)
207{
208 if (callchain_param.mode == CHAIN_FLAT)
209 perf_gtk__add_callchain_flat(root, store, parent, col, total);
210 else
211 perf_gtk__add_callchain_graph(root, store, parent, col, total);
212}
213
142static void on_row_activated(GtkTreeView *view, GtkTreePath *path, 214static void on_row_activated(GtkTreeView *view, GtkTreePath *path,
143 GtkTreeViewColumn *col __maybe_unused, 215 GtkTreeViewColumn *col __maybe_unused,
144 gpointer user_data __maybe_unused) 216 gpointer user_data __maybe_unused)