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 /tools | |
| 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>
Diffstat (limited to 'tools')
| -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) |
