aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-report.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-report.c')
-rw-r--r--tools/perf/builtin-report.c164
1 files changed, 1 insertions, 163 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 7b43504900ff..c1a54fc8527a 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -28,6 +28,7 @@
28 28
29#include "util/thread.h" 29#include "util/thread.h"
30#include "util/sort.h" 30#include "util/sort.h"
31#include "util/hist.h"
31 32
32static char const *input_name = "perf.data"; 33static char const *input_name = "perf.data";
33 34
@@ -55,8 +56,6 @@ static int exclude_other = 1;
55 56
56static char callchain_default_opt[] = "fractal,0.5"; 57static char callchain_default_opt[] = "fractal,0.5";
57 58
58static int callchain;
59
60static char __cwd[PATH_MAX]; 59static char __cwd[PATH_MAX];
61static char *cwd = __cwd; 60static char *cwd = __cwd;
62static int cwdlen; 61static int cwdlen;
@@ -66,50 +65,8 @@ static struct thread *last_match;
66 65
67static struct perf_header *header; 66static struct perf_header *header;
68 67
69static
70struct callchain_param callchain_param = {
71 .mode = CHAIN_GRAPH_REL,
72 .min_percent = 0.5
73};
74
75static u64 sample_type; 68static u64 sample_type;
76 69
77static struct rb_root hist;
78
79static int64_t
80hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
81{
82 struct sort_entry *se;
83 int64_t cmp = 0;
84
85 list_for_each_entry(se, &hist_entry__sort_list, list) {
86 cmp = se->cmp(left, right);
87 if (cmp)
88 break;
89 }
90
91 return cmp;
92}
93
94static int64_t
95hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
96{
97 struct sort_entry *se;
98 int64_t cmp = 0;
99
100 list_for_each_entry(se, &hist_entry__sort_list, list) {
101 int64_t (*f)(struct hist_entry *, struct hist_entry *);
102
103 f = se->collapse ?: se->cmp;
104
105 cmp = f(left, right);
106 if (cmp)
107 break;
108 }
109
110 return cmp;
111}
112
113static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask) 70static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask)
114{ 71{
115 int i; 72 int i;
@@ -308,7 +265,6 @@ hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
308 return ret; 265 return ret;
309} 266}
310 267
311
312static size_t 268static size_t
313hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples) 269hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples)
314{ 270{
@@ -573,117 +529,6 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
573 return 0; 529 return 0;
574} 530}
575 531
576static void hist_entry__free(struct hist_entry *he)
577{
578 free(he);
579}
580
581/*
582 * collapse the histogram
583 */
584
585static struct rb_root collapse_hists;
586
587static void collapse__insert_entry(struct hist_entry *he)
588{
589 struct rb_node **p = &collapse_hists.rb_node;
590 struct rb_node *parent = NULL;
591 struct hist_entry *iter;
592 int64_t cmp;
593
594 while (*p != NULL) {
595 parent = *p;
596 iter = rb_entry(parent, struct hist_entry, rb_node);
597
598 cmp = hist_entry__collapse(iter, he);
599
600 if (!cmp) {
601 iter->count += he->count;
602 hist_entry__free(he);
603 return;
604 }
605
606 if (cmp < 0)
607 p = &(*p)->rb_left;
608 else
609 p = &(*p)->rb_right;
610 }
611
612 rb_link_node(&he->rb_node, parent, p);
613 rb_insert_color(&he->rb_node, &collapse_hists);
614}
615
616static void collapse__resort(void)
617{
618 struct rb_node *next;
619 struct hist_entry *n;
620
621 if (!sort__need_collapse)
622 return;
623
624 next = rb_first(&hist);
625 while (next) {
626 n = rb_entry(next, struct hist_entry, rb_node);
627 next = rb_next(&n->rb_node);
628
629 rb_erase(&n->rb_node, &hist);
630 collapse__insert_entry(n);
631 }
632}
633
634/*
635 * reverse the map, sort on count.
636 */
637
638static struct rb_root output_hists;
639
640static void output__insert_entry(struct hist_entry *he, u64 min_callchain_hits)
641{
642 struct rb_node **p = &output_hists.rb_node;
643 struct rb_node *parent = NULL;
644 struct hist_entry *iter;
645
646 if (callchain)
647 callchain_param.sort(&he->sorted_chain, &he->callchain,
648 min_callchain_hits, &callchain_param);
649
650 while (*p != NULL) {
651 parent = *p;
652 iter = rb_entry(parent, struct hist_entry, rb_node);
653
654 if (he->count > iter->count)
655 p = &(*p)->rb_left;
656 else
657 p = &(*p)->rb_right;
658 }
659
660 rb_link_node(&he->rb_node, parent, p);
661 rb_insert_color(&he->rb_node, &output_hists);
662}
663
664static void output__resort(u64 total_samples)
665{
666 struct rb_node *next;
667 struct hist_entry *n;
668 struct rb_root *tree = &hist;
669 u64 min_callchain_hits;
670
671 min_callchain_hits = total_samples * (callchain_param.min_percent / 100);
672
673 if (sort__need_collapse)
674 tree = &collapse_hists;
675
676 next = rb_first(tree);
677
678 while (next) {
679 n = rb_entry(next, struct hist_entry, rb_node);
680 next = rb_next(&n->rb_node);
681
682 rb_erase(&n->rb_node, tree);
683 output__insert_entry(n, min_callchain_hits);
684 }
685}
686
687static size_t output__fprintf(FILE *fp, u64 total_samples) 532static size_t output__fprintf(FILE *fp, u64 total_samples)
688{ 533{
689 struct hist_entry *pos; 534 struct hist_entry *pos;
@@ -778,13 +623,6 @@ print_entries:
778 return ret; 623 return ret;
779} 624}
780 625
781static unsigned long total = 0,
782 total_mmap = 0,
783 total_comm = 0,
784 total_fork = 0,
785 total_unknown = 0,
786 total_lost = 0;
787
788static int validate_chain(struct ip_callchain *chain, event_t *event) 626static int validate_chain(struct ip_callchain *chain, event_t *event)
789{ 627{
790 unsigned int chain_size; 628 unsigned int chain_size;