aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/perf_counter/builtin-report.c
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/perf_counter/builtin-report.c')
-rw-r--r--Documentation/perf_counter/builtin-report.c141
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
706struct 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
702static int64_t 713static int64_t
703hist_entry__cmp(struct hist_entry *left, struct hist_entry *right) 714sort__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
719static size_t
720sort__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) 728static struct sort_entry sort_thread = {
709 return cmp; 729 .cmp = sort__thread_cmp,
730 .print = sort__thread_print,
731};
732
733static int64_t
734sort__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
747static size_t
748sort__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
768static struct sort_entry sort_sym = {
769 .cmp = sort__sym_cmp,
770 .print = sort__sym_print,
771};
772
773static LIST_HEAD(hist_entry__sort_list);
774
775static 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
781static int64_t
782hist_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
796static size_t
797hist_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
720static int 820static int
721hist_entry__add(struct thread *thread, struct map *map, struct dso *dso, 821hist_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
765static size_t
766hist_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();