summaryrefslogtreecommitdiff
path: root/tools/perf/util/sort.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/sort.c')
-rw-r--r--tools/perf/util/sort.c129
1 files changed, 120 insertions, 9 deletions
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 0ecc2cb13792..e188f74698dd 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -374,6 +374,18 @@ char *hist_entry__srcline(struct hist_entry *he)
static int64_t
sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right)
{
+ int64_t ret;
+
+ ret = _sort__addr_cmp(left->ip, right->ip);
+ if (ret)
+ return ret;
+
+ return sort__dso_cmp(left, right);
+}
+
+static int64_t
+sort__srcline_collapse(struct hist_entry *left, struct hist_entry *right)
+{
if (!left->srcline)
left->srcline = hist_entry__srcline(left);
if (!right->srcline)
@@ -382,18 +394,31 @@ sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right)
return strcmp(right->srcline, left->srcline);
}
-static int hist_entry__srcline_snprintf(struct hist_entry *he, char *bf,
- size_t size, unsigned int width)
+static int64_t
+sort__srcline_sort(struct hist_entry *left, struct hist_entry *right)
+{
+ return sort__srcline_collapse(left, right);
+}
+
+static void
+sort__srcline_init(struct hist_entry *he)
{
if (!he->srcline)
he->srcline = hist_entry__srcline(he);
+}
+static int hist_entry__srcline_snprintf(struct hist_entry *he, char *bf,
+ size_t size, unsigned int width)
+{
return repsep_snprintf(bf, size, "%-.*s", width, he->srcline);
}
struct sort_entry sort_srcline = {
.se_header = "Source:Line",
.se_cmp = sort__srcline_cmp,
+ .se_collapse = sort__srcline_collapse,
+ .se_sort = sort__srcline_sort,
+ .se_init = sort__srcline_init,
.se_snprintf = hist_entry__srcline_snprintf,
.se_width_idx = HISTC_SRCLINE,
};
@@ -408,6 +433,12 @@ static char *addr_map_symbol__srcline(struct addr_map_symbol *ams)
static int64_t
sort__srcline_from_cmp(struct hist_entry *left, struct hist_entry *right)
{
+ return left->branch_info->from.addr - right->branch_info->from.addr;
+}
+
+static int64_t
+sort__srcline_from_collapse(struct hist_entry *left, struct hist_entry *right)
+{
if (!left->branch_info->srcline_from)
left->branch_info->srcline_from = addr_map_symbol__srcline(&left->branch_info->from);
@@ -417,6 +448,18 @@ sort__srcline_from_cmp(struct hist_entry *left, struct hist_entry *right)
return strcmp(right->branch_info->srcline_from, left->branch_info->srcline_from);
}
+static int64_t
+sort__srcline_from_sort(struct hist_entry *left, struct hist_entry *right)
+{
+ return sort__srcline_from_collapse(left, right);
+}
+
+static void sort__srcline_from_init(struct hist_entry *he)
+{
+ if (!he->branch_info->srcline_from)
+ he->branch_info->srcline_from = addr_map_symbol__srcline(&he->branch_info->from);
+}
+
static int hist_entry__srcline_from_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
@@ -426,6 +469,9 @@ static int hist_entry__srcline_from_snprintf(struct hist_entry *he, char *bf,
struct sort_entry sort_srcline_from = {
.se_header = "From Source:Line",
.se_cmp = sort__srcline_from_cmp,
+ .se_collapse = sort__srcline_from_collapse,
+ .se_sort = sort__srcline_from_sort,
+ .se_init = sort__srcline_from_init,
.se_snprintf = hist_entry__srcline_from_snprintf,
.se_width_idx = HISTC_SRCLINE_FROM,
};
@@ -435,6 +481,12 @@ struct sort_entry sort_srcline_from = {
static int64_t
sort__srcline_to_cmp(struct hist_entry *left, struct hist_entry *right)
{
+ return left->branch_info->to.addr - right->branch_info->to.addr;
+}
+
+static int64_t
+sort__srcline_to_collapse(struct hist_entry *left, struct hist_entry *right)
+{
if (!left->branch_info->srcline_to)
left->branch_info->srcline_to = addr_map_symbol__srcline(&left->branch_info->to);
@@ -444,6 +496,18 @@ sort__srcline_to_cmp(struct hist_entry *left, struct hist_entry *right)
return strcmp(right->branch_info->srcline_to, left->branch_info->srcline_to);
}
+static int64_t
+sort__srcline_to_sort(struct hist_entry *left, struct hist_entry *right)
+{
+ return sort__srcline_to_collapse(left, right);
+}
+
+static void sort__srcline_to_init(struct hist_entry *he)
+{
+ if (!he->branch_info->srcline_to)
+ he->branch_info->srcline_to = addr_map_symbol__srcline(&he->branch_info->to);
+}
+
static int hist_entry__srcline_to_snprintf(struct hist_entry *he, char *bf,
size_t size, unsigned int width)
{
@@ -453,6 +517,9 @@ static int hist_entry__srcline_to_snprintf(struct hist_entry *he, char *bf,
struct sort_entry sort_srcline_to = {
.se_header = "To Source:Line",
.se_cmp = sort__srcline_to_cmp,
+ .se_collapse = sort__srcline_to_collapse,
+ .se_sort = sort__srcline_to_sort,
+ .se_init = sort__srcline_to_init,
.se_snprintf = hist_entry__srcline_to_snprintf,
.se_width_idx = HISTC_SRCLINE_TO,
};
@@ -544,18 +611,41 @@ sort__srcfile_cmp(struct hist_entry *left, struct hist_entry *right)
return strcmp(right->srcfile, left->srcfile);
}
-static int hist_entry__srcfile_snprintf(struct hist_entry *he, char *bf,
- size_t size, unsigned int width)
+static int64_t
+sort__srcfile_collapse(struct hist_entry *left, struct hist_entry *right)
+{
+ if (!left->srcfile)
+ left->srcfile = hist_entry__get_srcfile(left);
+ if (!right->srcfile)
+ right->srcfile = hist_entry__get_srcfile(right);
+
+ return strcmp(right->srcfile, left->srcfile);
+}
+
+static int64_t
+sort__srcfile_sort(struct hist_entry *left, struct hist_entry *right)
+{
+ return sort__srcfile_collapse(left, right);
+}
+
+static void sort__srcfile_init(struct hist_entry *he)
{
if (!he->srcfile)
he->srcfile = hist_entry__get_srcfile(he);
+}
+static int hist_entry__srcfile_snprintf(struct hist_entry *he, char *bf,
+ size_t size, unsigned int width)
+{
return repsep_snprintf(bf, size, "%-.*s", width, he->srcfile);
}
struct sort_entry sort_srcfile = {
.se_header = "Source File",
.se_cmp = sort__srcfile_cmp,
+ .se_collapse = sort__srcfile_collapse,
+ .se_sort = sort__srcfile_sort,
+ .se_init = sort__srcfile_init,
.se_snprintf = hist_entry__srcfile_snprintf,
.se_width_idx = HISTC_SRCFILE,
};
@@ -2251,6 +2341,19 @@ static void hse_free(struct perf_hpp_fmt *fmt)
free(hse);
}
+static void hse_init(struct perf_hpp_fmt *fmt, struct hist_entry *he)
+{
+ struct hpp_sort_entry *hse;
+
+ if (!perf_hpp__is_sort_entry(fmt))
+ return;
+
+ hse = container_of(fmt, struct hpp_sort_entry, hpp);
+
+ if (hse->se->se_init)
+ hse->se->se_init(he);
+}
+
static struct hpp_sort_entry *
__sort_dimension__alloc_hpp(struct sort_dimension *sd, int level)
{
@@ -2274,6 +2377,7 @@ __sort_dimension__alloc_hpp(struct sort_dimension *sd, int level)
hse->hpp.sort = __sort__hpp_sort;
hse->hpp.equal = __sort__hpp_equal;
hse->hpp.free = hse_free;
+ hse->hpp.init = hse_init;
INIT_LIST_HEAD(&hse->hpp.list);
INIT_LIST_HEAD(&hse->hpp.sort_list);
@@ -2556,11 +2660,6 @@ static int64_t __sort__hde_cmp(struct perf_hpp_fmt *fmt,
hde = container_of(fmt, struct hpp_dynamic_entry, hpp);
- if (b == NULL) {
- update_dynamic_len(hde, a);
- return 0;
- }
-
field = hde->field;
if (field->flags & TEP_FIELD_IS_DYNAMIC) {
unsigned long long dyn;
@@ -2610,6 +2709,17 @@ static void hde_free(struct perf_hpp_fmt *fmt)
free(hde);
}
+static void __sort__hde_init(struct perf_hpp_fmt *fmt, struct hist_entry *he)
+{
+ struct hpp_dynamic_entry *hde;
+
+ if (!perf_hpp__is_dynamic_entry(fmt))
+ return;
+
+ hde = container_of(fmt, struct hpp_dynamic_entry, hpp);
+ update_dynamic_len(hde, he);
+}
+
static struct hpp_dynamic_entry *
__alloc_dynamic_entry(struct evsel *evsel, struct tep_format_field *field,
int level)
@@ -2632,6 +2742,7 @@ __alloc_dynamic_entry(struct evsel *evsel, struct tep_format_field *field,
hde->hpp.entry = __sort__hde_entry;
hde->hpp.color = NULL;
+ hde->hpp.init = __sort__hde_init;
hde->hpp.cmp = __sort__hde_cmp;
hde->hpp.collapse = __sort__hde_cmp;
hde->hpp.sort = __sort__hde_cmp;