diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/util/newt.c | 129 |
1 files changed, 84 insertions, 45 deletions
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c index a2ba3fffe04a..509d921532ef 100644 --- a/tools/perf/util/newt.c +++ b/tools/perf/util/newt.c | |||
@@ -381,53 +381,69 @@ static const void *newt__symbol_tree_get_current(newtComponent self) | |||
381 | return newtListboxGetCurrent(self); | 381 | return newtListboxGetCurrent(self); |
382 | } | 382 | } |
383 | 383 | ||
384 | static void perf_session__selection(newtComponent self, void *data) | 384 | static void hist_browser__selection(newtComponent self, void *data) |
385 | { | 385 | { |
386 | const struct map_symbol **symbol_ptr = data; | 386 | const struct map_symbol **symbol_ptr = data; |
387 | *symbol_ptr = newt__symbol_tree_get_current(self); | 387 | *symbol_ptr = newt__symbol_tree_get_current(self); |
388 | } | 388 | } |
389 | 389 | ||
390 | int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists, | 390 | struct hist_browser { |
391 | u64 session_total, const char *helpline) | 391 | newtComponent form, tree; |
392 | const struct map_symbol *selection; | ||
393 | }; | ||
394 | |||
395 | static struct hist_browser *hist_browser__new(void) | ||
396 | { | ||
397 | struct hist_browser *self = malloc(sizeof(*self)); | ||
398 | |||
399 | if (self != NULL) { | ||
400 | char seq[] = "."; | ||
401 | int rows; | ||
402 | |||
403 | newtGetScreenSize(NULL, &rows); | ||
404 | |||
405 | if (symbol_conf.use_callchain) | ||
406 | self->tree = newtCheckboxTreeMulti(0, 0, rows - 5, seq, | ||
407 | NEWT_FLAG_SCROLL); | ||
408 | else | ||
409 | self->tree = newtListbox(0, 0, rows - 5, | ||
410 | (NEWT_FLAG_SCROLL | | ||
411 | NEWT_FLAG_RETURNEXIT)); | ||
412 | newtComponentAddCallback(self->tree, hist_browser__selection, | ||
413 | &self->selection); | ||
414 | } | ||
415 | |||
416 | return self; | ||
417 | } | ||
418 | |||
419 | static void hist_browser__delete(struct hist_browser *self) | ||
420 | { | ||
421 | newtFormDestroy(self->form); | ||
422 | newtPopWindow(); | ||
423 | free(self); | ||
424 | } | ||
425 | |||
426 | static int hist_browser__populate(struct hist_browser *self, struct rb_root *hists, | ||
427 | u64 nr_hists, u64 session_total) | ||
392 | { | 428 | { |
429 | int max_len = 0, idx, cols, rows; | ||
430 | struct ui_progress *progress; | ||
393 | struct rb_node *nd; | 431 | struct rb_node *nd; |
394 | char seq[] = "."; | ||
395 | int rows, cols, idx; | ||
396 | int max_len = 0; | ||
397 | char str[1024]; | ||
398 | newtComponent form, tree; | ||
399 | struct newtExitStruct es; | ||
400 | const struct map_symbol *selection; | ||
401 | u64 curr_hist = 0; | 432 | u64 curr_hist = 0; |
402 | struct ui_progress *progress; | ||
403 | 433 | ||
404 | progress = ui_progress__new("Adding entries to the browser...", nr_hists); | 434 | progress = ui_progress__new("Adding entries to the browser...", nr_hists); |
405 | if (progress == NULL) | 435 | if (progress == NULL) |
406 | return -1; | 436 | return -1; |
407 | 437 | ||
408 | snprintf(str, sizeof(str), "Samples: %Ld", session_total); | ||
409 | newtDrawRootText(0, 0, str); | ||
410 | newtPushHelpLine(helpline); | ||
411 | |||
412 | newtGetScreenSize(&cols, &rows); | ||
413 | |||
414 | if (symbol_conf.use_callchain) | ||
415 | tree = newtCheckboxTreeMulti(0, 0, rows - 5, seq, | ||
416 | NEWT_FLAG_SCROLL); | ||
417 | else | ||
418 | tree = newtListbox(0, 0, rows - 5, (NEWT_FLAG_SCROLL | | ||
419 | NEWT_FLAG_RETURNEXIT)); | ||
420 | |||
421 | newtComponentAddCallback(tree, perf_session__selection, &selection); | ||
422 | |||
423 | idx = 0; | 438 | idx = 0; |
424 | for (nd = rb_first(hists); nd; nd = rb_next(nd)) { | 439 | for (nd = rb_first(hists); nd; nd = rb_next(nd)) { |
425 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); | 440 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); |
426 | int len = hist_entry__append_browser(h, tree, session_total); | 441 | int len = hist_entry__append_browser(h, self->tree, session_total); |
427 | if (len > max_len) | 442 | if (len > max_len) |
428 | max_len = len; | 443 | max_len = len; |
429 | if (symbol_conf.use_callchain) | 444 | if (symbol_conf.use_callchain) |
430 | hist_entry__append_callchain_browser(h, tree, session_total, idx++); | 445 | hist_entry__append_callchain_browser(h, self->tree, |
446 | session_total, idx++); | ||
431 | ++curr_hist; | 447 | ++curr_hist; |
432 | if (curr_hist % 5) | 448 | if (curr_hist % 5) |
433 | ui_progress__update(progress, curr_hist); | 449 | ui_progress__update(progress, curr_hist); |
@@ -435,27 +451,50 @@ int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists, | |||
435 | 451 | ||
436 | ui_progress__delete(progress); | 452 | ui_progress__delete(progress); |
437 | 453 | ||
454 | newtGetScreenSize(&cols, &rows); | ||
455 | |||
438 | if (max_len > cols) | 456 | if (max_len > cols) |
439 | max_len = cols - 3; | 457 | max_len = cols - 3; |
440 | 458 | ||
441 | if (!symbol_conf.use_callchain) | 459 | if (!symbol_conf.use_callchain) |
442 | newtListboxSetWidth(tree, max_len); | 460 | newtListboxSetWidth(self->tree, max_len); |
443 | 461 | ||
444 | newtCenteredWindow(max_len + (symbol_conf.use_callchain ? 5 : 0), | 462 | newtCenteredWindow(max_len + (symbol_conf.use_callchain ? 5 : 0), |
445 | rows - 5, "Report"); | 463 | rows - 5, "Report"); |
446 | form = newt_form__new(); | 464 | self->form = newt_form__new(); |
447 | newtFormAddHotKey(form, 'A'); | 465 | newtFormAddHotKey(self->form, 'A'); |
448 | newtFormAddHotKey(form, 'a'); | 466 | newtFormAddHotKey(self->form, 'a'); |
449 | newtFormAddHotKey(form, NEWT_KEY_RIGHT); | 467 | newtFormAddHotKey(self->form, NEWT_KEY_RIGHT); |
450 | newtFormAddComponents(form, tree, NULL); | 468 | newtFormAddComponents(self->form, self->tree, NULL); |
451 | selection = newt__symbol_tree_get_current(tree); | 469 | self->selection = newt__symbol_tree_get_current(self->tree); |
470 | |||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists, | ||
475 | u64 session_total, const char *helpline) | ||
476 | { | ||
477 | struct newtExitStruct es; | ||
478 | char str[1024]; | ||
479 | int err = -1; | ||
480 | struct hist_browser *browser = hist_browser__new(); | ||
481 | |||
482 | if (browser == NULL) | ||
483 | return -1; | ||
484 | |||
485 | snprintf(str, sizeof(str), "Samples: %Ld", session_total); | ||
486 | newtDrawRootText(0, 0, str); | ||
487 | newtPushHelpLine(helpline); | ||
488 | |||
489 | if (hist_browser__populate(browser, hists, nr_hists, session_total) < 0) | ||
490 | goto out; | ||
452 | 491 | ||
453 | while (1) { | 492 | while (1) { |
454 | char annotate[512]; | 493 | char annotate[512]; |
455 | const char *options[2]; | 494 | const char *options[2]; |
456 | int nr_options = 0, choice = 0; | 495 | int nr_options = 0, choice = 0; |
457 | 496 | ||
458 | newtFormRun(form, &es); | 497 | newtFormRun(browser->form, &es); |
459 | if (es.reason == NEWT_EXIT_HOTKEY) { | 498 | if (es.reason == NEWT_EXIT_HOTKEY) { |
460 | if (toupper(es.u.key) == 'A') | 499 | if (toupper(es.u.key) == 'A') |
461 | goto do_annotate; | 500 | goto do_annotate; |
@@ -469,9 +508,9 @@ int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists, | |||
469 | } | 508 | } |
470 | } | 509 | } |
471 | 510 | ||
472 | if (selection->sym != NULL) { | 511 | if (browser->selection->sym != NULL) { |
473 | snprintf(annotate, sizeof(annotate), | 512 | snprintf(annotate, sizeof(annotate), |
474 | "Annotate %s", selection->sym->name); | 513 | "Annotate %s", browser->selection->sym->name); |
475 | options[nr_options++] = annotate; | 514 | options[nr_options++] = annotate; |
476 | } | 515 | } |
477 | 516 | ||
@@ -480,21 +519,21 @@ int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists, | |||
480 | if (choice == nr_options - 1) | 519 | if (choice == nr_options - 1) |
481 | break; | 520 | break; |
482 | do_annotate: | 521 | do_annotate: |
483 | if (selection->sym != NULL && choice >= 0) { | 522 | if (browser->selection->sym != NULL && choice >= 0) { |
484 | if (selection->map->dso->origin == DSO__ORIG_KERNEL) { | 523 | if (browser->selection->map->dso->origin == DSO__ORIG_KERNEL) { |
485 | newtPopHelpLine(); | 524 | newtPopHelpLine(); |
486 | newtPushHelpLine("No vmlinux file found, can't " | 525 | newtPushHelpLine("No vmlinux file found, can't " |
487 | "annotate with just a " | 526 | "annotate with just a " |
488 | "kallsyms file"); | 527 | "kallsyms file"); |
489 | continue; | 528 | continue; |
490 | } | 529 | } |
491 | map_symbol__annotate_browser(selection); | 530 | map_symbol__annotate_browser(browser->selection); |
492 | } | 531 | } |
493 | } | 532 | } |
494 | 533 | err = 0; | |
495 | newtFormDestroy(form); | 534 | out: |
496 | newtPopWindow(); | 535 | hist_browser__delete(browser); |
497 | return 0; | 536 | return err; |
498 | } | 537 | } |
499 | 538 | ||
500 | void setup_browser(void) | 539 | void setup_browser(void) |