]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - tools/perf/builtin-stat.c
perf tools: Remove unused 'prefix' from builtin functions
[karo-tx-linux.git] / tools / perf / builtin-stat.c
index 5c13a0f40adc04ae6abba9e06ecd4d60222a2d01..2158ea14da57ba98993ba1103ec910a24c903ad5 100644 (file)
@@ -140,6 +140,7 @@ static unsigned int         unit_width                      = 4; /* strlen("unit") */
 static bool                    forever                         = false;
 static bool                    metric_only                     = false;
 static bool                    force_metric_only               = false;
+static bool                    no_merge                        = false;
 static struct timespec         ref_time;
 static struct cpu_map          *aggr_map;
 static aggr_get_id_t           aggr_get_id;
@@ -1144,6 +1145,7 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval,
        out.print_metric = pm;
        out.new_line = nl;
        out.ctx = &os;
+       out.force_header = false;
 
        if (csv_output && !metric_only) {
                print_noise(counter, noise);
@@ -1182,12 +1184,37 @@ static void aggr_update_shadow(void)
        }
 }
 
-static void collect_data(struct perf_evsel *counter,
+static void collect_all_aliases(struct perf_evsel *counter,
                            void (*cb)(struct perf_evsel *counter, void *data,
                                       bool first),
                            void *data)
 {
+       struct perf_evsel *alias;
+
+       alias = list_prepare_entry(counter, &(evsel_list->entries), node);
+       list_for_each_entry_continue (alias, &evsel_list->entries, node) {
+               if (strcmp(perf_evsel__name(alias), perf_evsel__name(counter)) ||
+                   alias->scale != counter->scale ||
+                   alias->cgrp != counter->cgrp ||
+                   strcmp(alias->unit, counter->unit) ||
+                   nsec_counter(alias) != nsec_counter(counter))
+                       break;
+               alias->merged_stat = true;
+               cb(alias, data, false);
+       }
+}
+
+static bool collect_data(struct perf_evsel *counter,
+                           void (*cb)(struct perf_evsel *counter, void *data,
+                                      bool first),
+                           void *data)
+{
+       if (counter->merged_stat)
+               return false;
        cb(counter, data, true);
+       if (!no_merge)
+               collect_all_aliases(counter, cb, data);
+       return true;
 }
 
 struct aggr_data {
@@ -1211,6 +1238,16 @@ static void aggr_cb(struct perf_evsel *counter, void *data, bool first)
                if (first)
                        ad->nr++;
                counts = perf_counts(counter->counts, cpu, 0);
+               /*
+                * When any result is bad, make them all to give
+                * consistent output in interval mode.
+                */
+               if (counts->ena == 0 || counts->run == 0 ||
+                   counter->counts->scaled == -1) {
+                       ad->ena = 0;
+                       ad->run = 0;
+                       break;
+               }
                ad->val += counts->val;
                ad->ena += counts->ena;
                ad->run += counts->run;
@@ -1245,7 +1282,8 @@ static void print_aggr(char *prefix)
                evlist__for_each_entry(evsel_list, counter) {
                        ad.val = ad.ena = ad.run = 0;
                        ad.nr = 0;
-                       collect_data(counter, aggr_cb, &ad);
+                       if (!collect_data(counter, aggr_cb, &ad))
+                               continue;
                        nr = ad.nr;
                        ena = ad.ena;
                        run = ad.run;
@@ -1318,7 +1356,8 @@ static void print_counter_aggr(struct perf_evsel *counter, char *prefix)
        double uval;
        struct caggr_data cd = { .avg = 0.0 };
 
-       collect_data(counter, counter_aggr_cb, &cd);
+       if (!collect_data(counter, counter_aggr_cb, &cd))
+               return;
 
        if (prefix && !metric_only)
                fprintf(output, "%s", prefix);
@@ -1353,7 +1392,8 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
        for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
                struct aggr_data ad = { .cpu = cpu };
 
-               collect_data(counter, counter_cb, &ad);
+               if (!collect_data(counter, counter_cb, &ad))
+                       return;
                val = ad.val;
                ena = ad.ena;
                run = ad.run;
@@ -1441,6 +1481,7 @@ static void print_metric_headers(const char *prefix, bool no_indent)
                out.ctx = &os;
                out.print_metric = print_metric_header;
                out.new_line = new_line_metric;
+               out.force_header = true;
                os.evsel = counter;
                perf_stat__print_shadow_stats(counter, 0,
                                              0,
@@ -1701,6 +1742,7 @@ static const struct option stat_options[] = {
                    "list of cpus to monitor in system-wide"),
        OPT_SET_UINT('A', "no-aggr", &stat_config.aggr_mode,
                    "disable CPU count aggregation", AGGR_NONE),
+       OPT_BOOLEAN(0, "no-merge", &no_merge, "Do not merge identical named events"),
        OPT_STRING('x', "field-separator", &csv_sep, "separator",
                   "print counts with custom separator"),
        OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
@@ -2436,7 +2478,7 @@ static void setup_system_wide(int forks)
        }
 }
 
-int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
+int cmd_stat(int argc, const char **argv)
 {
        const char * const stat_usage[] = {
                "perf stat [<options>] [<command>]",
@@ -2458,6 +2500,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
        argc = parse_options_subcommand(argc, argv, stat_options, stat_subcommands,
                                        (const char **) stat_usage,
                                        PARSE_OPT_STOP_AT_NON_OPTION);
+       perf_stat__collect_metric_expr(evsel_list);
        perf_stat__init_shadow_stats();
 
        if (csv_sep) {