[PATCH 23/30] perf stat: Separate counters reading and processing

From: Jiri Olsa
Date: Sun Jun 14 2015 - 04:22:43 EST


Separating counters reading and processing so we could use
the processing part in following patches.

Using simple reading via perf_evsel__read function
to read counters now, because part of the processing
was in the read_cb callback.

Link: http://lkml.kernel.org/n/tip-u2z2wndrt664tkk3v3sh9bxz@xxxxxxxxxxxxxx
Signed-off-by: Jiri Olsa <jolsa@xxxxxxxxxx>
---
tools/perf/builtin-stat.c | 56 +++++++++++++++++++++++++++++++++--------------
1 file changed, 39 insertions(+), 17 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 72d43484507e..3b923e179d90 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -223,8 +223,9 @@ static int check_per_pkg(struct perf_evsel *counter, int cpu, bool *skip)
return 0;
}

-static int read_cb(struct perf_evsel *evsel, int cpu, int thread,
- struct perf_counts_values *count)
+static int
+process_counter_values(struct perf_evsel *evsel, int cpu, int thread,
+ struct perf_counts_values *count)
{
struct perf_counts_values *aggr = &evsel->counts->aggr;
static struct perf_counts_values zero;
@@ -245,7 +246,6 @@ static int read_cb(struct perf_evsel *evsel, int cpu, int thread,
if (!evsel->snapshot)
perf_evsel__compute_deltas(evsel, cpu, thread, count);
perf_counts_values__scale(count, scale, NULL);
- *perf_counts(evsel->counts, cpu, thread) = *count;
if (aggr_mode == AGGR_NONE)
perf_stat__update_shadow_stats(evsel, count->values, cpu);
break;
@@ -262,23 +262,41 @@ static int read_cb(struct perf_evsel *evsel, int cpu, int thread,
return 0;
}

-static int read_counter(struct perf_evsel *counter);
+static int process_counter_maps(struct perf_evsel *counter)
+{
+ int nthreads = thread_map__nr(counter->threads);
+ int ncpus = perf_evsel__nr_cpus(counter);
+ int cpu, thread;

-/*
- * Read out the results of a single counter:
- * aggregate counts across CPUs in system-wide mode
- */
-static int read_counter_aggr(struct perf_evsel *counter)
+ if (counter->system_wide)
+ nthreads = 1;
+
+ for (thread = 0; thread < nthreads; thread++) {
+ for (cpu = 0; cpu < ncpus; cpu++) {
+ if (process_counter_values(counter, cpu, thread,
+ perf_counts(counter->counts, cpu, thread)))
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int process_counter(struct perf_evsel *counter)
{
struct perf_counts_values *aggr = &counter->counts->aggr;
struct perf_stat *ps = counter->priv;
u64 *count = counter->counts->aggr.values;
- int i;
+ int i, ret;

aggr->val = aggr->ena = aggr->run = 0;

- if (read_counter(counter))
- return -1;
+ ret = process_counter_maps(counter);
+ if (ret)
+ return ret;
+
+ if (aggr_mode != AGGR_GLOBAL)
+ return 0;

if (!counter->snapshot)
perf_evsel__compute_deltas(counter, -1, -1, aggr);
@@ -321,7 +339,10 @@ static int read_counter(struct perf_evsel *counter)

for (thread = 0; thread < nthreads; thread++) {
for (cpu = 0; cpu < ncpus; cpu++) {
- if (perf_evsel__read_cb(counter, cpu, thread, read_cb))
+ struct perf_counts_values *count;
+
+ count = perf_counts(counter->counts, cpu, thread);
+ if (perf_evsel__read(counter, cpu, thread, count))
return -1;
}
}
@@ -338,10 +359,11 @@ static void read_counters(bool close)
ps = counter->priv;
memset(ps->res_stats, 0, sizeof(ps->res_stats));

- if (aggr_mode == AGGR_GLOBAL)
- read_counter_aggr(counter);
- else
- read_counter(counter);
+ if (read_counter(counter))
+ pr_warning("failed to read counter %s\n", counter->name);
+
+ if (process_counter(counter))
+ pr_warning("failed to process counter %s\n", counter->name);

if (close) {
perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
--
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/