aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/ui
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2010-08-09 14:30:40 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-08-10 15:11:42 -0400
commit92221162875ec48913d3f9710046e48d599c9cf2 (patch)
tree891aeb2c50777478aaf0cd5a2537db65f6b7d2ae /tools/perf/util/ui
parent1e6dd077a880ba5570beb690523b7a78a91a7615 (diff)
perf annotate: Sort by hottest lines in the TUI
Right now it will just sort and position at the hottest line, i.e. the one where more samples were taken. It will be at the center of the screen and later TAB/shift-TAB will cycle thru the hottest lines. Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> LKML-Reference: <new-submission> 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/annotate.c153
1 files changed, 115 insertions, 38 deletions
diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c
index 5b01df633f9a..763592b09d74 100644
--- a/tools/perf/util/ui/browsers/annotate.c
+++ b/tools/perf/util/ui/browsers/annotate.c
@@ -14,6 +14,23 @@ static void ui__error_window(const char *fmt, ...)
14 va_end(ap); 14 va_end(ap);
15} 15}
16 16
17struct annotate_browser {
18 struct ui_browser b;
19 struct rb_root entries;
20};
21
22struct objdump_line_rb_node {
23 struct rb_node rb_node;
24 double percent;
25 u32 idx;
26};
27
28static inline
29struct objdump_line_rb_node *objdump_line__rb(struct objdump_line *self)
30{
31 return (struct objdump_line_rb_node *)(self + 1);
32}
33
17static void annotate_browser__write(struct ui_browser *self, void *entry, int row) 34static void annotate_browser__write(struct ui_browser *self, void *entry, int row)
18{ 35{
19 struct objdump_line *ol = rb_entry(entry, struct objdump_line, node); 36 struct objdump_line *ol = rb_entry(entry, struct objdump_line, node);
@@ -21,17 +38,41 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro
21 int width = self->width; 38 int width = self->width;
22 39
23 if (ol->offset != -1) { 40 if (ol->offset != -1) {
24 struct hist_entry *he = self->priv; 41 struct objdump_line_rb_node *olrb = objdump_line__rb(ol);
25 struct symbol *sym = he->ms.sym; 42 int color = ui_browser__percent_color(olrb->percent, current_entry);
26 int len = he->ms.sym->end - he->ms.sym->start; 43 SLsmg_set_color(color);
44 slsmg_printf(" %7.2f ", olrb->percent);
45 if (!current_entry)
46 SLsmg_set_color(HE_COLORSET_CODE);
47 } else {
48 int color = ui_browser__percent_color(0, current_entry);
49 SLsmg_set_color(color);
50 slsmg_write_nstring(" ", 9);
51 }
52
53 SLsmg_write_char(':');
54 slsmg_write_nstring(" ", 8);
55 if (!*ol->line)
56 slsmg_write_nstring(" ", width - 18);
57 else
58 slsmg_write_nstring(ol->line, width - 18);
59}
60
61static double objdump_line__calc_percent(struct objdump_line *self,
62 struct list_head *head,
63 struct symbol *sym)
64{
65 double percent = 0.0;
66
67 if (self->offset != -1) {
68 int len = sym->end - sym->start;
27 unsigned int hits = 0; 69 unsigned int hits = 0;
28 double percent = 0.0;
29 int color;
30 struct sym_priv *priv = symbol__priv(sym); 70 struct sym_priv *priv = symbol__priv(sym);
31 struct sym_ext *sym_ext = priv->ext; 71 struct sym_ext *sym_ext = priv->ext;
32 struct sym_hist *h = priv->hist; 72 struct sym_hist *h = priv->hist;
33 s64 offset = ol->offset; 73 s64 offset = self->offset;
34 struct objdump_line *next = objdump__get_next_ip_line(self->entries, ol); 74 struct objdump_line *next = objdump__get_next_ip_line(head, self);
75
35 76
36 while (offset < (s64)len && 77 while (offset < (s64)len &&
37 (next == NULL || offset < next->offset)) { 78 (next == NULL || offset < next->offset)) {
@@ -45,37 +86,45 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro
45 86
46 if (sym_ext == NULL && h->sum) 87 if (sym_ext == NULL && h->sum)
47 percent = 100.0 * hits / h->sum; 88 percent = 100.0 * hits / h->sum;
48
49 color = ui_browser__percent_color(percent, current_entry);
50 SLsmg_set_color(color);
51 slsmg_printf(" %7.2f ", percent);
52 if (!current_entry)
53 SLsmg_set_color(HE_COLORSET_CODE);
54 } else {
55 int color = ui_browser__percent_color(0, current_entry);
56 SLsmg_set_color(color);
57 slsmg_write_nstring(" ", 9);
58 } 89 }
59 90
60 SLsmg_write_char(':'); 91 return percent;
61 slsmg_write_nstring(" ", 8); 92}
62 if (!*ol->line) 93
63 slsmg_write_nstring(" ", width - 18); 94static void objdump__insert_line(struct rb_root *self,
64 else 95 struct objdump_line_rb_node *line)
65 slsmg_write_nstring(ol->line, width - 18); 96{
97 struct rb_node **p = &self->rb_node;
98 struct rb_node *parent = NULL;
99 struct objdump_line_rb_node *l;
100
101 while (*p != NULL) {
102 parent = *p;
103 l = rb_entry(parent, struct objdump_line_rb_node, rb_node);
104 if (line->percent < l->percent)
105 p = &(*p)->rb_left;
106 else
107 p = &(*p)->rb_right;
108 }
109 rb_link_node(&line->rb_node, parent, p);
110 rb_insert_color(&line->rb_node, self);
66} 111}
67 112
68int hist_entry__tui_annotate(struct hist_entry *self) 113int hist_entry__tui_annotate(struct hist_entry *self)
69{ 114{
70 struct newtExitStruct es; 115 struct newtExitStruct es;
71 struct objdump_line *pos, *n; 116 struct objdump_line *pos, *n;
117 struct objdump_line_rb_node *rbpos;
118 struct rb_node *nd;
72 LIST_HEAD(head); 119 LIST_HEAD(head);
73 struct ui_browser browser = { 120 struct annotate_browser browser = {
74 .entries = &head, 121 .b = {
75 .refresh = ui_browser__list_head_refresh, 122 .entries = &head,
76 .seek = ui_browser__list_head_seek, 123 .refresh = ui_browser__list_head_refresh,
77 .write = annotate_browser__write, 124 .seek = ui_browser__list_head_seek,
78 .priv = self, 125 .write = annotate_browser__write,
126 .priv = self,
127 },
79 }; 128 };
80 int ret; 129 int ret;
81 130
@@ -85,7 +134,7 @@ int hist_entry__tui_annotate(struct hist_entry *self)
85 if (self->ms.map->dso->annotate_warned) 134 if (self->ms.map->dso->annotate_warned)
86 return -1; 135 return -1;
87 136
88 if (hist_entry__annotate(self, &head) < 0) { 137 if (hist_entry__annotate(self, &head, sizeof(*rbpos)) < 0) {
89 ui__error_window(ui_helpline__last_msg); 138 ui__error_window(ui_helpline__last_msg);
90 return -1; 139 return -1;
91 } 140 }
@@ -94,16 +143,44 @@ int hist_entry__tui_annotate(struct hist_entry *self)
94 143
95 list_for_each_entry(pos, &head, node) { 144 list_for_each_entry(pos, &head, node) {
96 size_t line_len = strlen(pos->line); 145 size_t line_len = strlen(pos->line);
97 if (browser.width < line_len) 146 if (browser.b.width < line_len)
98 browser.width = line_len; 147 browser.b.width = line_len;
99 ++browser.nr_entries; 148 rbpos = objdump_line__rb(pos);
149 rbpos->idx = browser.b.nr_entries++;
150 rbpos->percent = objdump_line__calc_percent(pos, &head, self->ms.sym);
151 if (rbpos->percent < 0.01)
152 continue;
153 objdump__insert_line(&browser.entries, rbpos);
154 }
155
156 /*
157 * Position the browser at the hottest line.
158 */
159 nd = rb_last(&browser.entries);
160 if (nd != NULL) {
161 unsigned back;
162
163 ui_browser__refresh_dimensions(&browser.b);
164 back = browser.b.height / 2;
165 rbpos = rb_entry(nd, struct objdump_line_rb_node, rb_node);
166 pos = ((struct objdump_line *)rbpos) - 1;
167 browser.b.top_idx = browser.b.index = rbpos->idx;
168
169 while (browser.b.top_idx != 0 && back != 0) {
170 pos = list_entry(pos->node.prev, struct objdump_line, node);
171
172 --browser.b.top_idx;
173 --back;
174 }
175
176 browser.b.top = pos;
100 } 177 }
101 178
102 browser.width += 18; /* Percentage */ 179 browser.b.width += 18; /* Percentage */
103 ui_browser__show(&browser, self->ms.sym->name); 180 ui_browser__show(&browser.b, self->ms.sym->name);
104 newtFormAddHotKey(browser.form, ' '); 181 newtFormAddHotKey(browser.b.form, ' ');
105 ret = ui_browser__run(&browser, &es); 182 ret = ui_browser__run(&browser.b, &es);
106 newtFormDestroy(browser.form); 183 newtFormDestroy(browser.b.form);
107 newtPopWindow(); 184 newtPopWindow();
108 list_for_each_entry_safe(pos, n, &head, node) { 185 list_for_each_entry_safe(pos, n, &head, node) {
109 list_del(&pos->node); 186 list_del(&pos->node);