perf stat: Fix interval output values
[cascardo/linux.git] / tools / perf / util / stat.c
index 2d9d830..afb0c45 100644 (file)
@@ -310,7 +310,16 @@ int perf_stat_process_counter(struct perf_stat_config *config,
        int i, ret;
 
        aggr->val = aggr->ena = aggr->run = 0;
-       init_stats(ps->res_stats);
+
+       /*
+        * We calculate counter's data every interval,
+        * and the display code shows ps->res_stats
+        * avg value. We need to zero the stats for
+        * interval mode, otherwise overall avg running
+        * averages will be shown for each interval.
+        */
+       if (config->interval)
+               init_stats(ps->res_stats);
 
        if (counter->per_pkg)
                zero_per_pkg(counter);
@@ -341,3 +350,65 @@ int perf_stat_process_counter(struct perf_stat_config *config,
 
        return 0;
 }
+
+int perf_event__process_stat_event(struct perf_tool *tool __maybe_unused,
+                                  union perf_event *event,
+                                  struct perf_session *session)
+{
+       struct perf_counts_values count;
+       struct stat_event *st = &event->stat;
+       struct perf_evsel *counter;
+
+       count.val = st->val;
+       count.ena = st->ena;
+       count.run = st->run;
+
+       counter = perf_evlist__id2evsel(session->evlist, st->id);
+       if (!counter) {
+               pr_err("Failed to resolve counter for stat event.\n");
+               return -EINVAL;
+       }
+
+       *perf_counts(counter->counts, st->cpu, st->thread) = count;
+       counter->supported = true;
+       return 0;
+}
+
+size_t perf_event__fprintf_stat(union perf_event *event, FILE *fp)
+{
+       struct stat_event *st = (struct stat_event *) event;
+       size_t ret;
+
+       ret  = fprintf(fp, "\n... id %" PRIu64 ", cpu %d, thread %d\n",
+                      st->id, st->cpu, st->thread);
+       ret += fprintf(fp, "... value %" PRIu64 ", enabled %" PRIu64 ", running %" PRIu64 "\n",
+                      st->val, st->ena, st->run);
+
+       return ret;
+}
+
+size_t perf_event__fprintf_stat_round(union perf_event *event, FILE *fp)
+{
+       struct stat_round_event *rd = (struct stat_round_event *)event;
+       size_t ret;
+
+       ret = fprintf(fp, "\n... time %" PRIu64 ", type %s\n", rd->time,
+                     rd->type == PERF_STAT_ROUND_TYPE__FINAL ? "FINAL" : "INTERVAL");
+
+       return ret;
+}
+
+size_t perf_event__fprintf_stat_config(union perf_event *event, FILE *fp)
+{
+       struct perf_stat_config sc;
+       size_t ret;
+
+       perf_event__read_stat_config(&sc, &event->stat_config);
+
+       ret  = fprintf(fp, "\n");
+       ret += fprintf(fp, "... aggr_mode %d\n", sc.aggr_mode);
+       ret += fprintf(fp, "... scale     %d\n", sc.scale);
+       ret += fprintf(fp, "... interval  %u\n", sc.interval);
+
+       return ret;
+}