diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-08-06 15:51:12 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-08-06 15:51:12 -0400 |
commit | 43730982c3e9355dd8bd6b31f0a0a3508ad4209d (patch) | |
tree | a6f05a4fc0ff118745d1000c535e506321510bd9 | |
parent | 449e5b247ca7c9dc9fc3391b7eebfefdeb2ce1fc (diff) |
perf tui: Introduce list_head based generic ui_browser refresh routine
So that building other browser based on structures linked via a linked
list can be as easy as it is already for the ones linked via an rb_tree.
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/util/include/linux/list.h | 8 | ||||
-rw-r--r-- | tools/perf/util/newt.c | 49 |
2 files changed, 32 insertions, 25 deletions
diff --git a/tools/perf/util/include/linux/list.h b/tools/perf/util/include/linux/list.h index dbe4b814382a..f5ca26e53fbb 100644 --- a/tools/perf/util/include/linux/list.h +++ b/tools/perf/util/include/linux/list.h | |||
@@ -15,4 +15,12 @@ static inline void list_del_range(struct list_head *begin, | |||
15 | begin->prev->next = end->next; | 15 | begin->prev->next = end->next; |
16 | end->next->prev = begin->prev; | 16 | end->next->prev = begin->prev; |
17 | } | 17 | } |
18 | |||
19 | /** | ||
20 | * list_for_each_from - iterate over a list from one of its nodes | ||
21 | * @pos: the &struct list_head to use as a loop cursor, from where to start | ||
22 | * @head: the head for your list. | ||
23 | */ | ||
24 | #define list_for_each_from(pos, head) \ | ||
25 | for (; prefetch(pos->next), pos != (head); pos = pos->next) | ||
18 | #endif | 26 | #endif |
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c index e2deae0704d7..37fe8eb811ca 100644 --- a/tools/perf/util/newt.c +++ b/tools/perf/util/newt.c | |||
@@ -456,20 +456,24 @@ static int ui_browser__show(struct ui_browser *self, const char *title) | |||
456 | return 0; | 456 | return 0; |
457 | } | 457 | } |
458 | 458 | ||
459 | static int objdump_line__show(struct objdump_line *self, struct list_head *head, | 459 | static void annotate_browser__write(struct ui_browser *self, void *entry, int row) |
460 | int width, struct hist_entry *he, int len, | ||
461 | bool current_entry) | ||
462 | { | 460 | { |
463 | if (self->offset != -1) { | 461 | struct objdump_line *ol = rb_entry(entry, struct objdump_line, node); |
462 | bool current_entry = ui_browser__is_current_entry(self, row); | ||
463 | int width = self->width; | ||
464 | |||
465 | if (ol->offset != -1) { | ||
466 | struct hist_entry *he = self->priv; | ||
464 | struct symbol *sym = he->ms.sym; | 467 | struct symbol *sym = he->ms.sym; |
468 | int len = he->ms.sym->end - he->ms.sym->start; | ||
465 | unsigned int hits = 0; | 469 | unsigned int hits = 0; |
466 | double percent = 0.0; | 470 | double percent = 0.0; |
467 | int color; | 471 | int color; |
468 | struct sym_priv *priv = symbol__priv(sym); | 472 | struct sym_priv *priv = symbol__priv(sym); |
469 | struct sym_ext *sym_ext = priv->ext; | 473 | struct sym_ext *sym_ext = priv->ext; |
470 | struct sym_hist *h = priv->hist; | 474 | struct sym_hist *h = priv->hist; |
471 | s64 offset = self->offset; | 475 | s64 offset = ol->offset; |
472 | struct objdump_line *next = objdump__get_next_ip_line(head, self); | 476 | struct objdump_line *next = objdump__get_next_ip_line(self->entries, ol); |
473 | 477 | ||
474 | while (offset < (s64)len && | 478 | while (offset < (s64)len && |
475 | (next == NULL || offset < next->offset)) { | 479 | (next == NULL || offset < next->offset)) { |
@@ -497,12 +501,10 @@ static int objdump_line__show(struct objdump_line *self, struct list_head *head, | |||
497 | 501 | ||
498 | SLsmg_write_char(':'); | 502 | SLsmg_write_char(':'); |
499 | slsmg_write_nstring(" ", 8); | 503 | slsmg_write_nstring(" ", 8); |
500 | if (!*self->line) | 504 | if (!*ol->line) |
501 | slsmg_write_nstring(" ", width - 18); | 505 | slsmg_write_nstring(" ", width - 18); |
502 | else | 506 | else |
503 | slsmg_write_nstring(self->line, width - 18); | 507 | slsmg_write_nstring(ol->line, width - 18); |
504 | |||
505 | return 0; | ||
506 | } | 508 | } |
507 | 509 | ||
508 | static int ui_browser__refresh(struct ui_browser *self) | 510 | static int ui_browser__refresh(struct ui_browser *self) |
@@ -607,24 +609,20 @@ static char *callchain_list__sym_name(struct callchain_list *self, | |||
607 | return bf; | 609 | return bf; |
608 | } | 610 | } |
609 | 611 | ||
610 | static unsigned int hist_entry__annotate_browser_refresh(struct ui_browser *self) | 612 | static unsigned int ui_browser__list_head_refresh(struct ui_browser *self) |
611 | { | 613 | { |
612 | struct objdump_line *pos; | 614 | struct list_head *pos; |
613 | struct list_head *head = self->entries; | 615 | struct list_head *head = self->entries; |
614 | struct hist_entry *he = self->priv; | ||
615 | int row = 0; | 616 | int row = 0; |
616 | int len = he->ms.sym->end - he->ms.sym->start; | ||
617 | 617 | ||
618 | if (self->first_visible_entry == NULL || self->first_visible_entry == self->entries) | 618 | if (self->first_visible_entry == NULL || self->first_visible_entry == self->entries) |
619 | self->first_visible_entry = head->next; | 619 | self->first_visible_entry = head->next; |
620 | 620 | ||
621 | pos = list_entry(self->first_visible_entry, struct objdump_line, node); | 621 | pos = self->first_visible_entry; |
622 | 622 | ||
623 | list_for_each_entry_from(pos, head, node) { | 623 | list_for_each_from(pos, head) { |
624 | bool current_entry = ui_browser__is_current_entry(self, row); | ||
625 | SLsmg_gotorc(self->top + row, self->left); | 624 | SLsmg_gotorc(self->top + row, self->left); |
626 | objdump_line__show(pos, head, self->width, | 625 | self->write(self, pos, row); |
627 | he, len, current_entry); | ||
628 | if (++row == self->height) | 626 | if (++row == self->height) |
629 | break; | 627 | break; |
630 | } | 628 | } |
@@ -634,10 +632,16 @@ static unsigned int hist_entry__annotate_browser_refresh(struct ui_browser *self | |||
634 | 632 | ||
635 | int hist_entry__tui_annotate(struct hist_entry *self) | 633 | int hist_entry__tui_annotate(struct hist_entry *self) |
636 | { | 634 | { |
637 | struct ui_browser browser; | ||
638 | struct newtExitStruct es; | 635 | struct newtExitStruct es; |
639 | struct objdump_line *pos, *n; | 636 | struct objdump_line *pos, *n; |
640 | LIST_HEAD(head); | 637 | LIST_HEAD(head); |
638 | struct ui_browser browser = { | ||
639 | .entries = &head, | ||
640 | .refresh = ui_browser__list_head_refresh, | ||
641 | .seek = ui_browser__list_head_seek, | ||
642 | .write = annotate_browser__write, | ||
643 | .priv = self, | ||
644 | }; | ||
641 | int ret; | 645 | int ret; |
642 | 646 | ||
643 | if (self->ms.sym == NULL) | 647 | if (self->ms.sym == NULL) |
@@ -653,11 +657,6 @@ int hist_entry__tui_annotate(struct hist_entry *self) | |||
653 | 657 | ||
654 | ui_helpline__push("Press <- or ESC to exit"); | 658 | ui_helpline__push("Press <- or ESC to exit"); |
655 | 659 | ||
656 | memset(&browser, 0, sizeof(browser)); | ||
657 | browser.entries = &head; | ||
658 | browser.refresh = hist_entry__annotate_browser_refresh; | ||
659 | browser.seek = ui_browser__list_head_seek; | ||
660 | browser.priv = self; | ||
661 | list_for_each_entry(pos, &head, node) { | 660 | list_for_each_entry(pos, &head, node) { |
662 | size_t line_len = strlen(pos->line); | 661 | size_t line_len = strlen(pos->line); |
663 | if (browser.width < line_len) | 662 | if (browser.width < line_len) |