aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/newt.c129
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
384static void perf_session__selection(newtComponent self, void *data) 384static 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
390int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists, 390struct hist_browser {
391 u64 session_total, const char *helpline) 391 newtComponent form, tree;
392 const struct map_symbol *selection;
393};
394
395static 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
419static void hist_browser__delete(struct hist_browser *self)
420{
421 newtFormDestroy(self->form);
422 newtPopWindow();
423 free(self);
424}
425
426static 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
474int 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;
482do_annotate: 521do_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); 534out:
496 newtPopWindow(); 535 hist_browser__delete(browser);
497 return 0; 536 return err;
498} 537}
499 538
500void setup_browser(void) 539void setup_browser(void)