Merge branch 'tip/perf/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/roste...
[pandora-kernel.git] / tools / perf / util / ui / browsers / top.c
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 "../helpline.h"
11 #include "../libslang.h"
12 #include "../../evlist.h"
13 #include "../../hist.h"
14 #include "../../sort.h"
15 #include "../../symbol.h"
16 #include "../../top.h"
17
18 struct perf_top_browser {
19         struct ui_browser b;
20         struct rb_root    root;
21         float             sum_ksamples;
22         int               dso_width;
23         int               dso_short_width;
24         int               sym_width;
25 };
26
27 static void perf_top_browser__write(struct ui_browser *browser, void *entry, int row)
28 {
29         struct perf_top_browser *top_browser = container_of(browser, struct perf_top_browser, b);
30         struct sym_entry *syme = rb_entry(entry, struct sym_entry, rb_node);
31         bool current_entry = ui_browser__is_current_entry(browser, row);
32         struct symbol *symbol = sym_entry__symbol(syme);
33         struct perf_top *top = browser->priv;
34         int width = browser->width;
35         double pcnt;
36
37         pcnt = 100.0 - (100.0 * ((top_browser->sum_ksamples - syme->snap_count) /
38                                  top_browser->sum_ksamples));
39         ui_browser__set_percent_color(browser, pcnt, current_entry);
40
41         if (top->evlist->nr_entries == 1 || !top->display_weighted) {
42                 slsmg_printf("%20.2f ", syme->weight);
43                 width -= 24;
44         } else {
45                 slsmg_printf("%9.1f %10ld ", syme->weight, syme->snap_count);
46                 width -= 23;
47         }
48
49         slsmg_printf("%4.1f%%", pcnt);
50         width -= 7;
51
52         if (verbose) {
53                 slsmg_printf(" %016" PRIx64, symbol->start);
54                 width -= 17;
55         }
56
57         slsmg_printf(" %-*.*s ", top_browser->sym_width, top_browser->sym_width,
58                      symbol->name);
59         width -= top_browser->sym_width;
60         slsmg_write_nstring(width >= syme->map->dso->long_name_len ?
61                                 syme->map->dso->long_name :
62                                 syme->map->dso->short_name, width);
63 }
64
65 static void perf_top_browser__update_rb_tree(struct perf_top_browser *browser)
66 {
67         struct perf_top *top = browser->b.priv;
68
69         browser->root = RB_ROOT;
70         browser->b.top = NULL;
71         browser->sum_ksamples = perf_top__decay_samples(top, &browser->root);
72         perf_top__find_widths(top, &browser->root, &browser->dso_width,
73                               &browser->dso_short_width,
74                               &browser->sym_width);
75         if (browser->sym_width + browser->dso_width > browser->b.width - 29) {
76                 browser->dso_width = browser->dso_short_width;
77                 if (browser->sym_width + browser->dso_width > browser->b.width - 29)
78                         browser->sym_width = browser->b.width - browser->dso_width - 29;
79         }
80         browser->b.nr_entries = top->rb_entries;
81 }
82
83 static int perf_top_browser__run(struct perf_top_browser *browser)
84 {
85         int key;
86         char title[160];
87         struct perf_top *top = browser->b.priv;
88         int delay_msecs = top->delay_secs * 1000;
89
90         perf_top_browser__update_rb_tree(browser);
91         perf_top__header_snprintf(top, title, sizeof(title));
92         perf_top__reset_sample_counters(top);
93
94         if (ui_browser__show(&browser->b, title, "ESC: exit") < 0)
95                 return -1;
96
97         newtFormSetTimer(browser->b.form, delay_msecs);
98
99         while (1) {
100                 key = ui_browser__run(&browser->b);
101
102                 switch (key) {
103                 case -1:
104                         /* FIXME we need to check if it was es.reason == NEWT_EXIT_TIMER */
105                         perf_top_browser__update_rb_tree(browser);
106                         perf_top__header_snprintf(top, title, sizeof(title));
107                         perf_top__reset_sample_counters(top);
108                         ui_browser__set_color(&browser->b, NEWT_COLORSET_ROOT);
109                         SLsmg_gotorc(0, 0);
110                         slsmg_write_nstring(title, browser->b.width);
111                         break;
112                 case NEWT_KEY_TAB:
113                 default:
114                         goto out;
115                 }
116         }
117 out:
118         ui_browser__hide(&browser->b);
119         return key;
120 }
121
122 int perf_top__tui_browser(struct perf_top *top)
123 {
124         struct perf_top_browser browser = {
125                 .b = {
126                         .entries = &browser.root,
127                         .refresh = ui_browser__rb_tree_refresh,
128                         .seek    = ui_browser__rb_tree_seek,
129                         .write   = perf_top_browser__write,
130                         .priv    = top,
131                 },
132         };
133
134         ui_helpline__push("Press <- or ESC to exit");
135         return perf_top_browser__run(&browser);
136 }