Blame view
tools/perf/ui/browsers/hists.c
51 KB
d1b4f2491 perf ui: Move his... |
1 |
#include <stdio.h> |
d1b4f2491 perf ui: Move his... |
2 3 4 |
#include "../libslang.h" #include <stdlib.h> #include <string.h> |
d1b4f2491 perf ui: Move his... |
5 |
#include <linux/rbtree.h> |
aca7a94d6 perf tools: Move ... |
6 7 8 9 10 11 |
#include "../../util/evsel.h" #include "../../util/evlist.h" #include "../../util/hist.h" #include "../../util/pstack.h" #include "../../util/sort.h" #include "../../util/util.h" |
42337a222 perf top: Handle ... |
12 |
#include "../../util/top.h" |
68d807586 perf report: Post... |
13 |
#include "../../arch/common.h" |
d1b4f2491 perf ui: Move his... |
14 15 16 17 |
#include "../browser.h" #include "../helpline.h" #include "../util.h" |
4610e4137 perf ui browser: ... |
18 |
#include "../ui.h" |
d1b4f2491 perf ui: Move his... |
19 |
#include "map.h" |
d755330c5 perf tools: Fix s... |
20 |
#include "annotate.h" |
d1b4f2491 perf ui: Move his... |
21 |
|
d1b4f2491 perf ui: Move his... |
22 23 24 25 26 |
struct hist_browser { struct ui_browser b; struct hists *hists; struct hist_entry *he_selection; struct map_symbol *selection; |
aff3f3f68 perf hists browse... |
27 |
int print_seq; |
a7cb8863d perf hists browse... |
28 |
bool show_dso; |
025bf7ea0 perf hists browse... |
29 |
bool show_headers; |
064f19815 perf report: Add ... |
30 |
float min_pcnt; |
112f761fc perf ui/tui: Rena... |
31 |
u64 nr_non_filtered_entries; |
c3b789527 perf hists/tui: C... |
32 |
u64 nr_callchain_rows; |
d1b4f2491 perf ui: Move his... |
33 |
}; |
f5951d56a perf hists browse... |
34 |
extern void hist_browser__init_hpp(void); |
1e378ebd1 perf top: Add a v... |
35 36 37 |
static int hists__browser_title(struct hists *hists, struct hist_browser_timer *hbt, char *bf, size_t size); |
112f761fc perf ui/tui: Rena... |
38 |
static void hist_browser__update_nr_entries(struct hist_browser *hb); |
81cce8de9 perf browsers: Ad... |
39 |
|
c3b789527 perf hists/tui: C... |
40 |
static struct rb_node *hists__filter_entries(struct rb_node *nd, |
c3b789527 perf hists/tui: C... |
41 |
float min_pcnt); |
268397cb2 perf top/tui: Upd... |
42 43 44 45 |
static bool hist_browser__has_filter(struct hist_browser *hb) { return hists__has_filter(hb->hists) || hb->min_pcnt; } |
c3b789527 perf hists/tui: C... |
46 47 48 49 50 51 52 53 54 55 56 |
static u32 hist_browser__nr_entries(struct hist_browser *hb) { u32 nr_entries; if (hist_browser__has_filter(hb)) nr_entries = hb->nr_non_filtered_entries; else nr_entries = hb->hists->nr_entries; return nr_entries + hb->nr_callchain_rows; } |
025bf7ea0 perf hists browse... |
57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
static void hist_browser__update_rows(struct hist_browser *hb) { struct ui_browser *browser = &hb->b; u16 header_offset = hb->show_headers ? 1 : 0, index_row; browser->rows = browser->height - header_offset; /* * Verify if we were at the last line and that line isn't * visibe because we now show the header line(s). */ index_row = browser->index - browser->top_idx; if (index_row >= browser->rows) browser->index -= index_row - browser->rows + 1; } |
357cfff1c perf hists browse... |
71 |
static void hist_browser__refresh_dimensions(struct ui_browser *browser) |
d1b4f2491 perf ui: Move his... |
72 |
{ |
357cfff1c perf hists browse... |
73 |
struct hist_browser *hb = container_of(browser, struct hist_browser, b); |
d1b4f2491 perf ui: Move his... |
74 |
/* 3 == +/- toggle symbol before actual hist_entry rendering */ |
357cfff1c perf hists browse... |
75 76 77 78 79 80 81 82 |
browser->width = 3 + (hists__sort_list_width(hb->hists) + sizeof("[k]")); /* * FIXME: Just keeping existing behaviour, but this really should be * before updating browser->width, as it will invalidate the * calculation above. Fix this and the fallout in another * changeset. */ ui_browser__refresh_dimensions(browser); |
025bf7ea0 perf hists browse... |
83 |
hist_browser__update_rows(hb); |
d1b4f2491 perf ui: Move his... |
84 |
} |
ca3ff33b5 perf hists browse... |
85 86 |
static void hist_browser__gotorc(struct hist_browser *browser, int row, int column) { |
025bf7ea0 perf hists browse... |
87 88 89 |
u16 header_offset = browser->show_headers ? 1 : 0; ui_browser__gotorc(&browser->b, row + header_offset, column); |
ca3ff33b5 perf hists browse... |
90 |
} |
05e8b0804 perf ui browser: ... |
91 |
static void hist_browser__reset(struct hist_browser *browser) |
d1b4f2491 perf ui: Move his... |
92 |
{ |
c3b789527 perf hists/tui: C... |
93 94 95 96 97 |
/* * The hists__remove_entry_filter() already folds non-filtered * entries so we can assume it has 0 callchain rows. */ browser->nr_callchain_rows = 0; |
268397cb2 perf top/tui: Upd... |
98 |
hist_browser__update_nr_entries(browser); |
c3b789527 perf hists/tui: C... |
99 |
browser->b.nr_entries = hist_browser__nr_entries(browser); |
357cfff1c perf hists browse... |
100 |
hist_browser__refresh_dimensions(&browser->b); |
05e8b0804 perf ui browser: ... |
101 |
ui_browser__reset_index(&browser->b); |
d1b4f2491 perf ui: Move his... |
102 103 104 105 106 107 |
} static char tree__folded_sign(bool unfolded) { return unfolded ? '-' : '+'; } |
05e8b0804 perf ui browser: ... |
108 |
static char map_symbol__folded(const struct map_symbol *ms) |
d1b4f2491 perf ui: Move his... |
109 |
{ |
05e8b0804 perf ui browser: ... |
110 |
return ms->has_children ? tree__folded_sign(ms->unfolded) : ' '; |
d1b4f2491 perf ui: Move his... |
111 |
} |
05e8b0804 perf ui browser: ... |
112 |
static char hist_entry__folded(const struct hist_entry *he) |
d1b4f2491 perf ui: Move his... |
113 |
{ |
05e8b0804 perf ui browser: ... |
114 |
return map_symbol__folded(&he->ms); |
d1b4f2491 perf ui: Move his... |
115 |
} |
05e8b0804 perf ui browser: ... |
116 |
static char callchain_list__folded(const struct callchain_list *cl) |
d1b4f2491 perf ui: Move his... |
117 |
{ |
05e8b0804 perf ui browser: ... |
118 |
return map_symbol__folded(&cl->ms); |
d1b4f2491 perf ui: Move his... |
119 |
} |
05e8b0804 perf ui browser: ... |
120 |
static void map_symbol__set_folding(struct map_symbol *ms, bool unfold) |
3c916cc28 perf hists browse... |
121 |
{ |
05e8b0804 perf ui browser: ... |
122 |
ms->unfolded = unfold ? ms->has_children : false; |
3c916cc28 perf hists browse... |
123 |
} |
05e8b0804 perf ui browser: ... |
124 |
static int callchain_node__count_rows_rb_tree(struct callchain_node *node) |
d1b4f2491 perf ui: Move his... |
125 126 127 |
{ int n = 0; struct rb_node *nd; |
05e8b0804 perf ui browser: ... |
128 |
for (nd = rb_first(&node->rb_root); nd; nd = rb_next(nd)) { |
d1b4f2491 perf ui: Move his... |
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
struct callchain_node *child = rb_entry(nd, struct callchain_node, rb_node); struct callchain_list *chain; char folded_sign = ' '; /* No children */ list_for_each_entry(chain, &child->val, list) { ++n; /* We need this because we may not have children */ folded_sign = callchain_list__folded(chain); if (folded_sign == '+') break; } if (folded_sign == '-') /* Have children and they're unfolded */ n += callchain_node__count_rows_rb_tree(child); } return n; } static int callchain_node__count_rows(struct callchain_node *node) { struct callchain_list *chain; bool unfolded = false; int n = 0; list_for_each_entry(chain, &node->val, list) { ++n; unfolded = chain->ms.unfolded; } if (unfolded) n += callchain_node__count_rows_rb_tree(node); return n; } static int callchain__count_rows(struct rb_root *chain) { struct rb_node *nd; int n = 0; for (nd = rb_first(chain); nd; nd = rb_next(nd)) { struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node); n += callchain_node__count_rows(node); } return n; } |
05e8b0804 perf ui browser: ... |
177 |
static bool map_symbol__toggle_fold(struct map_symbol *ms) |
d1b4f2491 perf ui: Move his... |
178 |
{ |
05e8b0804 perf ui browser: ... |
179 |
if (!ms) |
8493fe1da perf hists browse... |
180 |
return false; |
05e8b0804 perf ui browser: ... |
181 |
if (!ms->has_children) |
d1b4f2491 perf ui: Move his... |
182 |
return false; |
05e8b0804 perf ui browser: ... |
183 |
ms->unfolded = !ms->unfolded; |
d1b4f2491 perf ui: Move his... |
184 185 |
return true; } |
05e8b0804 perf ui browser: ... |
186 |
static void callchain_node__init_have_children_rb_tree(struct callchain_node *node) |
d1b4f2491 perf ui: Move his... |
187 |
{ |
05e8b0804 perf ui browser: ... |
188 |
struct rb_node *nd = rb_first(&node->rb_root); |
d1b4f2491 perf ui: Move his... |
189 |
|
05e8b0804 perf ui browser: ... |
190 |
for (nd = rb_first(&node->rb_root); nd; nd = rb_next(nd)) { |
d1b4f2491 perf ui: Move his... |
191 192 |
struct callchain_node *child = rb_entry(nd, struct callchain_node, rb_node); struct callchain_list *chain; |
293db47f4 perf hists browse... |
193 |
bool first = true; |
d1b4f2491 perf ui: Move his... |
194 195 196 197 198 |
list_for_each_entry(chain, &child->val, list) { if (first) { first = false; chain->ms.has_children = chain->list.next != &child->val || |
293db47f4 perf hists browse... |
199 |
!RB_EMPTY_ROOT(&child->rb_root); |
d1b4f2491 perf ui: Move his... |
200 201 |
} else chain->ms.has_children = chain->list.next == &child->val && |
293db47f4 perf hists browse... |
202 |
!RB_EMPTY_ROOT(&child->rb_root); |
d1b4f2491 perf ui: Move his... |
203 204 205 206 207 |
} callchain_node__init_have_children_rb_tree(child); } } |
a7444af69 perf tools: Colla... |
208 209 |
static void callchain_node__init_have_children(struct callchain_node *node, bool has_sibling) |
d1b4f2491 perf ui: Move his... |
210 211 |
{ struct callchain_list *chain; |
a7444af69 perf tools: Colla... |
212 213 |
chain = list_entry(node->val.next, struct callchain_list, list); chain->ms.has_children = has_sibling; |
82162b5ae perf hists browse... |
214 215 |
if (!list_empty(&node->val)) { chain = list_entry(node->val.prev, struct callchain_list, list); |
05e8b0804 perf ui browser: ... |
216 |
chain->ms.has_children = !RB_EMPTY_ROOT(&node->rb_root); |
82162b5ae perf hists browse... |
217 |
} |
d1b4f2491 perf ui: Move his... |
218 |
|
05e8b0804 perf ui browser: ... |
219 |
callchain_node__init_have_children_rb_tree(node); |
d1b4f2491 perf ui: Move his... |
220 |
} |
05e8b0804 perf ui browser: ... |
221 |
static void callchain__init_have_children(struct rb_root *root) |
d1b4f2491 perf ui: Move his... |
222 |
{ |
a7444af69 perf tools: Colla... |
223 224 |
struct rb_node *nd = rb_first(root); bool has_sibling = nd && rb_next(nd); |
d1b4f2491 perf ui: Move his... |
225 |
|
05e8b0804 perf ui browser: ... |
226 |
for (nd = rb_first(root); nd; nd = rb_next(nd)) { |
d1b4f2491 perf ui: Move his... |
227 |
struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node); |
a7444af69 perf tools: Colla... |
228 |
callchain_node__init_have_children(node, has_sibling); |
d1b4f2491 perf ui: Move his... |
229 230 |
} } |
05e8b0804 perf ui browser: ... |
231 |
static void hist_entry__init_have_children(struct hist_entry *he) |
d1b4f2491 perf ui: Move his... |
232 |
{ |
05e8b0804 perf ui browser: ... |
233 234 235 236 |
if (!he->init_have_children) { he->ms.has_children = !RB_EMPTY_ROOT(&he->sorted_chain); callchain__init_have_children(&he->sorted_chain); he->init_have_children = true; |
d1b4f2491 perf ui: Move his... |
237 238 |
} } |
05e8b0804 perf ui browser: ... |
239 |
static bool hist_browser__toggle_fold(struct hist_browser *browser) |
d1b4f2491 perf ui: Move his... |
240 |
{ |
05e8b0804 perf ui browser: ... |
241 242 |
if (map_symbol__toggle_fold(browser->selection)) { struct hist_entry *he = browser->he_selection; |
d1b4f2491 perf ui: Move his... |
243 244 |
hist_entry__init_have_children(he); |
c3b789527 perf hists/tui: C... |
245 246 |
browser->b.nr_entries -= he->nr_rows; browser->nr_callchain_rows -= he->nr_rows; |
d1b4f2491 perf ui: Move his... |
247 248 249 250 251 |
if (he->ms.unfolded) he->nr_rows = callchain__count_rows(&he->sorted_chain); else he->nr_rows = 0; |
c3b789527 perf hists/tui: C... |
252 253 254 |
browser->b.nr_entries += he->nr_rows; browser->nr_callchain_rows += he->nr_rows; |
d1b4f2491 perf ui: Move his... |
255 256 257 258 259 260 261 |
return true; } /* If it doesn't have children, no toggling performed */ return false; } |
05e8b0804 perf ui browser: ... |
262 |
static int callchain_node__set_folding_rb_tree(struct callchain_node *node, bool unfold) |
3c916cc28 perf hists browse... |
263 264 265 |
{ int n = 0; struct rb_node *nd; |
05e8b0804 perf ui browser: ... |
266 |
for (nd = rb_first(&node->rb_root); nd; nd = rb_next(nd)) { |
3c916cc28 perf hists browse... |
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 |
struct callchain_node *child = rb_entry(nd, struct callchain_node, rb_node); struct callchain_list *chain; bool has_children = false; list_for_each_entry(chain, &child->val, list) { ++n; map_symbol__set_folding(&chain->ms, unfold); has_children = chain->ms.has_children; } if (has_children) n += callchain_node__set_folding_rb_tree(child, unfold); } return n; } static int callchain_node__set_folding(struct callchain_node *node, bool unfold) { struct callchain_list *chain; bool has_children = false; int n = 0; list_for_each_entry(chain, &node->val, list) { ++n; map_symbol__set_folding(&chain->ms, unfold); has_children = chain->ms.has_children; } if (has_children) n += callchain_node__set_folding_rb_tree(node, unfold); return n; } static int callchain__set_folding(struct rb_root *chain, bool unfold) { struct rb_node *nd; int n = 0; for (nd = rb_first(chain); nd; nd = rb_next(nd)) { struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node); n += callchain_node__set_folding(node, unfold); } return n; } |
05e8b0804 perf ui browser: ... |
314 |
static void hist_entry__set_folding(struct hist_entry *he, bool unfold) |
3c916cc28 perf hists browse... |
315 |
{ |
05e8b0804 perf ui browser: ... |
316 317 |
hist_entry__init_have_children(he); map_symbol__set_folding(&he->ms, unfold); |
3c916cc28 perf hists browse... |
318 |
|
05e8b0804 perf ui browser: ... |
319 320 321 |
if (he->ms.has_children) { int n = callchain__set_folding(&he->sorted_chain, unfold); he->nr_rows = unfold ? n : 0; |
3c916cc28 perf hists browse... |
322 |
} else |
05e8b0804 perf ui browser: ... |
323 |
he->nr_rows = 0; |
3c916cc28 perf hists browse... |
324 |
} |
c3b789527 perf hists/tui: C... |
325 326 |
static void __hist_browser__set_folding(struct hist_browser *browser, bool unfold) |
3c916cc28 perf hists browse... |
327 328 |
{ struct rb_node *nd; |
c3b789527 perf hists/tui: C... |
329 |
struct hists *hists = browser->hists; |
3c916cc28 perf hists browse... |
330 |
|
c3b789527 perf hists/tui: C... |
331 |
for (nd = rb_first(&hists->entries); |
14135663f perf tools: Apply... |
332 |
(nd = hists__filter_entries(nd, browser->min_pcnt)) != NULL; |
c3b789527 perf hists/tui: C... |
333 |
nd = rb_next(nd)) { |
3c916cc28 perf hists browse... |
334 335 |
struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); hist_entry__set_folding(he, unfold); |
c3b789527 perf hists/tui: C... |
336 |
browser->nr_callchain_rows += he->nr_rows; |
3c916cc28 perf hists browse... |
337 338 |
} } |
05e8b0804 perf ui browser: ... |
339 |
static void hist_browser__set_folding(struct hist_browser *browser, bool unfold) |
3c916cc28 perf hists browse... |
340 |
{ |
c3b789527 perf hists/tui: C... |
341 342 343 344 |
browser->nr_callchain_rows = 0; __hist_browser__set_folding(browser, unfold); browser->b.nr_entries = hist_browser__nr_entries(browser); |
3c916cc28 perf hists browse... |
345 |
/* Go to the start, we may be way after valid entries after a collapse */ |
05e8b0804 perf ui browser: ... |
346 |
ui_browser__reset_index(&browser->b); |
3c916cc28 perf hists browse... |
347 |
} |
7b27509fc perf hists browse... |
348 349 350 351 352 353 354 355 356 357 358 359 360 361 |
static void ui_browser__warn_lost_events(struct ui_browser *browser) { ui_browser__warning(browser, 4, "Events are being lost, check IO/CPU overload! " "You may want to run 'perf' using a RT scheduler policy: " " perf top -r 80 " "Or reduce the sampling frequency."); } |
dd00d486d perf hists browse... |
362 |
static int hist_browser__run(struct hist_browser *browser, |
9783adf77 perf tools: Intro... |
363 |
struct hist_browser_timer *hbt) |
d1b4f2491 perf ui: Move his... |
364 |
{ |
b50e003db perf ui browser: ... |
365 |
int key; |
81cce8de9 perf browsers: Ad... |
366 |
char title[160]; |
9783adf77 perf tools: Intro... |
367 |
int delay_secs = hbt ? hbt->refresh : 0; |
d1b4f2491 perf ui: Move his... |
368 |
|
05e8b0804 perf ui browser: ... |
369 |
browser->b.entries = &browser->hists->entries; |
c3b789527 perf hists/tui: C... |
370 |
browser->b.nr_entries = hist_browser__nr_entries(browser); |
d1b4f2491 perf ui: Move his... |
371 |
|
1e378ebd1 perf top: Add a v... |
372 |
hists__browser_title(browser->hists, hbt, title, sizeof(title)); |
d1b4f2491 perf ui: Move his... |
373 |
|
05e8b0804 perf ui browser: ... |
374 |
if (ui_browser__show(&browser->b, title, |
59e8fe32f perf ui browser: ... |
375 |
"Press '?' for help on key bindings") < 0) |
d1b4f2491 perf ui: Move his... |
376 |
return -1; |
d1b4f2491 perf ui: Move his... |
377 |
while (1) { |
05e8b0804 perf ui browser: ... |
378 |
key = ui_browser__run(&browser->b, delay_secs); |
d1b4f2491 perf ui: Move his... |
379 |
|
b50e003db perf ui browser: ... |
380 |
switch (key) { |
fa5df9435 perf top: Add --p... |
381 382 |
case K_TIMER: { u64 nr_entries; |
9783adf77 perf tools: Intro... |
383 |
hbt->timer(hbt->arg); |
fa5df9435 perf top: Add --p... |
384 |
|
c3b789527 perf hists/tui: C... |
385 |
if (hist_browser__has_filter(browser)) |
112f761fc perf ui/tui: Rena... |
386 |
hist_browser__update_nr_entries(browser); |
fa5df9435 perf top: Add --p... |
387 |
|
c3b789527 perf hists/tui: C... |
388 |
nr_entries = hist_browser__nr_entries(browser); |
fa5df9435 perf top: Add --p... |
389 |
ui_browser__update_nr_entries(&browser->b, nr_entries); |
7b27509fc perf hists browse... |
390 |
|
05e8b0804 perf ui browser: ... |
391 392 393 394 395 |
if (browser->hists->stats.nr_lost_warned != browser->hists->stats.nr_events[PERF_RECORD_LOST]) { browser->hists->stats.nr_lost_warned = browser->hists->stats.nr_events[PERF_RECORD_LOST]; ui_browser__warn_lost_events(&browser->b); |
7b27509fc perf hists browse... |
396 |
} |
1e378ebd1 perf top: Add a v... |
397 398 |
hists__browser_title(browser->hists, hbt, title, sizeof(title)); |
05e8b0804 perf ui browser: ... |
399 |
ui_browser__show_title(&browser->b, title); |
81cce8de9 perf browsers: Ad... |
400 |
continue; |
fa5df9435 perf top: Add --p... |
401 |
} |
4694153c2 perf ui hist brow... |
402 |
case 'D': { /* Debug */ |
d1b4f2491 perf ui: Move his... |
403 |
static int seq; |
05e8b0804 perf ui browser: ... |
404 |
struct hist_entry *h = rb_entry(browser->b.top, |
d1b4f2491 perf ui: Move his... |
405 406 |
struct hist_entry, rb_node); ui_helpline__pop(); |
62c95ae33 perf ui browser: ... |
407 |
ui_helpline__fpush("%d: nr_ent=(%d,%d), rows=%d, idx=%d, fve: idx=%d, row_off=%d, nrows=%d", |
05e8b0804 perf ui browser: ... |
408 409 |
seq++, browser->b.nr_entries, browser->hists->nr_entries, |
62c95ae33 perf ui browser: ... |
410 |
browser->b.rows, |
05e8b0804 perf ui browser: ... |
411 412 |
browser->b.index, browser->b.top_idx, |
d1b4f2491 perf ui: Move his... |
413 414 |
h->row_offset, h->nr_rows); } |
3c916cc28 perf hists browse... |
415 416 417 |
break; case 'C': /* Collapse the whole world. */ |
05e8b0804 perf ui browser: ... |
418 |
hist_browser__set_folding(browser, false); |
3c916cc28 perf hists browse... |
419 420 421 |
break; case 'E': /* Expand the whole world. */ |
05e8b0804 perf ui browser: ... |
422 |
hist_browser__set_folding(browser, true); |
3c916cc28 perf hists browse... |
423 |
break; |
025bf7ea0 perf hists browse... |
424 425 426 427 |
case 'H': browser->show_headers = !browser->show_headers; hist_browser__update_rows(browser); break; |
cf9580036 perf ui browser: ... |
428 |
case K_ENTER: |
05e8b0804 perf ui browser: ... |
429 |
if (hist_browser__toggle_fold(browser)) |
d1b4f2491 perf ui: Move his... |
430 431 432 |
break; /* fall thru */ default: |
b50e003db perf ui browser: ... |
433 |
goto out; |
d1b4f2491 perf ui: Move his... |
434 435 |
} } |
b50e003db perf ui browser: ... |
436 |
out: |
05e8b0804 perf ui browser: ... |
437 |
ui_browser__hide(&browser->b); |
b50e003db perf ui browser: ... |
438 |
return key; |
d1b4f2491 perf ui: Move his... |
439 |
} |
39ee533fc perf hists browse... |
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 |
struct callchain_print_arg { /* for hists browser */ off_t row_offset; bool is_current_entry; /* for file dump */ FILE *fp; int printed; }; typedef void (*print_callchain_entry_fn)(struct hist_browser *browser, struct callchain_list *chain, const char *str, int offset, unsigned short row, struct callchain_print_arg *arg); |
f4536ddd2 perf hists browse... |
455 456 |
static void hist_browser__show_callchain_entry(struct hist_browser *browser, struct callchain_list *chain, |
39ee533fc perf hists browse... |
457 458 459 |
const char *str, int offset, unsigned short row, struct callchain_print_arg *arg) |
f4536ddd2 perf hists browse... |
460 461 |
{ int color, width; |
39ee533fc perf hists browse... |
462 |
char folded_sign = callchain_list__folded(chain); |
f4536ddd2 perf hists browse... |
463 464 465 466 467 468 |
color = HE_COLORSET_NORMAL; width = browser->b.width - (offset + 2); if (ui_browser__is_current_entry(&browser->b, row)) { browser->selection = &chain->ms; color = HE_COLORSET_SELECTED; |
39ee533fc perf hists browse... |
469 |
arg->is_current_entry = true; |
f4536ddd2 perf hists browse... |
470 471 472 473 474 475 476 477 |
} ui_browser__set_color(&browser->b, color); hist_browser__gotorc(browser, row, 0); slsmg_write_nstring(" ", offset); slsmg_printf("%c ", folded_sign); slsmg_write_nstring(str, width); } |
39ee533fc perf hists browse... |
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 |
static void hist_browser__fprintf_callchain_entry(struct hist_browser *b __maybe_unused, struct callchain_list *chain, const char *str, int offset, unsigned short row __maybe_unused, struct callchain_print_arg *arg) { char folded_sign = callchain_list__folded(chain); arg->printed += fprintf(arg->fp, "%*s%c %s ", offset, " ", folded_sign, str); } typedef bool (*check_output_full_fn)(struct hist_browser *browser, unsigned short row); static bool hist_browser__check_output_full(struct hist_browser *browser, unsigned short row) { return browser->b.rows == row; } static bool hist_browser__check_dump_full(struct hist_browser *browser __maybe_unused, unsigned short row __maybe_unused) { return false; } |
d1b4f2491 perf ui: Move his... |
505 |
#define LEVEL_OFFSET_STEP 3 |
c09a7e755 perf hists browse... |
506 507 |
static int hist_browser__show_callchain(struct hist_browser *browser, struct rb_root *root, int level, |
39ee533fc perf hists browse... |
508 509 510 511 |
unsigned short row, u64 total, print_callchain_entry_fn print, struct callchain_print_arg *arg, check_output_full_fn is_output_full) |
d1b4f2491 perf ui: Move his... |
512 513 |
{ struct rb_node *node; |
f4536ddd2 perf hists browse... |
514 |
int first_row = row, offset = level * LEVEL_OFFSET_STEP; |
36e15dd40 perf hists browse... |
515 |
u64 new_total; |
4087d11cd perf hists browse... |
516 |
bool need_percent; |
d1b4f2491 perf ui: Move his... |
517 |
|
c09a7e755 perf hists browse... |
518 |
node = rb_first(root); |
4087d11cd perf hists browse... |
519 |
need_percent = !!rb_next(node); |
d1b4f2491 perf ui: Move his... |
520 521 522 |
while (node) { struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node); struct rb_node *next = rb_next(node); |
f08c3154a perf callchain: R... |
523 |
u64 cumul = callchain_cumul_hits(child); |
d1b4f2491 perf ui: Move his... |
524 525 526 527 |
struct callchain_list *chain; char folded_sign = ' '; int first = true; int extra_offset = 0; |
d1b4f2491 perf ui: Move his... |
528 |
list_for_each_entry(chain, &child->val, list) { |
a7cb8863d perf hists browse... |
529 |
char bf[1024], *alloc_str; |
d1b4f2491 perf ui: Move his... |
530 |
const char *str; |
d1b4f2491 perf ui: Move his... |
531 |
bool was_first = first; |
163caed90 perf hists browse... |
532 |
if (first) |
d1b4f2491 perf ui: Move his... |
533 |
first = false; |
4087d11cd perf hists browse... |
534 |
else if (need_percent) |
d1b4f2491 perf ui: Move his... |
535 |
extra_offset = LEVEL_OFFSET_STEP; |
d1b4f2491 perf ui: Move his... |
536 537 |
folded_sign = callchain_list__folded(chain); |
39ee533fc perf hists browse... |
538 539 |
if (arg->row_offset != 0) { arg->row_offset--; |
d1b4f2491 perf ui: Move his... |
540 541 542 543 |
goto do_next; } alloc_str = NULL; |
a7cb8863d perf hists browse... |
544 545 |
str = callchain_list__sym_name(chain, bf, sizeof(bf), browser->show_dso); |
c09a7e755 perf hists browse... |
546 |
|
4087d11cd perf hists browse... |
547 |
if (was_first && need_percent) { |
c09a7e755 perf hists browse... |
548 |
double percent = cumul * 100.0 / total; |
d1b4f2491 perf ui: Move his... |
549 550 551 552 553 554 |
if (asprintf(&alloc_str, "%2.2f%% %s", percent, str) < 0) str = "Not enough memory!"; else str = alloc_str; } |
39ee533fc perf hists browse... |
555 |
print(browser, chain, str, offset + extra_offset, row, arg); |
d1b4f2491 perf ui: Move his... |
556 |
free(alloc_str); |
39ee533fc perf hists browse... |
557 |
if (is_output_full(browser, ++row)) |
d1b4f2491 perf ui: Move his... |
558 559 560 561 562 563 564 565 |
goto out; do_next: if (folded_sign == '+') break; } if (folded_sign == '-') { const int new_level = level + (extra_offset ? 2 : 1); |
d1b4f2491 perf ui: Move his... |
566 |
|
c09a7e755 perf hists browse... |
567 568 569 570 |
if (callchain_param.mode == CHAIN_GRAPH_REL) new_total = child->children_hit; else new_total = total; |
d1b4f2491 perf ui: Move his... |
571 |
|
c09a7e755 perf hists browse... |
572 |
row += hist_browser__show_callchain(browser, &child->rb_root, |
39ee533fc perf hists browse... |
573 574 |
new_level, row, new_total, print, arg, is_output_full); |
d1b4f2491 perf ui: Move his... |
575 |
} |
39ee533fc perf hists browse... |
576 |
if (is_output_full(browser, row)) |
d1b4f2491 perf ui: Move his... |
577 |
break; |
c09a7e755 perf hists browse... |
578 |
node = next; |
d1b4f2491 perf ui: Move his... |
579 |
} |
c09a7e755 perf hists browse... |
580 |
out: |
d1b4f2491 perf ui: Move his... |
581 582 |
return row - first_row; } |
897014603 perf hists browse... |
583 584 585 586 587 |
struct hpp_arg { struct ui_browser *b; char folded_sign; bool current_entry; }; |
2f6d9009a perf ui/tui: Reus... |
588 589 590 |
static int __hpp__slsmg_color_printf(struct perf_hpp *hpp, const char *fmt, ...) { struct hpp_arg *arg = hpp->ptr; |
d675107ce perf tools: Make ... |
591 |
int ret, len; |
2f6d9009a perf ui/tui: Reus... |
592 593 |
va_list args; double percent; |
371d8c402 perf hists browse... |
594 |
|
2f6d9009a perf ui/tui: Reus... |
595 |
va_start(args, fmt); |
d675107ce perf tools: Make ... |
596 |
len = va_arg(args, int); |
2f6d9009a perf ui/tui: Reus... |
597 598 |
percent = va_arg(args, double); va_end(args); |
371d8c402 perf hists browse... |
599 |
|
2f6d9009a perf ui/tui: Reus... |
600 |
ui_browser__set_percent_color(arg->b, percent, arg->current_entry); |
371d8c402 perf hists browse... |
601 |
|
d675107ce perf tools: Make ... |
602 |
ret = scnprintf(hpp->buf, hpp->size, fmt, len, percent); |
2f6d9009a perf ui/tui: Reus... |
603 |
slsmg_printf("%s", hpp->buf); |
5aed9d249 perf hists browse... |
604 |
|
2f6d9009a perf ui/tui: Reus... |
605 |
advance_hpp(hpp, ret); |
5aed9d249 perf hists browse... |
606 607 |
return ret; } |
fb821c9e7 perf ui: Get rid ... |
608 |
#define __HPP_COLOR_PERCENT_FN(_type, _field) \ |
5aed9d249 perf hists browse... |
609 610 611 612 613 |
static u64 __hpp_get_##_field(struct hist_entry *he) \ { \ return he->stat._field; \ } \ \ |
2c5d4b4a0 perf tools: Add s... |
614 |
static int \ |
5b5916696 perf report: Hono... |
615 |
hist_browser__hpp_color_##_type(struct perf_hpp_fmt *fmt, \ |
2c5d4b4a0 perf tools: Add s... |
616 617 |
struct perf_hpp *hpp, \ struct hist_entry *he) \ |
f5951d56a perf hists browse... |
618 |
{ \ |
5b5916696 perf report: Hono... |
619 620 |
return hpp__fmt(fmt, hpp, he, __hpp_get_##_field, " %*.2f%%", \ __hpp__slsmg_color_printf, true); \ |
f5951d56a perf hists browse... |
621 |
} |
0434ddd21 perf ui/browser: ... |
622 623 624 625 626 627 628 |
#define __HPP_COLOR_ACC_PERCENT_FN(_type, _field) \ static u64 __hpp_get_acc_##_field(struct hist_entry *he) \ { \ return he->stat_acc->_field; \ } \ \ static int \ |
5b5916696 perf report: Hono... |
629 |
hist_browser__hpp_color_##_type(struct perf_hpp_fmt *fmt, \ |
0434ddd21 perf ui/browser: ... |
630 631 632 633 |
struct perf_hpp *hpp, \ struct hist_entry *he) \ { \ if (!symbol_conf.cumulate_callchain) { \ |
5b5916696 perf report: Hono... |
634 |
int len = fmt->user_len ?: fmt->len; \ |
d675107ce perf tools: Make ... |
635 |
int ret = scnprintf(hpp->buf, hpp->size, \ |
5b5916696 perf report: Hono... |
636 |
"%*s", len, "N/A"); \ |
0434ddd21 perf ui/browser: ... |
637 638 639 640 |
slsmg_printf("%s", hpp->buf); \ \ return ret; \ } \ |
5b5916696 perf report: Hono... |
641 642 |
return hpp__fmt(fmt, hpp, he, __hpp_get_acc_##_field, \ " %*.2f%%", __hpp__slsmg_color_printf, true); \ |
0434ddd21 perf ui/browser: ... |
643 |
} |
fb821c9e7 perf ui: Get rid ... |
644 645 646 647 648 |
__HPP_COLOR_PERCENT_FN(overhead, period) __HPP_COLOR_PERCENT_FN(overhead_sys, period_sys) __HPP_COLOR_PERCENT_FN(overhead_us, period_us) __HPP_COLOR_PERCENT_FN(overhead_guest_sys, period_guest_sys) __HPP_COLOR_PERCENT_FN(overhead_guest_us, period_guest_us) |
0434ddd21 perf ui/browser: ... |
649 |
__HPP_COLOR_ACC_PERCENT_FN(overhead_acc, period) |
f5951d56a perf hists browse... |
650 |
|
5aed9d249 perf hists browse... |
651 |
#undef __HPP_COLOR_PERCENT_FN |
0434ddd21 perf ui/browser: ... |
652 |
#undef __HPP_COLOR_ACC_PERCENT_FN |
f5951d56a perf hists browse... |
653 654 655 |
void hist_browser__init_hpp(void) { |
f5951d56a perf hists browse... |
656 657 658 659 660 661 662 663 664 665 |
perf_hpp__format[PERF_HPP__OVERHEAD].color = hist_browser__hpp_color_overhead; perf_hpp__format[PERF_HPP__OVERHEAD_SYS].color = hist_browser__hpp_color_overhead_sys; perf_hpp__format[PERF_HPP__OVERHEAD_US].color = hist_browser__hpp_color_overhead_us; perf_hpp__format[PERF_HPP__OVERHEAD_GUEST_SYS].color = hist_browser__hpp_color_overhead_guest_sys; perf_hpp__format[PERF_HPP__OVERHEAD_GUEST_US].color = hist_browser__hpp_color_overhead_guest_us; |
0434ddd21 perf ui/browser: ... |
666 667 |
perf_hpp__format[PERF_HPP__OVERHEAD_ACC].color = hist_browser__hpp_color_overhead_acc; |
f5951d56a perf hists browse... |
668 |
} |
05e8b0804 perf ui browser: ... |
669 |
static int hist_browser__show_entry(struct hist_browser *browser, |
d1b4f2491 perf ui: Move his... |
670 671 672 673 |
struct hist_entry *entry, unsigned short row) { char s[256]; |
1240005e0 perf hists: Intro... |
674 |
int printed = 0; |
67d259165 perf hists browse... |
675 |
int width = browser->b.width; |
d1b4f2491 perf ui: Move his... |
676 |
char folded_sign = ' '; |
05e8b0804 perf ui browser: ... |
677 |
bool current_entry = ui_browser__is_current_entry(&browser->b, row); |
d1b4f2491 perf ui: Move his... |
678 |
off_t row_offset = entry->row_offset; |
63a1a3d82 perf hists browse... |
679 |
bool first = true; |
1240005e0 perf hists: Intro... |
680 |
struct perf_hpp_fmt *fmt; |
d1b4f2491 perf ui: Move his... |
681 682 |
if (current_entry) { |
05e8b0804 perf ui browser: ... |
683 684 |
browser->he_selection = entry; browser->selection = &entry->ms; |
d1b4f2491 perf ui: Move his... |
685 686 687 |
} if (symbol_conf.use_callchain) { |
163caed90 perf hists browse... |
688 |
hist_entry__init_have_children(entry); |
d1b4f2491 perf ui: Move his... |
689 690 691 692 |
folded_sign = hist_entry__folded(entry); } if (row_offset == 0) { |
897014603 perf hists browse... |
693 |
struct hpp_arg arg = { |
fb821c9e7 perf ui: Get rid ... |
694 |
.b = &browser->b, |
897014603 perf hists browse... |
695 696 697 |
.folded_sign = folded_sign, .current_entry = current_entry, }; |
f5951d56a perf hists browse... |
698 699 700 |
struct perf_hpp hpp = { .buf = s, .size = sizeof(s), |
897014603 perf hists browse... |
701 |
.ptr = &arg, |
f5951d56a perf hists browse... |
702 |
}; |
d1b4f2491 perf ui: Move his... |
703 |
|
ca3ff33b5 perf hists browse... |
704 |
hist_browser__gotorc(browser, row, 0); |
c172f7422 perf ui browser: ... |
705 |
|
1240005e0 perf hists: Intro... |
706 |
perf_hpp__for_each_format(fmt) { |
e67d49a72 perf tools: Skip ... |
707 708 |
if (perf_hpp__should_skip(fmt)) continue; |
fb821c9e7 perf ui: Get rid ... |
709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 |
if (current_entry && browser->b.navkeypressed) { ui_browser__set_color(&browser->b, HE_COLORSET_SELECTED); } else { ui_browser__set_color(&browser->b, HE_COLORSET_NORMAL); } if (first) { if (symbol_conf.use_callchain) { slsmg_printf("%c ", folded_sign); width -= 2; } first = false; } else { |
f5951d56a perf hists browse... |
724 725 726 |
slsmg_printf(" "); width -= 2; } |
c172f7422 perf ui browser: ... |
727 |
|
1240005e0 perf hists: Intro... |
728 |
if (fmt->color) { |
2c5d4b4a0 perf tools: Add s... |
729 |
width -= fmt->color(fmt, &hpp, entry); |
f5951d56a perf hists browse... |
730 |
} else { |
2c5d4b4a0 perf tools: Add s... |
731 |
width -= fmt->entry(fmt, &hpp, entry); |
f5951d56a perf hists browse... |
732 733 |
slsmg_printf("%s", s); } |
2cf9cebf0 perf hists browse... |
734 |
} |
f5951d56a perf hists browse... |
735 736 737 |
/* The scroll bar isn't being used */ if (!browser->b.navkeypressed) width += 1; |
26d8b3382 perf tools: Conso... |
738 |
slsmg_write_nstring("", width); |
d1b4f2491 perf ui: Move his... |
739 740 741 742 |
++row; ++printed; } else --row_offset; |
62c95ae33 perf ui browser: ... |
743 |
if (folded_sign == '-' && row != browser->b.rows) { |
c09a7e755 perf hists browse... |
744 |
u64 total = hists__total_period(entry->hists); |
39ee533fc perf hists browse... |
745 746 747 748 |
struct callchain_print_arg arg = { .row_offset = row_offset, .is_current_entry = current_entry, }; |
c09a7e755 perf hists browse... |
749 |
|
4087d11cd perf hists browse... |
750 751 752 753 754 755 |
if (callchain_param.mode == CHAIN_GRAPH_REL) { if (symbol_conf.cumulate_callchain) total = entry->stat_acc->period; else total = entry->stat.period; } |
c09a7e755 perf hists browse... |
756 |
printed += hist_browser__show_callchain(browser, |
39ee533fc perf hists browse... |
757 758 759 |
&entry->sorted_chain, 1, row, total, hist_browser__show_callchain_entry, &arg, hist_browser__check_output_full); |
c09a7e755 perf hists browse... |
760 |
|
39ee533fc perf hists browse... |
761 |
if (arg.is_current_entry) |
05e8b0804 perf ui browser: ... |
762 |
browser->he_selection = entry; |
d1b4f2491 perf ui: Move his... |
763 764 765 766 |
} return printed; } |
81a888fea perf hists browse... |
767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 |
static int advance_hpp_check(struct perf_hpp *hpp, int inc) { advance_hpp(hpp, inc); return hpp->size <= 0; } static int hists__scnprintf_headers(char *buf, size_t size, struct hists *hists) { struct perf_hpp dummy_hpp = { .buf = buf, .size = size, }; struct perf_hpp_fmt *fmt; size_t ret = 0; if (symbol_conf.use_callchain) { ret = scnprintf(buf, size, " "); if (advance_hpp_check(&dummy_hpp, ret)) return ret; } perf_hpp__for_each_format(fmt) { if (perf_hpp__should_skip(fmt)) continue; |
81a888fea perf hists browse... |
791 792 793 794 795 796 797 798 799 800 801 |
ret = fmt->header(fmt, &dummy_hpp, hists_to_evsel(hists)); if (advance_hpp_check(&dummy_hpp, ret)) break; ret = scnprintf(dummy_hpp.buf, dummy_hpp.size, " "); if (advance_hpp_check(&dummy_hpp, ret)) break; } return ret; } |
025bf7ea0 perf hists browse... |
802 803 |
static void hist_browser__show_headers(struct hist_browser *browser) { |
81a888fea perf hists browse... |
804 805 806 |
char headers[1024]; hists__scnprintf_headers(headers, sizeof(headers), browser->hists); |
025bf7ea0 perf hists browse... |
807 808 |
ui_browser__gotorc(&browser->b, 0, 0); ui_browser__set_color(&browser->b, HE_COLORSET_ROOT); |
81a888fea perf hists browse... |
809 |
slsmg_write_nstring(headers, browser->b.width + 1); |
025bf7ea0 perf hists browse... |
810 |
} |
437cfe7a3 perf hists browse... |
811 812 813 814 815 816 817 818 819 |
static void ui_browser__hists_init_top(struct ui_browser *browser) { if (browser->top == NULL) { struct hist_browser *hb; hb = container_of(browser, struct hist_browser, b); browser->top = rb_first(&hb->hists->entries); } } |
05e8b0804 perf ui browser: ... |
820 |
static unsigned int hist_browser__refresh(struct ui_browser *browser) |
d1b4f2491 perf ui: Move his... |
821 822 |
{ unsigned row = 0; |
025bf7ea0 perf hists browse... |
823 |
u16 header_offset = 0; |
d1b4f2491 perf ui: Move his... |
824 |
struct rb_node *nd; |
05e8b0804 perf ui browser: ... |
825 |
struct hist_browser *hb = container_of(browser, struct hist_browser, b); |
d1b4f2491 perf ui: Move his... |
826 |
|
025bf7ea0 perf hists browse... |
827 828 829 830 |
if (hb->show_headers) { hist_browser__show_headers(hb); header_offset = 1; } |
05e8b0804 perf ui browser: ... |
831 |
ui_browser__hists_init_top(browser); |
d1b4f2491 perf ui: Move his... |
832 |
|
05e8b0804 perf ui browser: ... |
833 |
for (nd = browser->top; nd; nd = rb_next(nd)) { |
d1b4f2491 perf ui: Move his... |
834 |
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); |
14135663f perf tools: Apply... |
835 |
float percent; |
d1b4f2491 perf ui: Move his... |
836 837 838 |
if (h->filtered) continue; |
14135663f perf tools: Apply... |
839 |
percent = hist_entry__get_percent_limit(h); |
064f19815 perf report: Add ... |
840 841 |
if (percent < hb->min_pcnt) continue; |
d1b4f2491 perf ui: Move his... |
842 |
row += hist_browser__show_entry(hb, h, row); |
62c95ae33 perf ui browser: ... |
843 |
if (row == browser->rows) |
d1b4f2491 perf ui: Move his... |
844 845 |
break; } |
025bf7ea0 perf hists browse... |
846 |
return row + header_offset; |
d1b4f2491 perf ui: Move his... |
847 |
} |
064f19815 perf report: Add ... |
848 |
static struct rb_node *hists__filter_entries(struct rb_node *nd, |
064f19815 perf report: Add ... |
849 |
float min_pcnt) |
d1b4f2491 perf ui: Move his... |
850 851 852 |
{ while (nd != NULL) { struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); |
14135663f perf tools: Apply... |
853 |
float percent = hist_entry__get_percent_limit(h); |
064f19815 perf report: Add ... |
854 |
|
c0f1527b7 perf report/tui: ... |
855 |
if (!h->filtered && percent >= min_pcnt) |
d1b4f2491 perf ui: Move his... |
856 857 858 859 860 861 862 |
return nd; nd = rb_next(nd); } return NULL; } |
064f19815 perf report: Add ... |
863 |
static struct rb_node *hists__filter_prev_entries(struct rb_node *nd, |
064f19815 perf report: Add ... |
864 |
float min_pcnt) |
d1b4f2491 perf ui: Move his... |
865 866 867 |
{ while (nd != NULL) { struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); |
14135663f perf tools: Apply... |
868 |
float percent = hist_entry__get_percent_limit(h); |
064f19815 perf report: Add ... |
869 870 |
if (!h->filtered && percent >= min_pcnt) |
d1b4f2491 perf ui: Move his... |
871 872 873 874 875 876 877 |
return nd; nd = rb_prev(nd); } return NULL; } |
05e8b0804 perf ui browser: ... |
878 |
static void ui_browser__hists_seek(struct ui_browser *browser, |
d1b4f2491 perf ui: Move his... |
879 880 881 882 883 |
off_t offset, int whence) { struct hist_entry *h; struct rb_node *nd; bool first = true; |
064f19815 perf report: Add ... |
884 885 886 |
struct hist_browser *hb; hb = container_of(browser, struct hist_browser, b); |
d1b4f2491 perf ui: Move his... |
887 |
|
05e8b0804 perf ui browser: ... |
888 |
if (browser->nr_entries == 0) |
60098917c perf hists browse... |
889 |
return; |
05e8b0804 perf ui browser: ... |
890 |
ui_browser__hists_init_top(browser); |
437cfe7a3 perf hists browse... |
891 |
|
d1b4f2491 perf ui: Move his... |
892 893 |
switch (whence) { case SEEK_SET: |
064f19815 perf report: Add ... |
894 |
nd = hists__filter_entries(rb_first(browser->entries), |
14135663f perf tools: Apply... |
895 |
hb->min_pcnt); |
d1b4f2491 perf ui: Move his... |
896 897 |
break; case SEEK_CUR: |
05e8b0804 perf ui browser: ... |
898 |
nd = browser->top; |
d1b4f2491 perf ui: Move his... |
899 900 |
goto do_offset; case SEEK_END: |
064f19815 perf report: Add ... |
901 |
nd = hists__filter_prev_entries(rb_last(browser->entries), |
14135663f perf tools: Apply... |
902 |
hb->min_pcnt); |
d1b4f2491 perf ui: Move his... |
903 904 905 906 907 908 909 910 911 912 |
first = false; break; default: return; } /* * Moves not relative to the first visible entry invalidates its * row_offset: */ |
05e8b0804 perf ui browser: ... |
913 |
h = rb_entry(browser->top, struct hist_entry, rb_node); |
d1b4f2491 perf ui: Move his... |
914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 |
h->row_offset = 0; /* * Here we have to check if nd is expanded (+), if it is we can't go * the next top level hist_entry, instead we must compute an offset of * what _not_ to show and not change the first visible entry. * * This offset increments when we are going from top to bottom and * decreases when we're going from bottom to top. * * As we don't have backpointers to the top level in the callchains * structure, we need to always print the whole hist_entry callchain, * skipping the first ones that are before the first visible entry * and stop when we printed enough lines to fill the screen. */ do_offset: if (offset > 0) { do { h = rb_entry(nd, struct hist_entry, rb_node); if (h->ms.unfolded) { u16 remaining = h->nr_rows - h->row_offset; if (offset > remaining) { offset -= remaining; h->row_offset = 0; } else { h->row_offset += offset; offset = 0; |
05e8b0804 perf ui browser: ... |
941 |
browser->top = nd; |
d1b4f2491 perf ui: Move his... |
942 943 944 |
break; } } |
14135663f perf tools: Apply... |
945 |
nd = hists__filter_entries(rb_next(nd), hb->min_pcnt); |
d1b4f2491 perf ui: Move his... |
946 947 948 |
if (nd == NULL) break; --offset; |
05e8b0804 perf ui browser: ... |
949 |
browser->top = nd; |
d1b4f2491 perf ui: Move his... |
950 951 952 953 954 955 956 957 958 959 960 961 |
} while (offset != 0); } else if (offset < 0) { while (1) { h = rb_entry(nd, struct hist_entry, rb_node); if (h->ms.unfolded) { if (first) { if (-offset > h->row_offset) { offset += h->row_offset; h->row_offset = 0; } else { h->row_offset += offset; offset = 0; |
05e8b0804 perf ui browser: ... |
962 |
browser->top = nd; |
d1b4f2491 perf ui: Move his... |
963 964 965 966 967 968 969 970 971 |
break; } } else { if (-offset > h->nr_rows) { offset += h->nr_rows; h->row_offset = 0; } else { h->row_offset = h->nr_rows + offset; offset = 0; |
05e8b0804 perf ui browser: ... |
972 |
browser->top = nd; |
d1b4f2491 perf ui: Move his... |
973 974 975 976 |
break; } } } |
14135663f perf tools: Apply... |
977 |
nd = hists__filter_prev_entries(rb_prev(nd), |
064f19815 perf report: Add ... |
978 |
hb->min_pcnt); |
d1b4f2491 perf ui: Move his... |
979 980 981 |
if (nd == NULL) break; ++offset; |
05e8b0804 perf ui browser: ... |
982 |
browser->top = nd; |
d1b4f2491 perf ui: Move his... |
983 984 985 986 987 988 989 990 991 992 993 994 995 996 |
if (offset == 0) { /* * Last unfiltered hist_entry, check if it is * unfolded, if it is then we should have * row_offset at its last entry. */ h = rb_entry(nd, struct hist_entry, rb_node); if (h->ms.unfolded) h->row_offset = h->nr_rows; break; } first = false; } } else { |
05e8b0804 perf ui browser: ... |
997 |
browser->top = nd; |
d1b4f2491 perf ui: Move his... |
998 999 1000 1001 |
h = rb_entry(nd, struct hist_entry, rb_node); h->row_offset = 0; } } |
aff3f3f68 perf hists browse... |
1002 |
static int hist_browser__fprintf_callchain(struct hist_browser *browser, |
39ee533fc perf hists browse... |
1003 |
struct hist_entry *he, FILE *fp) |
aff3f3f68 perf hists browse... |
1004 |
{ |
39ee533fc perf hists browse... |
1005 1006 1007 1008 |
u64 total = hists__total_period(he->hists); struct callchain_print_arg arg = { .fp = fp, }; |
aff3f3f68 perf hists browse... |
1009 |
|
39ee533fc perf hists browse... |
1010 1011 |
if (symbol_conf.cumulate_callchain) total = he->stat_acc->period; |
aff3f3f68 perf hists browse... |
1012 |
|
39ee533fc perf hists browse... |
1013 1014 1015 1016 |
hist_browser__show_callchain(browser, &he->sorted_chain, 1, 0, total, hist_browser__fprintf_callchain_entry, &arg, hist_browser__check_dump_full); return arg.printed; |
aff3f3f68 perf hists browse... |
1017 1018 1019 1020 1021 1022 |
} static int hist_browser__fprintf_entry(struct hist_browser *browser, struct hist_entry *he, FILE *fp) { char s[8192]; |
aff3f3f68 perf hists browse... |
1023 1024 |
int printed = 0; char folded_sign = ' '; |
26d8b3382 perf tools: Conso... |
1025 1026 1027 1028 1029 1030 1031 |
struct perf_hpp hpp = { .buf = s, .size = sizeof(s), }; struct perf_hpp_fmt *fmt; bool first = true; int ret; |
aff3f3f68 perf hists browse... |
1032 1033 1034 |
if (symbol_conf.use_callchain) folded_sign = hist_entry__folded(he); |
aff3f3f68 perf hists browse... |
1035 1036 |
if (symbol_conf.use_callchain) printed += fprintf(fp, "%c ", folded_sign); |
26d8b3382 perf tools: Conso... |
1037 |
perf_hpp__for_each_format(fmt) { |
e67d49a72 perf tools: Skip ... |
1038 1039 |
if (perf_hpp__should_skip(fmt)) continue; |
26d8b3382 perf tools: Conso... |
1040 1041 1042 1043 1044 |
if (!first) { ret = scnprintf(hpp.buf, hpp.size, " "); advance_hpp(&hpp, ret); } else first = false; |
aff3f3f68 perf hists browse... |
1045 |
|
26d8b3382 perf tools: Conso... |
1046 1047 1048 |
ret = fmt->entry(fmt, &hpp, he); advance_hpp(&hpp, ret); } |
aff3f3f68 perf hists browse... |
1049 1050 1051 1052 |
printed += fprintf(fp, "%s ", rtrim(s)); if (folded_sign == '-') |
39ee533fc perf hists browse... |
1053 |
printed += hist_browser__fprintf_callchain(browser, he, fp); |
aff3f3f68 perf hists browse... |
1054 1055 1056 1057 1058 1059 |
return printed; } static int hist_browser__fprintf(struct hist_browser *browser, FILE *fp) { |
064f19815 perf report: Add ... |
1060 |
struct rb_node *nd = hists__filter_entries(rb_first(browser->b.entries), |
064f19815 perf report: Add ... |
1061 |
browser->min_pcnt); |
aff3f3f68 perf hists browse... |
1062 1063 1064 1065 1066 1067 |
int printed = 0; while (nd) { struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); printed += hist_browser__fprintf_entry(browser, h, fp); |
14135663f perf tools: Apply... |
1068 |
nd = hists__filter_entries(rb_next(nd), browser->min_pcnt); |
aff3f3f68 perf hists browse... |
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 |
} return printed; } static int hist_browser__dump(struct hist_browser *browser) { char filename[64]; FILE *fp; while (1) { scnprintf(filename, sizeof(filename), "perf.hist.%d", browser->print_seq); if (access(filename, F_OK)) break; /* * XXX: Just an arbitrary lazy upper limit */ if (++browser->print_seq == 8192) { ui_helpline__fpush("Too many perf.hist.N files, nothing written!"); return -1; } } fp = fopen(filename, "w"); if (fp == NULL) { char bf[64]; |
4cc49d4dc perf tools: use X... |
1095 1096 |
const char *err = strerror_r(errno, bf, sizeof(bf)); ui_helpline__fpush("Couldn't write to %s: %s", filename, err); |
aff3f3f68 perf hists browse... |
1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 |
return -1; } ++browser->print_seq; hist_browser__fprintf(browser, fp); fclose(fp); ui_helpline__fpush("%s written!", filename); return 0; } |
d1b4f2491 perf ui: Move his... |
1107 1108 |
static struct hist_browser *hist_browser__new(struct hists *hists) { |
05e8b0804 perf ui browser: ... |
1109 |
struct hist_browser *browser = zalloc(sizeof(*browser)); |
d1b4f2491 perf ui: Move his... |
1110 |
|
05e8b0804 perf ui browser: ... |
1111 1112 1113 |
if (browser) { browser->hists = hists; browser->b.refresh = hist_browser__refresh; |
357cfff1c perf hists browse... |
1114 |
browser->b.refresh_dimensions = hist_browser__refresh_dimensions; |
05e8b0804 perf ui browser: ... |
1115 1116 |
browser->b.seek = ui_browser__hists_seek; browser->b.use_navkeypressed = true; |
c83023676 perf hists browse... |
1117 |
browser->show_headers = symbol_conf.show_hist_headers; |
d1b4f2491 perf ui: Move his... |
1118 |
} |
05e8b0804 perf ui browser: ... |
1119 |
return browser; |
d1b4f2491 perf ui: Move his... |
1120 |
} |
05e8b0804 perf ui browser: ... |
1121 |
static void hist_browser__delete(struct hist_browser *browser) |
d1b4f2491 perf ui: Move his... |
1122 |
{ |
05e8b0804 perf ui browser: ... |
1123 |
free(browser); |
d1b4f2491 perf ui: Move his... |
1124 |
} |
05e8b0804 perf ui browser: ... |
1125 |
static struct hist_entry *hist_browser__selected_entry(struct hist_browser *browser) |
d1b4f2491 perf ui: Move his... |
1126 |
{ |
05e8b0804 perf ui browser: ... |
1127 |
return browser->he_selection; |
d1b4f2491 perf ui: Move his... |
1128 |
} |
05e8b0804 perf ui browser: ... |
1129 |
static struct thread *hist_browser__selected_thread(struct hist_browser *browser) |
d1b4f2491 perf ui: Move his... |
1130 |
{ |
05e8b0804 perf ui browser: ... |
1131 |
return browser->he_selection->thread; |
d1b4f2491 perf ui: Move his... |
1132 |
} |
1e378ebd1 perf top: Add a v... |
1133 1134 1135 1136 1137 1138 1139 1140 1141 |
/* Check whether the browser is for 'top' or 'report' */ static inline bool is_report_browser(void *timer) { return timer == NULL; } static int hists__browser_title(struct hists *hists, struct hist_browser_timer *hbt, char *bf, size_t size) |
d1b4f2491 perf ui: Move his... |
1142 |
{ |
469917ce8 perf ui browser: ... |
1143 1144 |
char unit; int printed; |
05e8b0804 perf ui browser: ... |
1145 1146 1147 1148 |
const struct dso *dso = hists->dso_filter; const struct thread *thread = hists->thread_filter; unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE]; u64 nr_events = hists->stats.total_period; |
717e263fc perf report: Show... |
1149 |
struct perf_evsel *evsel = hists_to_evsel(hists); |
dd00d486d perf hists browse... |
1150 |
const char *ev_name = perf_evsel__name(evsel); |
717e263fc perf report: Show... |
1151 1152 |
char buf[512]; size_t buflen = sizeof(buf); |
f21483305 perf report: Add ... |
1153 1154 1155 1156 |
if (symbol_conf.filter_relative) { nr_samples = hists->stats.nr_non_filtered_samples; nr_events = hists->stats.total_non_filtered_period; } |
759ff497e perf evsel: Intro... |
1157 |
if (perf_evsel__is_group_event(evsel)) { |
717e263fc perf report: Show... |
1158 1159 1160 1161 1162 1163 |
struct perf_evsel *pos; perf_evsel__group_desc(evsel, buf, buflen); ev_name = buf; for_each_group_member(pos, evsel) { |
4ea062ed4 perf evsel: Add h... |
1164 |
struct hists *pos_hists = evsel__hists(pos); |
f21483305 perf report: Add ... |
1165 |
if (symbol_conf.filter_relative) { |
4ea062ed4 perf evsel: Add h... |
1166 1167 |
nr_samples += pos_hists->stats.nr_non_filtered_samples; nr_events += pos_hists->stats.total_non_filtered_period; |
f21483305 perf report: Add ... |
1168 |
} else { |
4ea062ed4 perf evsel: Add h... |
1169 1170 |
nr_samples += pos_hists->stats.nr_events[PERF_RECORD_SAMPLE]; nr_events += pos_hists->stats.total_period; |
f21483305 perf report: Add ... |
1171 |
} |
717e263fc perf report: Show... |
1172 1173 |
} } |
cc6862809 perf report: Corr... |
1174 1175 1176 |
nr_samples = convert_unit(nr_samples, &unit); printed = scnprintf(bf, size, |
e641f696e perf hists browse... |
1177 |
"Samples: %lu%c of event '%s', Event count (approx.): %" PRIu64, |
cc6862809 perf report: Corr... |
1178 |
nr_samples, unit, ev_name, nr_events); |
469917ce8 perf ui browser: ... |
1179 |
|
d1b4f2491 perf ui: Move his... |
1180 |
|
05e8b0804 perf ui browser: ... |
1181 |
if (hists->uid_filter_str) |
0d37aa34f perf tools: Intro... |
1182 |
printed += snprintf(bf + printed, size - printed, |
05e8b0804 perf ui browser: ... |
1183 |
", UID: %s", hists->uid_filter_str); |
d1b4f2491 perf ui: Move his... |
1184 |
if (thread) |
e7f01d1e3 perf tools: Use s... |
1185 |
printed += scnprintf(bf + printed, size - printed, |
469917ce8 perf ui browser: ... |
1186 |
", Thread: %s(%d)", |
b9c5143a0 perf tools: Use a... |
1187 |
(thread->comm_set ? thread__comm_str(thread) : ""), |
380512345 perf tools: struc... |
1188 |
thread->tid); |
d1b4f2491 perf ui: Move his... |
1189 |
if (dso) |
e7f01d1e3 perf tools: Use s... |
1190 |
printed += scnprintf(bf + printed, size - printed, |
469917ce8 perf ui browser: ... |
1191 |
", DSO: %s", dso->short_name); |
1e378ebd1 perf top: Add a v... |
1192 1193 1194 1195 1196 1197 |
if (!is_report_browser(hbt)) { struct perf_top *top = hbt->arg; if (top->zero) printed += scnprintf(bf + printed, size - printed, " [z]"); } |
469917ce8 perf ui browser: ... |
1198 |
return printed; |
d1b4f2491 perf ui: Move his... |
1199 |
} |
24bff2dc0 perf report: Fix ... |
1200 1201 1202 |
static inline void free_popup_options(char **options, int n) { int i; |
046625231 perf tools: Intro... |
1203 1204 |
for (i = 0; i < n; ++i) zfree(&options[i]); |
24bff2dc0 perf report: Fix ... |
1205 |
} |
341487ab5 perf hists browse... |
1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 |
/* * Only runtime switching of perf data file will make "input_name" point * to a malloced buffer. So add "is_input_name_malloced" flag to decide * whether we need to call free() for current "input_name" during the switch. */ static bool is_input_name_malloced = false; static int switch_data_file(void) { char *pwd, *options[32], *abs_path[32], *tmp; DIR *pwd_dir; int nr_options = 0, choice = -1, ret = -1; struct dirent *dent; pwd = getenv("PWD"); if (!pwd) return ret; pwd_dir = opendir(pwd); if (!pwd_dir) return ret; memset(options, 0, sizeof(options)); memset(options, 0, sizeof(abs_path)); while ((dent = readdir(pwd_dir))) { char path[PATH_MAX]; u64 magic; char *name = dent->d_name; FILE *file; if (!(dent->d_type == DT_REG)) continue; snprintf(path, sizeof(path), "%s/%s", pwd, name); file = fopen(path, "r"); if (!file) continue; if (fread(&magic, 1, 8, file) < 8) goto close_file_and_continue; if (is_perf_magic(magic)) { options[nr_options] = strdup(name); if (!options[nr_options]) goto close_file_and_continue; abs_path[nr_options] = strdup(path); if (!abs_path[nr_options]) { |
74cf249d5 perf tools: Use z... |
1256 |
zfree(&options[nr_options]); |
341487ab5 perf hists browse... |
1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 |
ui__warning("Can't search all data files due to memory shortage. "); fclose(file); break; } nr_options++; } close_file_and_continue: fclose(file); if (nr_options >= 32) { ui__warning("Too many perf data files in PWD! " "Only the first 32 files will be listed. "); break; } } closedir(pwd_dir); if (nr_options) { choice = ui__popup_menu(nr_options, options); if (choice < nr_options && choice >= 0) { tmp = strdup(abs_path[choice]); if (tmp) { if (is_input_name_malloced) free((void *)input_name); input_name = tmp; is_input_name_malloced = true; ret = 0; } else ui__warning("Data switch failed due to memory shortage! "); } } free_popup_options(options, nr_options); free_popup_options(abs_path, nr_options); return ret; } |
112f761fc perf ui/tui: Rena... |
1298 |
static void hist_browser__update_nr_entries(struct hist_browser *hb) |
064f19815 perf report: Add ... |
1299 1300 1301 |
{ u64 nr_entries = 0; struct rb_node *nd = rb_first(&hb->hists->entries); |
268397cb2 perf top/tui: Upd... |
1302 1303 1304 1305 |
if (hb->min_pcnt == 0) { hb->nr_non_filtered_entries = hb->hists->nr_non_filtered_entries; return; } |
14135663f perf tools: Apply... |
1306 |
while ((nd = hists__filter_entries(nd, hb->min_pcnt)) != NULL) { |
064f19815 perf report: Add ... |
1307 |
nr_entries++; |
c481f9301 perf ui/tui: Fix ... |
1308 |
nd = rb_next(nd); |
064f19815 perf report: Add ... |
1309 |
} |
112f761fc perf ui/tui: Rena... |
1310 |
hb->nr_non_filtered_entries = nr_entries; |
064f19815 perf report: Add ... |
1311 |
} |
341487ab5 perf hists browse... |
1312 |
|
34958544b perf annotate bro... |
1313 |
static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, |
dd00d486d perf hists browse... |
1314 |
const char *helpline, |
81cce8de9 perf browsers: Ad... |
1315 |
bool left_exits, |
68d807586 perf report: Post... |
1316 |
struct hist_browser_timer *hbt, |
064f19815 perf report: Add ... |
1317 |
float min_pcnt, |
68d807586 perf report: Post... |
1318 |
struct perf_session_env *env) |
d1b4f2491 perf ui: Move his... |
1319 |
{ |
4ea062ed4 perf evsel: Add h... |
1320 |
struct hists *hists = evsel__hists(evsel); |
05e8b0804 perf ui browser: ... |
1321 |
struct hist_browser *browser = hist_browser__new(hists); |
a68c2c581 perf report: Enab... |
1322 |
struct branch_info *bi; |
d1b4f2491 perf ui: Move his... |
1323 |
struct pstack *fstack; |
24bff2dc0 perf report: Fix ... |
1324 1325 |
char *options[16]; int nr_options = 0; |
d1b4f2491 perf ui: Move his... |
1326 |
int key = -1; |
938a23ae7 perf ui browser: ... |
1327 |
char buf[64]; |
cdbab7c20 perf hists browse... |
1328 |
char script_opt[64]; |
9783adf77 perf tools: Intro... |
1329 |
int delay_secs = hbt ? hbt->refresh : 0; |
59dc9f253 perf tools: Fix c... |
1330 |
struct perf_hpp_fmt *fmt; |
d1b4f2491 perf ui: Move his... |
1331 |
|
e8e684a58 perf ui/tui: Spli... |
1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 |
#define HIST_BROWSER_HELP_COMMON \ "h/?/F1 Show this window " \ "UP/DOWN/PGUP " \ "PGDN/SPACE Navigate " \ "q/ESC/CTRL+C Exit browser " \ "For multiple event sessions: " \ "TAB/UNTAB Switch events " \ "For symbolic views (--sort has sym): " \ "-> Zoom into DSO/Threads & Annotate current symbol " \ "<- Zoom out " \ "a Annotate current symbol " \ "C Collapse all callchains " \ "d Zoom into current DSO " \ "E Expand all callchains " \ |
105eb30f1 perf ui/tui: Add ... |
1363 1364 |
"F Toggle percentage of filtered entries " \ |
025bf7ea0 perf hists browse... |
1365 1366 |
"H Display column headers " \ |
e8e684a58 perf ui/tui: Spli... |
1367 1368 1369 |
/* help messages are sorted by lexical order of the hotkey */ const char report_help[] = HIST_BROWSER_HELP_COMMON |
6dd601354 perf ui/tui: Impl... |
1370 1371 |
"i Show header information " |
e8e684a58 perf ui/tui: Spli... |
1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 |
"P Print histograms to perf.hist.N " "r Run available scripts " "s Switch to another data file in PWD " "t Zoom into current Thread " "V Verbose (DSO names in callchains, etc) " "/ Filter symbol by name"; const char top_help[] = HIST_BROWSER_HELP_COMMON "P Print histograms to perf.hist.N " "t Zoom into current Thread " "V Verbose (DSO names in callchains, etc) " |
42337a222 perf top: Handle ... |
1390 1391 |
"z Toggle zeroing of samples " |
e8e684a58 perf ui/tui: Spli... |
1392 |
"/ Filter symbol by name"; |
d1b4f2491 perf ui: Move his... |
1393 1394 |
if (browser == NULL) return -1; |
064f19815 perf report: Add ... |
1395 1396 |
if (min_pcnt) { browser->min_pcnt = min_pcnt; |
112f761fc perf ui/tui: Rena... |
1397 |
hist_browser__update_nr_entries(browser); |
064f19815 perf report: Add ... |
1398 |
} |
d1b4f2491 perf ui: Move his... |
1399 1400 1401 1402 1403 |
fstack = pstack__new(2); if (fstack == NULL) goto out; ui_helpline__push(helpline); |
24bff2dc0 perf report: Fix ... |
1404 |
memset(options, 0, sizeof(options)); |
59dc9f253 perf tools: Fix c... |
1405 1406 |
perf_hpp__for_each_format(fmt) perf_hpp__reset_width(fmt, hists); |
5b5916696 perf report: Hono... |
1407 1408 |
if (symbol_conf.col_width_list_str) perf_hpp__set_user_width(symbol_conf.col_width_list_str); |
d1b4f2491 perf ui: Move his... |
1409 |
while (1) { |
60098917c perf hists browse... |
1410 1411 |
const struct thread *thread = NULL; const struct dso *dso = NULL; |
24bff2dc0 perf report: Fix ... |
1412 |
int choice = 0, |
d1b4f2491 perf ui: Move his... |
1413 |
annotate = -2, zoom_dso = -2, zoom_thread = -2, |
a68c2c581 perf report: Enab... |
1414 |
annotate_f = -2, annotate_t = -2, browse_map = -2; |
341487ab5 perf hists browse... |
1415 1416 |
int scripts_comm = -2, scripts_symbol = -2, scripts_all = -2, switch_data = -2; |
d1b4f2491 perf ui: Move his... |
1417 |
|
24bff2dc0 perf report: Fix ... |
1418 |
nr_options = 0; |
dd00d486d perf hists browse... |
1419 |
key = hist_browser__run(browser, hbt); |
d1b4f2491 perf ui: Move his... |
1420 |
|
60098917c perf hists browse... |
1421 1422 1423 1424 |
if (browser->he_selection != NULL) { thread = hist_browser__selected_thread(browser); dso = browser->selection->map ? browser->selection->map->dso : NULL; } |
b50e003db perf ui browser: ... |
1425 |
switch (key) { |
cf9580036 perf ui browser: ... |
1426 1427 |
case K_TAB: case K_UNTAB: |
e4419b8ed perf hists browse... |
1428 1429 |
if (nr_events == 1) continue; |
b50e003db perf ui browser: ... |
1430 1431 1432 1433 1434 1435 |
/* * Exit the browser, let hists__browser_tree * go to the next or previous */ goto out_free_stack; case 'a': |
9c796ec8d perf hists browse... |
1436 |
if (!sort__has_sym) { |
7b27509fc perf hists browse... |
1437 |
ui_browser__warning(&browser->b, delay_secs * 2, |
a6e51f9fa perf hists browse... |
1438 |
"Annotation is only available for symbolic views, " |
a68c2c581 perf report: Enab... |
1439 |
"include \"sym*\" in --sort to use it."); |
a6e51f9fa perf hists browse... |
1440 1441 |
continue; } |
60098917c perf hists browse... |
1442 |
if (browser->selection == NULL || |
db9a9cbc8 perf hists browse... |
1443 |
browser->selection->sym == NULL || |
b50e003db perf ui browser: ... |
1444 |
browser->selection->map->dso->annotate_warned) |
d1b4f2491 perf ui: Move his... |
1445 |
continue; |
b50e003db perf ui browser: ... |
1446 |
goto do_annotate; |
aff3f3f68 perf hists browse... |
1447 1448 1449 |
case 'P': hist_browser__dump(browser); continue; |
b50e003db perf ui browser: ... |
1450 1451 |
case 'd': goto zoom_dso; |
a7cb8863d perf hists browse... |
1452 1453 1454 |
case 'V': browser->show_dso = !browser->show_dso; continue; |
b50e003db perf ui browser: ... |
1455 1456 |
case 't': goto zoom_thread; |
5a5626b1b perf hists browse... |
1457 |
case '/': |
938a23ae7 perf ui browser: ... |
1458 1459 1460 1461 |
if (ui_browser__input_window("Symbol to show", "Please enter the name of symbol you want to see", buf, "ENTER: OK, ESC: Cancel", delay_secs * 2) == K_ENTER) { |
05e8b0804 perf ui browser: ... |
1462 1463 |
hists->symbol_filter_str = *buf ? buf : NULL; hists__filter_by_symbol(hists); |
938a23ae7 perf ui browser: ... |
1464 1465 1466 |
hist_browser__reset(browser); } continue; |
cdbab7c20 perf hists browse... |
1467 |
case 'r': |
9783adf77 perf tools: Intro... |
1468 |
if (is_report_browser(hbt)) |
c77d8d703 perf browser: Don... |
1469 1470 |
goto do_scripts; continue; |
341487ab5 perf hists browse... |
1471 1472 1473 1474 |
case 's': if (is_report_browser(hbt)) goto do_data_switch; continue; |
6dd601354 perf ui/tui: Impl... |
1475 1476 1477 1478 1479 |
case 'i': /* env->arch is NULL for live-mode (i.e. perf top) */ if (env->arch) tui__header_window(env); continue; |
105eb30f1 perf ui/tui: Add ... |
1480 1481 1482 |
case 'F': symbol_conf.filter_relative ^= 1; continue; |
42337a222 perf top: Handle ... |
1483 1484 1485 1486 1487 1488 1489 |
case 'z': if (!is_report_browser(hbt)) { struct perf_top *top = hbt->arg; top->zero = !top->zero; } continue; |
cf9580036 perf ui browser: ... |
1490 |
case K_F1: |
b50e003db perf ui browser: ... |
1491 1492 |
case 'h': case '?': |
4610e4137 perf ui browser: ... |
1493 |
ui_browser__help_window(&browser->b, |
e8e684a58 perf ui/tui: Spli... |
1494 |
is_report_browser(hbt) ? report_help : top_help); |
b50e003db perf ui browser: ... |
1495 |
continue; |
cf9580036 perf ui browser: ... |
1496 1497 |
case K_ENTER: case K_RIGHT: |
b50e003db perf ui browser: ... |
1498 1499 |
/* menu */ break; |
cf9580036 perf ui browser: ... |
1500 |
case K_LEFT: { |
b50e003db perf ui browser: ... |
1501 |
const void *top; |
d1b4f2491 perf ui: Move his... |
1502 |
|
7f0030b21 perf report tui: ... |
1503 1504 1505 1506 1507 1508 |
if (pstack__empty(fstack)) { /* * Go back to the perf_evsel_menu__run or other user */ if (left_exits) goto out_free_stack; |
d1b4f2491 perf ui: Move his... |
1509 |
continue; |
7f0030b21 perf report tui: ... |
1510 |
} |
b50e003db perf ui browser: ... |
1511 |
top = pstack__pop(fstack); |
d7b76f093 perf hists: Move ... |
1512 |
if (top == &browser->hists->dso_filter) |
b50e003db perf ui browser: ... |
1513 |
goto zoom_out_dso; |
d7b76f093 perf hists: Move ... |
1514 |
if (top == &browser->hists->thread_filter) |
b50e003db perf ui browser: ... |
1515 1516 1517 |
goto zoom_out_thread; continue; } |
cf9580036 perf ui browser: ... |
1518 |
case K_ESC: |
7f0030b21 perf report tui: ... |
1519 |
if (!left_exits && |
4610e4137 perf ui browser: ... |
1520 1521 |
!ui_browser__dialog_yesno(&browser->b, "Do you really want to exit?")) |
b50e003db perf ui browser: ... |
1522 1523 |
continue; /* Fall thru */ |
ed7e5662d perf ui browser: ... |
1524 1525 |
case 'q': case CTRL('c'): |
b50e003db perf ui browser: ... |
1526 |
goto out_free_stack; |
ed7e5662d perf ui browser: ... |
1527 1528 |
default: continue; |
d1b4f2491 perf ui: Move his... |
1529 |
} |
9c796ec8d perf hists browse... |
1530 |
if (!sort__has_sym) |
724c9c9f2 perf hists browse... |
1531 |
goto add_exit_option; |
55369fc17 perf sort: Introd... |
1532 |
if (sort__mode == SORT_MODE__BRANCH) { |
a68c2c581 perf report: Enab... |
1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 |
bi = browser->he_selection->branch_info; if (browser->selection != NULL && bi && bi->from.sym != NULL && !bi->from.map->dso->annotate_warned && asprintf(&options[nr_options], "Annotate %s", bi->from.sym->name) > 0) annotate_f = nr_options++; if (browser->selection != NULL && bi && bi->to.sym != NULL && !bi->to.map->dso->annotate_warned && |
8bcd65fd2 perf report: Remo... |
1546 1547 |
(bi->to.sym != bi->from.sym || bi->to.map->dso != bi->from.map->dso) && |
a68c2c581 perf report: Enab... |
1548 1549 1550 1551 |
asprintf(&options[nr_options], "Annotate %s", bi->to.sym->name) > 0) annotate_t = nr_options++; } else { |
a68c2c581 perf report: Enab... |
1552 1553 |
if (browser->selection != NULL && browser->selection->sym != NULL && |
d755330c5 perf tools: Fix s... |
1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 |
!browser->selection->map->dso->annotate_warned) { struct annotation *notes; notes = symbol__annotation(browser->selection->sym); if (notes->src && asprintf(&options[nr_options], "Annotate %s", browser->selection->sym->name) > 0) annotate = nr_options++; } |
a68c2c581 perf report: Enab... |
1564 |
} |
d1b4f2491 perf ui: Move his... |
1565 1566 1567 |
if (thread != NULL && asprintf(&options[nr_options], "Zoom %s %s(%d) thread", |
d7b76f093 perf hists: Move ... |
1568 |
(browser->hists->thread_filter ? "out of" : "into"), |
b9c5143a0 perf tools: Use a... |
1569 |
(thread->comm_set ? thread__comm_str(thread) : ""), |
380512345 perf tools: struc... |
1570 |
thread->tid) > 0) |
d1b4f2491 perf ui: Move his... |
1571 1572 1573 1574 |
zoom_thread = nr_options++; if (dso != NULL && asprintf(&options[nr_options], "Zoom %s %s DSO", |
d7b76f093 perf hists: Move ... |
1575 |
(browser->hists->dso_filter ? "out of" : "into"), |
d1b4f2491 perf ui: Move his... |
1576 1577 |
(dso->kernel ? "the Kernel" : dso->short_name)) > 0) zoom_dso = nr_options++; |
60098917c perf hists browse... |
1578 1579 |
if (browser->selection != NULL && browser->selection->map != NULL && |
d1b4f2491 perf ui: Move his... |
1580 1581 |
asprintf(&options[nr_options], "Browse map details") > 0) browse_map = nr_options++; |
cdbab7c20 perf hists browse... |
1582 1583 1584 1585 1586 1587 |
/* perf script support */ if (browser->he_selection) { struct symbol *sym; if (asprintf(&options[nr_options], "Run scripts for samples of thread [%s]", |
b9c5143a0 perf tools: Use a... |
1588 |
thread__comm_str(browser->he_selection->thread)) > 0) |
cdbab7c20 perf hists browse... |
1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 |
scripts_comm = nr_options++; sym = browser->he_selection->ms.sym; if (sym && sym->namelen && asprintf(&options[nr_options], "Run scripts for samples of symbol [%s]", sym->name) > 0) scripts_symbol = nr_options++; } if (asprintf(&options[nr_options], "Run scripts for all samples") > 0) scripts_all = nr_options++; |
341487ab5 perf hists browse... |
1600 1601 1602 |
if (is_report_browser(hbt) && asprintf(&options[nr_options], "Switch to another data file in PWD") > 0) switch_data = nr_options++; |
724c9c9f2 perf hists browse... |
1603 |
add_exit_option: |
d1b4f2491 perf ui: Move his... |
1604 |
options[nr_options++] = (char *)"Exit"; |
24bff2dc0 perf report: Fix ... |
1605 |
retry_popup_menu: |
1e6dd077a perf ui: Complete... |
1606 |
choice = ui__popup_menu(nr_options, options); |
d1b4f2491 perf ui: Move his... |
1607 |
|
d1b4f2491 perf ui: Move his... |
1608 1609 |
if (choice == nr_options - 1) break; |
24bff2dc0 perf report: Fix ... |
1610 1611 |
if (choice == -1) { free_popup_options(options, nr_options - 1); |
d1b4f2491 perf ui: Move his... |
1612 |
continue; |
24bff2dc0 perf report: Fix ... |
1613 |
} |
d1b4f2491 perf ui: Move his... |
1614 |
|
a68c2c581 perf report: Enab... |
1615 |
if (choice == annotate || choice == annotate_t || choice == annotate_f) { |
d1b4f2491 perf ui: Move his... |
1616 |
struct hist_entry *he; |
d755330c5 perf tools: Fix s... |
1617 |
struct annotation *notes; |
4610e4137 perf ui browser: ... |
1618 |
int err; |
d1b4f2491 perf ui: Move his... |
1619 |
do_annotate: |
68d807586 perf report: Post... |
1620 1621 |
if (!objdump_path && perf_session_env__lookup_objdump(env)) continue; |
d1b4f2491 perf ui: Move his... |
1622 1623 1624 |
he = hist_browser__selected_entry(browser); if (he == NULL) continue; |
a68c2c581 perf report: Enab... |
1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 |
/* * we stash the branch_info symbol + map into the * the ms so we don't have to rewrite all the annotation * code to use branch_info. * in branch mode, the ms struct is not used */ if (choice == annotate_f) { he->ms.sym = he->branch_info->from.sym; he->ms.map = he->branch_info->from.map; } else if (choice == annotate_t) { he->ms.sym = he->branch_info->to.sym; he->ms.map = he->branch_info->to.map; } |
d755330c5 perf tools: Fix s... |
1639 1640 1641 |
notes = symbol__annotation(he->ms.sym); if (!notes->src) continue; |
df71d95f8 perf hists: Don't... |
1642 1643 1644 1645 |
/* * Don't let this be freed, say, by hists__decay_entry. */ he->used = true; |
db8fd07a5 perf annotate: Pa... |
1646 |
err = hist_entry__tui_annotate(he, evsel, hbt); |
df71d95f8 perf hists: Don't... |
1647 |
he->used = false; |
24bff2dc0 perf report: Fix ... |
1648 1649 1650 1651 1652 1653 1654 |
/* * offer option to annotate the other branch source or target * (if they exists) when returning from annotate */ if ((err == 'q' || err == CTRL('c')) && annotate_t != -2 && annotate_f != -2) goto retry_popup_menu; |
900e14a8f perf hists browse... |
1655 |
ui_browser__update_nr_entries(&browser->b, browser->hists->nr_entries); |
4610e4137 perf ui browser: ... |
1656 1657 |
if (err) ui_browser__handle_resize(&browser->b); |
24bff2dc0 perf report: Fix ... |
1658 |
|
d1b4f2491 perf ui: Move his... |
1659 1660 1661 1662 |
} else if (choice == browse_map) map__browse(browser->selection->map); else if (choice == zoom_dso) { zoom_dso: |
d7b76f093 perf hists: Move ... |
1663 1664 |
if (browser->hists->dso_filter) { pstack__remove(fstack, &browser->hists->dso_filter); |
d1b4f2491 perf ui: Move his... |
1665 1666 |
zoom_out_dso: ui_helpline__pop(); |
d7b76f093 perf hists: Move ... |
1667 |
browser->hists->dso_filter = NULL; |
f29984226 perf tools: Move ... |
1668 |
perf_hpp__set_elide(HISTC_DSO, false); |
d1b4f2491 perf ui: Move his... |
1669 1670 1671 1672 1673 |
} else { if (dso == NULL) continue; ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s DSO\"", dso->kernel ? "the Kernel" : dso->short_name); |
d7b76f093 perf hists: Move ... |
1674 |
browser->hists->dso_filter = dso; |
f29984226 perf tools: Move ... |
1675 |
perf_hpp__set_elide(HISTC_DSO, true); |
d7b76f093 perf hists: Move ... |
1676 |
pstack__push(fstack, &browser->hists->dso_filter); |
d1b4f2491 perf ui: Move his... |
1677 |
} |
05e8b0804 perf ui browser: ... |
1678 |
hists__filter_by_dso(hists); |
d1b4f2491 perf ui: Move his... |
1679 1680 1681 |
hist_browser__reset(browser); } else if (choice == zoom_thread) { zoom_thread: |
d7b76f093 perf hists: Move ... |
1682 1683 |
if (browser->hists->thread_filter) { pstack__remove(fstack, &browser->hists->thread_filter); |
d1b4f2491 perf ui: Move his... |
1684 1685 |
zoom_out_thread: ui_helpline__pop(); |
d7b76f093 perf hists: Move ... |
1686 |
browser->hists->thread_filter = NULL; |
f29984226 perf tools: Move ... |
1687 |
perf_hpp__set_elide(HISTC_THREAD, false); |
d1b4f2491 perf ui: Move his... |
1688 1689 |
} else { ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s(%d) thread\"", |
b9c5143a0 perf tools: Use a... |
1690 |
thread->comm_set ? thread__comm_str(thread) : "", |
380512345 perf tools: struc... |
1691 |
thread->tid); |
d7b76f093 perf hists: Move ... |
1692 |
browser->hists->thread_filter = thread; |
f29984226 perf tools: Move ... |
1693 |
perf_hpp__set_elide(HISTC_THREAD, false); |
d7b76f093 perf hists: Move ... |
1694 |
pstack__push(fstack, &browser->hists->thread_filter); |
d1b4f2491 perf ui: Move his... |
1695 |
} |
05e8b0804 perf ui browser: ... |
1696 |
hists__filter_by_thread(hists); |
d1b4f2491 perf ui: Move his... |
1697 1698 |
hist_browser__reset(browser); } |
cdbab7c20 perf hists browse... |
1699 1700 1701 1702 1703 1704 1705 |
/* perf scripts support */ else if (choice == scripts_all || choice == scripts_comm || choice == scripts_symbol) { do_scripts: memset(script_opt, 0, 64); if (choice == scripts_comm) |
b9c5143a0 perf tools: Use a... |
1706 |
sprintf(script_opt, " -c %s ", thread__comm_str(browser->he_selection->thread)); |
cdbab7c20 perf hists browse... |
1707 1708 1709 1710 1711 1712 |
if (choice == scripts_symbol) sprintf(script_opt, " -S %s ", browser->he_selection->ms.sym->name); script_browse(script_opt); } |
341487ab5 perf hists browse... |
1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 |
/* Switch to another data file */ else if (choice == switch_data) { do_data_switch: if (!switch_data_file()) { key = K_SWITCH_INPUT_DATA; break; } else ui__warning("Won't switch the data files due to " "no valid data file get selected! "); } |
d1b4f2491 perf ui: Move his... |
1725 1726 1727 1728 1729 |
} out_free_stack: pstack__delete(fstack); out: hist_browser__delete(browser); |
24bff2dc0 perf report: Fix ... |
1730 |
free_popup_options(options, nr_options - 1); |
d1b4f2491 perf ui: Move his... |
1731 1732 |
return key; } |
7f0030b21 perf report tui: ... |
1733 1734 1735 |
struct perf_evsel_menu { struct ui_browser b; struct perf_evsel *selection; |
7b27509fc perf hists browse... |
1736 |
bool lost_events, lost_events_warned; |
064f19815 perf report: Add ... |
1737 |
float min_pcnt; |
68d807586 perf report: Post... |
1738 |
struct perf_session_env *env; |
7f0030b21 perf report tui: ... |
1739 1740 1741 1742 1743 1744 1745 1746 |
}; static void perf_evsel_menu__write(struct ui_browser *browser, void *entry, int row) { struct perf_evsel_menu *menu = container_of(browser, struct perf_evsel_menu, b); struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node); |
4ea062ed4 perf evsel: Add h... |
1747 |
struct hists *hists = evsel__hists(evsel); |
7f0030b21 perf report tui: ... |
1748 |
bool current_entry = ui_browser__is_current_entry(browser, row); |
4ea062ed4 perf evsel: Add h... |
1749 |
unsigned long nr_events = hists->stats.nr_events[PERF_RECORD_SAMPLE]; |
7289f83cc perf tools: Move ... |
1750 |
const char *ev_name = perf_evsel__name(evsel); |
7f0030b21 perf report tui: ... |
1751 |
char bf[256], unit; |
7b27509fc perf hists browse... |
1752 1753 |
const char *warn = " "; size_t printed; |
7f0030b21 perf report tui: ... |
1754 1755 1756 |
ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED : HE_COLORSET_NORMAL); |
759ff497e perf evsel: Intro... |
1757 |
if (perf_evsel__is_group_event(evsel)) { |
717e263fc perf report: Show... |
1758 1759 1760 1761 1762 |
struct perf_evsel *pos; ev_name = perf_evsel__group_name(evsel); for_each_group_member(pos, evsel) { |
4ea062ed4 perf evsel: Add h... |
1763 1764 |
struct hists *pos_hists = evsel__hists(pos); nr_events += pos_hists->stats.nr_events[PERF_RECORD_SAMPLE]; |
717e263fc perf report: Show... |
1765 1766 |
} } |
7f0030b21 perf report tui: ... |
1767 |
nr_events = convert_unit(nr_events, &unit); |
e7f01d1e3 perf tools: Use s... |
1768 |
printed = scnprintf(bf, sizeof(bf), "%lu%c%s%s", nr_events, |
7b27509fc perf hists browse... |
1769 1770 |
unit, unit == ' ' ? "" : " ", ev_name); slsmg_printf("%s", bf); |
4ea062ed4 perf evsel: Add h... |
1771 |
nr_events = hists->stats.nr_events[PERF_RECORD_LOST]; |
7b27509fc perf hists browse... |
1772 1773 1774 1775 1776 |
if (nr_events != 0) { menu->lost_events = true; if (!current_entry) ui_browser__set_color(browser, HE_COLORSET_TOP); nr_events = convert_unit(nr_events, &unit); |
e7f01d1e3 perf tools: Use s... |
1777 1778 |
printed += scnprintf(bf, sizeof(bf), ": %ld%c%schunks LOST!", nr_events, unit, unit == ' ' ? "" : " "); |
7b27509fc perf hists browse... |
1779 1780 1781 1782 |
warn = bf; } slsmg_write_nstring(warn, browser->width - printed); |
7f0030b21 perf report tui: ... |
1783 1784 1785 1786 |
if (current_entry) menu->selection = evsel; } |
34958544b perf annotate bro... |
1787 1788 |
static int perf_evsel_menu__run(struct perf_evsel_menu *menu, int nr_events, const char *help, |
9783adf77 perf tools: Intro... |
1789 |
struct hist_browser_timer *hbt) |
d1b4f2491 perf ui: Move his... |
1790 |
{ |
7f0030b21 perf report tui: ... |
1791 |
struct perf_evlist *evlist = menu->b.priv; |
e248de331 perf tools: Impro... |
1792 |
struct perf_evsel *pos; |
dd00d486d perf hists browse... |
1793 |
const char *title = "Available samples"; |
9783adf77 perf tools: Intro... |
1794 |
int delay_secs = hbt ? hbt->refresh : 0; |
7f0030b21 perf report tui: ... |
1795 |
int key; |
d1b4f2491 perf ui: Move his... |
1796 |
|
7f0030b21 perf report tui: ... |
1797 1798 1799 |
if (ui_browser__show(&menu->b, title, "ESC: exit, ENTER|->: Browse histograms") < 0) return -1; |
7f0030b21 perf report tui: ... |
1800 |
while (1) { |
3af6e3386 perf ui browser: ... |
1801 |
key = ui_browser__run(&menu->b, delay_secs); |
7f0030b21 perf report tui: ... |
1802 1803 |
switch (key) { |
cf9580036 perf ui browser: ... |
1804 |
case K_TIMER: |
9783adf77 perf tools: Intro... |
1805 |
hbt->timer(hbt->arg); |
7b27509fc perf hists browse... |
1806 1807 1808 1809 1810 |
if (!menu->lost_events_warned && menu->lost_events) { ui_browser__warn_lost_events(&menu->b); menu->lost_events_warned = true; } |
81cce8de9 perf browsers: Ad... |
1811 |
continue; |
cf9580036 perf ui browser: ... |
1812 1813 |
case K_RIGHT: case K_ENTER: |
7f0030b21 perf report tui: ... |
1814 1815 1816 1817 |
if (!menu->selection) continue; pos = menu->selection; browse_hists: |
18eaf0b8e perf hists browse... |
1818 1819 1820 1821 1822 |
perf_evlist__set_selected(evlist, pos); /* * Give the calling tool a chance to populate the non * default evsel resorted hists tree. */ |
9783adf77 perf tools: Intro... |
1823 1824 |
if (hbt) hbt->timer(hbt->arg); |
34958544b perf annotate bro... |
1825 |
key = perf_evsel__hists_browse(pos, nr_events, help, |
dd00d486d perf hists browse... |
1826 |
true, hbt, |
064f19815 perf report: Add ... |
1827 |
menu->min_pcnt, |
68d807586 perf report: Post... |
1828 |
menu->env); |
7f0030b21 perf report tui: ... |
1829 |
ui_browser__show_title(&menu->b, title); |
18eaf0b8e perf hists browse... |
1830 |
switch (key) { |
cf9580036 perf ui browser: ... |
1831 |
case K_TAB: |
18eaf0b8e perf hists browse... |
1832 |
if (pos->node.next == &evlist->entries) |
9a354cdc2 perf tools: Use p... |
1833 |
pos = perf_evlist__first(evlist); |
18eaf0b8e perf hists browse... |
1834 |
else |
9a354cdc2 perf tools: Use p... |
1835 |
pos = perf_evsel__next(pos); |
18eaf0b8e perf hists browse... |
1836 |
goto browse_hists; |
cf9580036 perf ui browser: ... |
1837 |
case K_UNTAB: |
18eaf0b8e perf hists browse... |
1838 |
if (pos->node.prev == &evlist->entries) |
9a354cdc2 perf tools: Use p... |
1839 |
pos = perf_evlist__last(evlist); |
18eaf0b8e perf hists browse... |
1840 |
else |
d87fcb4a2 perf evsel: Intro... |
1841 |
pos = perf_evsel__prev(pos); |
18eaf0b8e perf hists browse... |
1842 |
goto browse_hists; |
cf9580036 perf ui browser: ... |
1843 |
case K_ESC: |
4610e4137 perf ui browser: ... |
1844 1845 |
if (!ui_browser__dialog_yesno(&menu->b, "Do you really want to exit?")) |
18eaf0b8e perf hists browse... |
1846 1847 |
continue; /* Fall thru */ |
341487ab5 perf hists browse... |
1848 |
case K_SWITCH_INPUT_DATA: |
18eaf0b8e perf hists browse... |
1849 1850 1851 1852 1853 1854 |
case 'q': case CTRL('c'): goto out; default: continue; } |
cf9580036 perf ui browser: ... |
1855 |
case K_LEFT: |
7f0030b21 perf report tui: ... |
1856 |
continue; |
cf9580036 perf ui browser: ... |
1857 |
case K_ESC: |
4610e4137 perf ui browser: ... |
1858 1859 |
if (!ui_browser__dialog_yesno(&menu->b, "Do you really want to exit?")) |
ed7e5662d perf ui browser: ... |
1860 1861 |
continue; /* Fall thru */ |
7f0030b21 perf report tui: ... |
1862 1863 1864 |
case 'q': case CTRL('c'): goto out; |
d1b4f2491 perf ui: Move his... |
1865 |
default: |
18eaf0b8e perf hists browse... |
1866 |
continue; |
d1b4f2491 perf ui: Move his... |
1867 1868 |
} } |
7f0030b21 perf report tui: ... |
1869 1870 1871 1872 |
out: ui_browser__hide(&menu->b); return key; } |
316c7136f perf tools: Finis... |
1873 |
static bool filter_group_entries(struct ui_browser *browser __maybe_unused, |
fc24d7c25 perf report: Bypa... |
1874 1875 1876 1877 1878 1879 1880 1881 1882 |
void *entry) { struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node); if (symbol_conf.event_group && !perf_evsel__is_group_leader(evsel)) return true; return false; } |
7f0030b21 perf report tui: ... |
1883 |
static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, |
fc24d7c25 perf report: Bypa... |
1884 |
int nr_entries, const char *help, |
68d807586 perf report: Post... |
1885 |
struct hist_browser_timer *hbt, |
064f19815 perf report: Add ... |
1886 |
float min_pcnt, |
68d807586 perf report: Post... |
1887 |
struct perf_session_env *env) |
7f0030b21 perf report tui: ... |
1888 1889 1890 1891 1892 1893 1894 1895 |
{ struct perf_evsel *pos; struct perf_evsel_menu menu = { .b = { .entries = &evlist->entries, .refresh = ui_browser__list_head_refresh, .seek = ui_browser__list_head_seek, .write = perf_evsel_menu__write, |
fc24d7c25 perf report: Bypa... |
1896 1897 |
.filter = filter_group_entries, .nr_entries = nr_entries, |
7f0030b21 perf report tui: ... |
1898 1899 |
.priv = evlist, }, |
064f19815 perf report: Add ... |
1900 |
.min_pcnt = min_pcnt, |
68d807586 perf report: Post... |
1901 |
.env = env, |
7f0030b21 perf report tui: ... |
1902 1903 1904 |
}; ui_helpline__push("Press ESC to exit"); |
0050f7aa1 perf evlist: Intr... |
1905 |
evlist__for_each(evlist, pos) { |
7289f83cc perf tools: Move ... |
1906 |
const char *ev_name = perf_evsel__name(pos); |
7f0030b21 perf report tui: ... |
1907 1908 1909 1910 |
size_t line_len = strlen(ev_name) + 7; if (menu.b.width < line_len) menu.b.width = line_len; |
7f0030b21 perf report tui: ... |
1911 |
} |
fc24d7c25 perf report: Bypa... |
1912 |
return perf_evsel_menu__run(&menu, nr_entries, help, hbt); |
7f0030b21 perf report tui: ... |
1913 |
} |
81cce8de9 perf browsers: Ad... |
1914 |
int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, |
68d807586 perf report: Post... |
1915 |
struct hist_browser_timer *hbt, |
064f19815 perf report: Add ... |
1916 |
float min_pcnt, |
68d807586 perf report: Post... |
1917 |
struct perf_session_env *env) |
7f0030b21 perf report tui: ... |
1918 |
{ |
fc24d7c25 perf report: Bypa... |
1919 1920 1921 1922 |
int nr_entries = evlist->nr_entries; single_entry: if (nr_entries == 1) { |
9a354cdc2 perf tools: Use p... |
1923 |
struct perf_evsel *first = perf_evlist__first(evlist); |
fc24d7c25 perf report: Bypa... |
1924 1925 |
return perf_evsel__hists_browse(first, nr_entries, help, |
dd00d486d perf hists browse... |
1926 |
false, hbt, min_pcnt, |
064f19815 perf report: Add ... |
1927 |
env); |
7f0030b21 perf report tui: ... |
1928 |
} |
fc24d7c25 perf report: Bypa... |
1929 1930 1931 1932 |
if (symbol_conf.event_group) { struct perf_evsel *pos; nr_entries = 0; |
0050f7aa1 perf evlist: Intr... |
1933 |
evlist__for_each(evlist, pos) { |
fc24d7c25 perf report: Bypa... |
1934 1935 |
if (perf_evsel__is_group_leader(pos)) nr_entries++; |
0050f7aa1 perf evlist: Intr... |
1936 |
} |
fc24d7c25 perf report: Bypa... |
1937 1938 1939 1940 1941 1942 |
if (nr_entries == 1) goto single_entry; } return __perf_evlist__tui_browse_hists(evlist, nr_entries, help, |
064f19815 perf report: Add ... |
1943 |
hbt, min_pcnt, env); |
d1b4f2491 perf ui: Move his... |
1944 |
} |