summaryrefslogtreecommitdiffstats
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.c147
1 files changed, 67 insertions, 80 deletions
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 041f236379e0..93fa136b0025 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -27,6 +27,7 @@ int sort__has_sym = 0;
int sort__has_dso = 0;
int sort__has_socket = 0;
int sort__has_thread = 0;
+int sort__has_comm = 0;
enum sort_mode sort__mode = SORT_MODE__NORMAL;
/*
@@ -1488,38 +1489,26 @@ bool perf_hpp__is_sort_entry(struct perf_hpp_fmt *format)
return format->header == __sort__hpp_header;
}
-bool perf_hpp__is_trace_entry(struct perf_hpp_fmt *fmt)
-{
- struct hpp_sort_entry *hse;
-
- if (!perf_hpp__is_sort_entry(fmt))
- return false;
-
- hse = container_of(fmt, struct hpp_sort_entry, hpp);
- return hse->se == &sort_trace;
+#define MK_SORT_ENTRY_CHK(key) \
+bool perf_hpp__is_ ## key ## _entry(struct perf_hpp_fmt *fmt) \
+{ \
+ struct hpp_sort_entry *hse; \
+ \
+ if (!perf_hpp__is_sort_entry(fmt)) \
+ return false; \
+ \
+ hse = container_of(fmt, struct hpp_sort_entry, hpp); \
+ return hse->se == &sort_ ## key ; \
}
-bool perf_hpp__is_srcline_entry(struct perf_hpp_fmt *fmt)
-{
- struct hpp_sort_entry *hse;
+MK_SORT_ENTRY_CHK(trace)
+MK_SORT_ENTRY_CHK(srcline)
+MK_SORT_ENTRY_CHK(srcfile)
+MK_SORT_ENTRY_CHK(thread)
+MK_SORT_ENTRY_CHK(comm)
+MK_SORT_ENTRY_CHK(dso)
+MK_SORT_ENTRY_CHK(sym)
- if (!perf_hpp__is_sort_entry(fmt))
- return false;
-
- hse = container_of(fmt, struct hpp_sort_entry, hpp);
- return hse->se == &sort_srcline;
-}
-
-bool perf_hpp__is_srcfile_entry(struct perf_hpp_fmt *fmt)
-{
- struct hpp_sort_entry *hse;
-
- if (!perf_hpp__is_sort_entry(fmt))
- return false;
-
- hse = container_of(fmt, struct hpp_sort_entry, hpp);
- return hse->se == &sort_srcfile;
-}
static bool __sort__hpp_equal(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b)
{
@@ -1602,31 +1591,47 @@ int hist_entry__filter(struct hist_entry *he, int type, const void *arg)
{
struct perf_hpp_fmt *fmt;
struct hpp_sort_entry *hse;
+ int ret = -1;
+ int r;
- fmt = he->fmt;
- if (fmt == NULL || !perf_hpp__is_sort_entry(fmt))
- return -1;
+ perf_hpp_list__for_each_format(he->hpp_list, fmt) {
+ if (!perf_hpp__is_sort_entry(fmt))
+ continue;
- hse = container_of(fmt, struct hpp_sort_entry, hpp);
- if (hse->se->se_filter == NULL)
- return -1;
+ hse = container_of(fmt, struct hpp_sort_entry, hpp);
+ if (hse->se->se_filter == NULL)
+ continue;
+
+ /*
+ * hist entry is filtered if any of sort key in the hpp list
+ * is applied. But it should skip non-matched filter types.
+ */
+ r = hse->se->se_filter(he, type, arg);
+ if (r >= 0) {
+ if (ret < 0)
+ ret = 0;
+ ret |= r;
+ }
+ }
- return hse->se->se_filter(he, type, arg);
+ return ret;
}
-static int __sort_dimension__add_hpp_sort(struct sort_dimension *sd, int level)
+static int __sort_dimension__add_hpp_sort(struct sort_dimension *sd,
+ struct perf_hpp_list *list,
+ int level)
{
struct hpp_sort_entry *hse = __sort_dimension__alloc_hpp(sd, level);
if (hse == NULL)
return -1;
- perf_hpp__register_sort_field(&hse->hpp);
+ perf_hpp_list__register_sort_field(list, &hse->hpp);
return 0;
}
-static int __sort_dimension__add_hpp_output(struct perf_hpp_list *list,
- struct sort_dimension *sd)
+static int __sort_dimension__add_hpp_output(struct sort_dimension *sd,
+ struct perf_hpp_list *list)
{
struct hpp_sort_entry *hse = __sort_dimension__alloc_hpp(sd, 0);
@@ -2147,12 +2152,14 @@ out:
return ret;
}
-static int __sort_dimension__add(struct sort_dimension *sd, int level)
+static int __sort_dimension__add(struct sort_dimension *sd,
+ struct perf_hpp_list *list,
+ int level)
{
if (sd->taken)
return 0;
- if (__sort_dimension__add_hpp_sort(sd, level) < 0)
+ if (__sort_dimension__add_hpp_sort(sd, list, level) < 0)
return -1;
if (sd->entry->se_collapse)
@@ -2163,7 +2170,9 @@ static int __sort_dimension__add(struct sort_dimension *sd, int level)
return 0;
}
-static int __hpp_dimension__add(struct hpp_dimension *hd, int level)
+static int __hpp_dimension__add(struct hpp_dimension *hd,
+ struct perf_hpp_list *list,
+ int level)
{
struct perf_hpp_fmt *fmt;
@@ -2175,7 +2184,7 @@ static int __hpp_dimension__add(struct hpp_dimension *hd, int level)
return -1;
hd->taken = 1;
- perf_hpp__register_sort_field(fmt);
+ perf_hpp_list__register_sort_field(list, fmt);
return 0;
}
@@ -2185,7 +2194,7 @@ static int __sort_dimension__add_output(struct perf_hpp_list *list,
if (sd->taken)
return 0;
- if (__sort_dimension__add_hpp_output(list, sd) < 0)
+ if (__sort_dimension__add_hpp_output(sd, list) < 0)
return -1;
sd->taken = 1;
@@ -2215,7 +2224,8 @@ int hpp_dimension__add_output(unsigned col)
return __hpp_dimension__add_output(&perf_hpp_list, &hpp_sort_dimensions[col]);
}
-static int sort_dimension__add(const char *tok, struct perf_evlist *evlist,
+static int sort_dimension__add(struct perf_hpp_list *list, const char *tok,
+ struct perf_evlist *evlist __maybe_unused,
int level)
{
unsigned int i;
@@ -2253,9 +2263,11 @@ static int sort_dimension__add(const char *tok, struct perf_evlist *evlist,
sort__has_socket = 1;
} else if (sd->entry == &sort_thread) {
sort__has_thread = 1;
+ } else if (sd->entry == &sort_comm) {
+ sort__has_comm = 1;
}
- return __sort_dimension__add(sd, level);
+ return __sort_dimension__add(sd, list, level);
}
for (i = 0; i < ARRAY_SIZE(hpp_sort_dimensions); i++) {
@@ -2264,7 +2276,7 @@ static int sort_dimension__add(const char *tok, struct perf_evlist *evlist,
if (strncasecmp(tok, hd->name, strlen(tok)))
continue;
- return __hpp_dimension__add(hd, level);
+ return __hpp_dimension__add(hd, list, level);
}
for (i = 0; i < ARRAY_SIZE(bstack_sort_dimensions); i++) {
@@ -2279,7 +2291,7 @@ static int sort_dimension__add(const char *tok, struct perf_evlist *evlist,
if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to)
sort__has_sym = 1;
- __sort_dimension__add(sd, level);
+ __sort_dimension__add(sd, list, level);
return 0;
}
@@ -2295,7 +2307,7 @@ static int sort_dimension__add(const char *tok, struct perf_evlist *evlist,
if (sd->entry == &sort_mem_daddr_sym)
sort__has_sym = 1;
- __sort_dimension__add(sd, level);
+ __sort_dimension__add(sd, list, level);
return 0;
}
@@ -2305,7 +2317,8 @@ static int sort_dimension__add(const char *tok, struct perf_evlist *evlist,
return -ESRCH;
}
-static int setup_sort_list(char *str, struct perf_evlist *evlist)
+static int setup_sort_list(struct perf_hpp_list *list, char *str,
+ struct perf_evlist *evlist)
{
char *tmp, *tok;
int ret = 0;
@@ -2332,7 +2345,7 @@ static int setup_sort_list(char *str, struct perf_evlist *evlist)
}
if (*tok) {
- ret = sort_dimension__add(tok, evlist, level);
+ ret = sort_dimension__add(list, tok, evlist, level);
if (ret == -EINVAL) {
error("Invalid --sort key: `%s'", tok);
break;
@@ -2480,7 +2493,7 @@ static int __setup_sorting(struct perf_evlist *evlist)
}
}
- ret = setup_sort_list(str, evlist);
+ ret = setup_sort_list(&perf_hpp_list, str, evlist);
free(str);
return ret;
@@ -2693,29 +2706,6 @@ out:
return ret;
}
-static void evlist__set_hists_nr_sort_keys(struct perf_evlist *evlist)
-{
- struct perf_evsel *evsel;
-
- evlist__for_each(evlist, evsel) {
- struct perf_hpp_fmt *fmt;
- struct hists *hists = evsel__hists(evsel);
-
- hists->nr_sort_keys = perf_hpp_list.nr_sort_keys;
-
- /*
- * If dynamic entries were used, it might add multiple
- * entries to each evsel for a single field name. Set
- * actual number of sort keys for each hists.
- */
- perf_hpp_list__for_each_sort_list(&perf_hpp_list, fmt) {
- if (perf_hpp__is_dynamic_entry(fmt) &&
- !perf_hpp__defined_dynamic_entry(fmt, hists))
- hists->nr_sort_keys--;
- }
- }
-}
-
int setup_sorting(struct perf_evlist *evlist)
{
int err;
@@ -2725,14 +2715,11 @@ int setup_sorting(struct perf_evlist *evlist)
return err;
if (parent_pattern != default_parent_pattern) {
- err = sort_dimension__add("parent", evlist, -1);
+ err = sort_dimension__add(&perf_hpp_list, "parent", evlist, -1);
if (err < 0)
return err;
}
- if (evlist != NULL)
- evlist__set_hists_nr_sort_keys(evlist);
-
reset_dimensions();
/*
OpenPOWER on IntegriCloud