diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2009-05-27 14:20:25 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-05-27 15:44:13 -0400 |
commit | 1aa167382323eeeeb38368cab85cf17979793cbe (patch) | |
tree | 7dfe17f659d3c6d0486ac7d2efd5923df5022191 /Documentation/perf_counter | |
parent | e7fb08b1d06a6b37263c765205de5614a2273aeb (diff) |
perf_counter: tools: report: Dynamic sort/print bits
Make the sorting and printing dynamic.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: John Kacur <jkacur@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
LKML-Reference: <20090527182100.921953817@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'Documentation/perf_counter')
-rw-r--r-- | Documentation/perf_counter/builtin-report.c | 141 |
1 files changed, 107 insertions, 34 deletions
diff --git a/Documentation/perf_counter/builtin-report.c b/Documentation/perf_counter/builtin-report.c index 276256439b78..856186fd2bd4 100644 --- a/Documentation/perf_counter/builtin-report.c +++ b/Documentation/perf_counter/builtin-report.c | |||
@@ -699,14 +699,41 @@ struct hist_entry { | |||
699 | uint32_t count; | 699 | uint32_t count; |
700 | }; | 700 | }; |
701 | 701 | ||
702 | /* | ||
703 | * configurable sorting bits | ||
704 | */ | ||
705 | |||
706 | struct sort_entry { | ||
707 | struct list_head list; | ||
708 | |||
709 | int64_t (*cmp)(struct hist_entry *, struct hist_entry *); | ||
710 | size_t (*print)(FILE *fp, struct hist_entry *); | ||
711 | }; | ||
712 | |||
702 | static int64_t | 713 | static int64_t |
703 | hist_entry__cmp(struct hist_entry *left, struct hist_entry *right) | 714 | sort__thread_cmp(struct hist_entry *left, struct hist_entry *right) |
704 | { | 715 | { |
705 | uint64_t ip_l, ip_r; | 716 | return right->thread->pid - left->thread->pid; |
706 | int cmp = right->thread->pid - left->thread->pid; | 717 | } |
718 | |||
719 | static size_t | ||
720 | sort__thread_print(FILE *fp, struct hist_entry *self) | ||
721 | { | ||
722 | char bf[32]; | ||
723 | |||
724 | return fprintf(fp, "%14s ", | ||
725 | thread__name(self->thread, bf, sizeof(bf))); | ||
726 | } | ||
707 | 727 | ||
708 | if (cmp) | 728 | static struct sort_entry sort_thread = { |
709 | return cmp; | 729 | .cmp = sort__thread_cmp, |
730 | .print = sort__thread_print, | ||
731 | }; | ||
732 | |||
733 | static int64_t | ||
734 | sort__sym_cmp(struct hist_entry *left, struct hist_entry *right) | ||
735 | { | ||
736 | uint64_t ip_l, ip_r; | ||
710 | 737 | ||
711 | if (left->sym == right->sym) | 738 | if (left->sym == right->sym) |
712 | return 0; | 739 | return 0; |
@@ -717,6 +744,79 @@ hist_entry__cmp(struct hist_entry *left, struct hist_entry *right) | |||
717 | return (int64_t)(ip_r - ip_l); | 744 | return (int64_t)(ip_r - ip_l); |
718 | } | 745 | } |
719 | 746 | ||
747 | static size_t | ||
748 | sort__sym_print(FILE *fp, struct hist_entry *self) | ||
749 | { | ||
750 | size_t ret = 0; | ||
751 | |||
752 | ret += fprintf(fp, "[%c] ", self->level); | ||
753 | |||
754 | if (verbose) | ||
755 | ret += fprintf(fp, "%#018llx ", (unsigned long long)self->ip); | ||
756 | |||
757 | if (self->level != '.') | ||
758 | ret += fprintf(fp, "%s ", | ||
759 | self->sym ? self->sym->name : "<unknown>"); | ||
760 | else | ||
761 | ret += fprintf(fp, "%s: %s ", | ||
762 | self->dso ? self->dso->name : "<unknown>", | ||
763 | self->sym ? self->sym->name : "<unknown>"); | ||
764 | |||
765 | return ret; | ||
766 | } | ||
767 | |||
768 | static struct sort_entry sort_sym = { | ||
769 | .cmp = sort__sym_cmp, | ||
770 | .print = sort__sym_print, | ||
771 | }; | ||
772 | |||
773 | static LIST_HEAD(hist_entry__sort_list); | ||
774 | |||
775 | static void setup_sorting(void) | ||
776 | { | ||
777 | list_add_tail(&sort_thread.list, &hist_entry__sort_list); | ||
778 | list_add_tail(&sort_sym.list, &hist_entry__sort_list); | ||
779 | } | ||
780 | |||
781 | static int64_t | ||
782 | hist_entry__cmp(struct hist_entry *left, struct hist_entry *right) | ||
783 | { | ||
784 | struct sort_entry *se; | ||
785 | int64_t cmp = 0; | ||
786 | |||
787 | list_for_each_entry(se, &hist_entry__sort_list, list) { | ||
788 | cmp = se->cmp(left, right); | ||
789 | if (cmp) | ||
790 | break; | ||
791 | } | ||
792 | |||
793 | return cmp; | ||
794 | } | ||
795 | |||
796 | static size_t | ||
797 | hist_entry__fprintf(FILE *fp, struct hist_entry *self, uint64_t total_samples) | ||
798 | { | ||
799 | struct sort_entry *se; | ||
800 | size_t ret; | ||
801 | |||
802 | if (total_samples) { | ||
803 | ret = fprintf(fp, "%5.2f%% ", | ||
804 | (self->count * 100.0) / total_samples); | ||
805 | } else | ||
806 | ret = fprintf(fp, "%12d ", self->count); | ||
807 | |||
808 | list_for_each_entry(se, &hist_entry__sort_list, list) | ||
809 | ret += se->print(fp, self); | ||
810 | |||
811 | ret += fprintf(fp, "\n"); | ||
812 | |||
813 | return ret; | ||
814 | } | ||
815 | |||
816 | /* | ||
817 | * collect histogram counts | ||
818 | */ | ||
819 | |||
720 | static int | 820 | static int |
721 | hist_entry__add(struct thread *thread, struct map *map, struct dso *dso, | 821 | hist_entry__add(struct thread *thread, struct map *map, struct dso *dso, |
722 | struct symbol *sym, uint64_t ip, char level) | 822 | struct symbol *sym, uint64_t ip, char level) |
@@ -762,35 +862,6 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso, | |||
762 | return 0; | 862 | return 0; |
763 | } | 863 | } |
764 | 864 | ||
765 | static size_t | ||
766 | hist_entry__fprintf(FILE *fp, struct hist_entry *self, uint64_t total_samples) | ||
767 | { | ||
768 | char bf[32]; | ||
769 | size_t ret; | ||
770 | |||
771 | if (total_samples) { | ||
772 | ret = fprintf(fp, "%5.2f%% ", | ||
773 | (self->count * 100.0) / total_samples); | ||
774 | } else | ||
775 | ret = fprintf(fp, "%12d ", self->count); | ||
776 | |||
777 | ret += fprintf(fp, "%14s [%c] ", | ||
778 | thread__name(self->thread, bf, sizeof(bf)), | ||
779 | self->level); | ||
780 | |||
781 | if (verbose) | ||
782 | ret += fprintf(fp, "%#018llx ", (unsigned long long)self->ip); | ||
783 | |||
784 | if (self->level != '.') | ||
785 | ret += fprintf(fp, "%s\n", | ||
786 | self->sym ? self->sym->name : "<unknown>"); | ||
787 | else | ||
788 | ret += fprintf(fp, "%s: %s\n", | ||
789 | self->dso ? self->dso->name : "<unknown>", | ||
790 | self->sym ? self->sym->name : "<unknown>"); | ||
791 | return ret; | ||
792 | } | ||
793 | |||
794 | /* | 865 | /* |
795 | * reverse the map, sort on count. | 866 | * reverse the map, sort on count. |
796 | */ | 867 | */ |
@@ -1077,6 +1148,8 @@ int cmd_report(int argc, const char **argv, const char *prefix) | |||
1077 | 1148 | ||
1078 | parse_options(argc, argv, options, report_usage, 0); | 1149 | parse_options(argc, argv, options, report_usage, 0); |
1079 | 1150 | ||
1151 | setup_sorting(); | ||
1152 | |||
1080 | setup_pager(); | 1153 | setup_pager(); |
1081 | 1154 | ||
1082 | return __cmd_report(); | 1155 | return __cmd_report(); |