aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/ui
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2011-10-05 18:16:15 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2011-10-07 15:56:44 -0400
commitab81f3fd350c510730adb1ca40ef55c2b2952121 (patch)
tree7b442d9592dd5666eb2cae6194962e545bd693a7 /tools/perf/util/ui
parent81cce8de9437be9234f651be1f03e596c1b1a79a (diff)
perf top: Reuse the 'report' hist_entry/hists classes
This actually fixes several problems we had in the old 'perf top': 1. Unresolved symbols not show, limitation that came from the old "KernelTop" codebase, to solve it we would need to do changes that would make sym_entry have most of the hist_entry fields. 2. It was using the number of samples, not the sum of sample->period. And brings the --sort code that allows us to have all the views in 'perf report', for instance: [root@emilia ~]# perf top --sort dso PerfTop: 5903 irqs/sec kernel:77.5% exact: 0.0% [1000Hz cycles], (all, 8 CPUs) ------------------------------------------------------------------------------ 31.59% libcrypto.so.1.0.0 21.55% [kernel] 18.57% libpython2.6.so.1.0 7.04% libc-2.12.so 6.99% _backend_agg.so 4.72% sshd 1.48% multiarray.so 1.39% libfreetype.so.6.3.22 1.37% perf 0.71% libgobject-2.0.so.0.2200.5 0.53% [tg3] 0.48% libglib-2.0.so.0.2200.5 0.44% libstdc++.so.6.0.13 0.40% libcairo.so.2.10800.8 0.38% libm-2.12.so 0.34% umath.so 0.30% libgdk-x11-2.0.so.0.1800.9 0.22% libpthread-2.12.so 0.20% libgtk-x11-2.0.so.0.1800.9 0.20% librt-2.12.so 0.15% _path.so 0.13% libpango-1.0.so.0.2800.1 0.11% libatlas.so.3.0 0.09% ft2font.so 0.09% libpangoft2-1.0.so.0.2800.1 0.08% libX11.so.6.3.0 0.07% [vdso] 0.06% cyclictest ^C All the filter lists can be used as well: --dsos, --comms, --symbols, etc. The 'perf report' TUI is also reused, being possible to apply all the zoom operations, do annotation, etc. This change will allow multiple simplifications in the symbol system as well, that will be detailed in upcoming changesets. Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-xzaaldxq7zhqrrxdxjifk1mh@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/ui')
-rw-r--r--tools/perf/util/ui/browsers/top.c236
1 files changed, 0 insertions, 236 deletions
diff --git a/tools/perf/util/ui/browsers/top.c b/tools/perf/util/ui/browsers/top.c
deleted file mode 100644
index d43875b2356f..000000000000
--- a/tools/perf/util/ui/browsers/top.c
+++ /dev/null
@@ -1,236 +0,0 @@
1/*
2 * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
3 *
4 * Parts came from builtin-{top,stat,record}.c, see those files for further
5 * copyright notes.
6 *
7 * Released under the GPL v2. (and only v2, not any later version)
8 */
9#include "../browser.h"
10#include "../../annotate.h"
11#include "../helpline.h"
12#include "../libslang.h"
13#include "../util.h"
14#include "../ui.h"
15#include "../../evlist.h"
16#include "../../hist.h"
17#include "../../sort.h"
18#include "../../symbol.h"
19#include "../../session.h"
20#include "../../top.h"
21
22struct perf_top_browser {
23 struct ui_browser b;
24 struct rb_root root;
25 struct sym_entry *selection;
26 float sum_ksamples;
27 int dso_width;
28 int dso_short_width;
29 int sym_width;
30};
31
32static void perf_top_browser__write(struct ui_browser *browser, void *entry, int row)
33{
34 struct perf_top_browser *top_browser = container_of(browser, struct perf_top_browser, b);
35 struct sym_entry *syme = rb_entry(entry, struct sym_entry, rb_node);
36 bool current_entry = ui_browser__is_current_entry(browser, row);
37 struct symbol *symbol = sym_entry__symbol(syme);
38 struct perf_top *top = browser->priv;
39 int width = browser->width;
40 double pcnt;
41
42 pcnt = 100.0 - (100.0 * ((top_browser->sum_ksamples - syme->snap_count) /
43 top_browser->sum_ksamples));
44 ui_browser__set_percent_color(browser, pcnt, current_entry);
45
46 if (top->evlist->nr_entries == 1 || !top->display_weighted) {
47 slsmg_printf("%20.2f ", syme->weight);
48 width -= 21;
49 } else {
50 slsmg_printf("%9.1f %10ld ", syme->weight, syme->snap_count);
51 width -= 20;
52 }
53
54 slsmg_printf("%4.1f%%", pcnt);
55 width -= 7;
56
57 if (verbose) {
58 slsmg_printf(" %016" PRIx64, symbol->start);
59 width -= 17;
60 }
61
62 slsmg_printf(" %-*.*s ", top_browser->sym_width, top_browser->sym_width,
63 symbol->name);
64 width -= top_browser->sym_width;
65 slsmg_write_nstring(width >= syme->map->dso->long_name_len ?
66 syme->map->dso->long_name :
67 syme->map->dso->short_name, width);
68
69 if (current_entry)
70 top_browser->selection = syme;
71}
72
73static void perf_top_browser__update_rb_tree(struct perf_top_browser *browser)
74{
75 struct perf_top *top = browser->b.priv;
76 u64 top_idx = browser->b.top_idx;
77
78 browser->root = RB_ROOT;
79 browser->b.top = NULL;
80 browser->sum_ksamples = perf_top__decay_samples(top, &browser->root);
81 /*
82 * No active symbols
83 */
84 if (top->rb_entries == 0)
85 return;
86
87 perf_top__find_widths(top, &browser->root, &browser->dso_width,
88 &browser->dso_short_width,
89 &browser->sym_width);
90 if (browser->sym_width + browser->dso_width > browser->b.width - 29) {
91 browser->dso_width = browser->dso_short_width;
92 if (browser->sym_width + browser->dso_width > browser->b.width - 29)
93 browser->sym_width = browser->b.width - browser->dso_width - 29;
94 }
95
96 /*
97 * Adjust the ui_browser indexes since the entries in the browser->root
98 * rb_tree may have changed, then seek it from start, so that we get a
99 * possible new top of the screen.
100 */
101 browser->b.nr_entries = top->rb_entries;
102
103 if (top_idx >= browser->b.nr_entries) {
104 if (browser->b.height >= browser->b.nr_entries)
105 top_idx = browser->b.nr_entries - browser->b.height;
106 else
107 top_idx = 0;
108 }
109
110 if (browser->b.index >= top_idx + browser->b.height)
111 browser->b.index = top_idx + browser->b.index - browser->b.top_idx;
112
113 if (browser->b.index >= browser->b.nr_entries)
114 browser->b.index = browser->b.nr_entries - 1;
115
116 browser->b.top_idx = top_idx;
117 browser->b.seek(&browser->b, top_idx, SEEK_SET);
118}
119
120static void perf_top_browser__annotate(struct perf_top_browser *browser)
121{
122 struct sym_entry *syme = browser->selection;
123 struct symbol *sym = sym_entry__symbol(syme);
124 struct annotation *notes = symbol__annotation(sym);
125 struct perf_top *top = browser->b.priv;
126
127 if (notes->src != NULL)
128 goto do_annotation;
129
130 pthread_mutex_lock(&notes->lock);
131
132 top->sym_filter_entry = NULL;
133
134 if (symbol__alloc_hist(sym, top->evlist->nr_entries) < 0) {
135 pr_err("Not enough memory for annotating '%s' symbol!\n",
136 sym->name);
137 pthread_mutex_unlock(&notes->lock);
138 return;
139 }
140
141 top->sym_filter_entry = syme;
142
143 pthread_mutex_unlock(&notes->lock);
144do_annotation:
145 symbol__tui_annotate(sym, syme->map, 0, NULL, NULL, top->delay_secs * 1000);
146}
147
148static void perf_top_browser__warn_lost(struct perf_top_browser *browser)
149{
150 struct perf_top *top = browser->b.priv;
151 char msg[128];
152 int len;
153
154 top->total_lost_warned = top->session->hists.stats.total_lost;
155 pthread_mutex_lock(&ui__lock);
156 ui_browser__set_color(&browser->b, HE_COLORSET_TOP);
157 len = snprintf(msg, sizeof(msg),
158 " WARNING: LOST %" PRIu64 " events, Check IO/CPU overload",
159 top->total_lost_warned);
160 if (len > browser->b.width)
161 len = browser->b.width;
162 SLsmg_gotorc(0, browser->b.width - len);
163 slsmg_write_nstring(msg, len);
164 pthread_mutex_unlock(&ui__lock);
165}
166
167static int perf_top_browser__run(struct perf_top_browser *browser)
168{
169 int key;
170 char title[160];
171 struct perf_top *top = browser->b.priv;
172 int delay_msecs = top->delay_secs * 1000;
173 int exit_keys[] = { 'a', NEWT_KEY_ENTER, NEWT_KEY_RIGHT, 0, };
174
175 perf_top_browser__update_rb_tree(browser);
176 perf_top__header_snprintf(top, title, sizeof(title));
177 perf_top__reset_sample_counters(top);
178
179 if (ui_browser__show(&browser->b, title,
180 "ESC: exit, ENTER|->|a: Live Annotate") < 0)
181 return -1;
182
183 newtFormSetTimer(browser->b.form, delay_msecs);
184 ui_browser__add_exit_keys(&browser->b, exit_keys);
185
186 while (1) {
187 key = ui_browser__run(&browser->b);
188
189 switch (key) {
190 case -1:
191 /* FIXME we need to check if it was es.reason == NEWT_EXIT_TIMER */
192 perf_top_browser__update_rb_tree(browser);
193 perf_top__header_snprintf(top, title, sizeof(title));
194 perf_top__reset_sample_counters(top);
195 ui_browser__set_color(&browser->b, NEWT_COLORSET_ROOT);
196 SLsmg_gotorc(0, 0);
197 slsmg_write_nstring(title, browser->b.width);
198
199 if (top->total_lost_warned != top->session->hists.stats.total_lost)
200 perf_top_browser__warn_lost(browser);
201 break;
202 case 'a':
203 case NEWT_KEY_RIGHT:
204 case NEWT_KEY_ENTER:
205 if (browser->selection)
206 perf_top_browser__annotate(browser);
207 break;
208 case NEWT_KEY_LEFT:
209 continue;
210 case NEWT_KEY_ESCAPE:
211 if (!ui__dialog_yesno("Do you really want to exit?"))
212 continue;
213 /* Fall thru */
214 default:
215 goto out;
216 }
217 }
218out:
219 ui_browser__hide(&browser->b);
220 return key;
221}
222
223int perf_top__tui_browser(struct perf_top *top)
224{
225 struct perf_top_browser browser = {
226 .b = {
227 .entries = &browser.root,
228 .refresh = ui_browser__rb_tree_refresh,
229 .seek = ui_browser__rb_tree_seek,
230 .write = perf_top_browser__write,
231 .priv = top,
232 },
233 };
234
235 return perf_top_browser__run(&browser);
236}