forked from Minki/linux
perf stat: Introduce print_counters function
Centralize counters print code into single print_counters function. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1435310967-14570-22-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
5835e22865
commit
d4f63a4741
@ -67,10 +67,7 @@
|
|||||||
#define CNTR_NOT_SUPPORTED "<not supported>"
|
#define CNTR_NOT_SUPPORTED "<not supported>"
|
||||||
#define CNTR_NOT_COUNTED "<not counted>"
|
#define CNTR_NOT_COUNTED "<not counted>"
|
||||||
|
|
||||||
static void print_stat(int argc, const char **argv);
|
static void print_counters(struct timespec *ts, int argc, const char **argv);
|
||||||
static void print_counter_aggr(struct perf_evsel *counter, char *prefix);
|
|
||||||
static void print_counter(struct perf_evsel *counter, char *prefix);
|
|
||||||
static void print_aggr(char *prefix);
|
|
||||||
|
|
||||||
/* Default events used for perf stat -T */
|
/* Default events used for perf stat -T */
|
||||||
static const char *transaction_attrs = {
|
static const char *transaction_attrs = {
|
||||||
@ -365,53 +362,14 @@ static void read_counters(bool close)
|
|||||||
|
|
||||||
static void process_interval(void)
|
static void process_interval(void)
|
||||||
{
|
{
|
||||||
static int num_print_interval;
|
|
||||||
struct perf_evsel *counter;
|
|
||||||
struct timespec ts, rs;
|
struct timespec ts, rs;
|
||||||
char prefix[64];
|
|
||||||
|
|
||||||
read_counters(false);
|
read_counters(false);
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
diff_timespec(&rs, &ts, &ref_time);
|
diff_timespec(&rs, &ts, &ref_time);
|
||||||
sprintf(prefix, "%6lu.%09lu%s", rs.tv_sec, rs.tv_nsec, csv_sep);
|
|
||||||
|
|
||||||
if (num_print_interval == 0 && !csv_output) {
|
print_counters(&rs, 0, NULL);
|
||||||
switch (aggr_mode) {
|
|
||||||
case AGGR_SOCKET:
|
|
||||||
fprintf(output, "# time socket cpus counts %*s events\n", unit_width, "unit");
|
|
||||||
break;
|
|
||||||
case AGGR_CORE:
|
|
||||||
fprintf(output, "# time core cpus counts %*s events\n", unit_width, "unit");
|
|
||||||
break;
|
|
||||||
case AGGR_NONE:
|
|
||||||
fprintf(output, "# time CPU counts %*s events\n", unit_width, "unit");
|
|
||||||
break;
|
|
||||||
case AGGR_GLOBAL:
|
|
||||||
default:
|
|
||||||
fprintf(output, "# time counts %*s events\n", unit_width, "unit");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (++num_print_interval == 25)
|
|
||||||
num_print_interval = 0;
|
|
||||||
|
|
||||||
switch (aggr_mode) {
|
|
||||||
case AGGR_CORE:
|
|
||||||
case AGGR_SOCKET:
|
|
||||||
print_aggr(prefix);
|
|
||||||
break;
|
|
||||||
case AGGR_NONE:
|
|
||||||
evlist__for_each(evsel_list, counter)
|
|
||||||
print_counter(counter, prefix);
|
|
||||||
break;
|
|
||||||
case AGGR_GLOBAL:
|
|
||||||
default:
|
|
||||||
evlist__for_each(evsel_list, counter)
|
|
||||||
print_counter_aggr(counter, prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
fflush(output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_initial_delay(void)
|
static void handle_initial_delay(void)
|
||||||
@ -901,9 +859,35 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_stat(int argc, const char **argv)
|
static void print_interval(char *prefix, struct timespec *ts)
|
||||||
|
{
|
||||||
|
static int num_print_interval;
|
||||||
|
|
||||||
|
sprintf(prefix, "%6lu.%09lu%s", ts->tv_sec, ts->tv_nsec, csv_sep);
|
||||||
|
|
||||||
|
if (num_print_interval == 0 && !csv_output) {
|
||||||
|
switch (aggr_mode) {
|
||||||
|
case AGGR_SOCKET:
|
||||||
|
fprintf(output, "# time socket cpus counts %*s events\n", unit_width, "unit");
|
||||||
|
break;
|
||||||
|
case AGGR_CORE:
|
||||||
|
fprintf(output, "# time core cpus counts %*s events\n", unit_width, "unit");
|
||||||
|
break;
|
||||||
|
case AGGR_NONE:
|
||||||
|
fprintf(output, "# time CPU counts %*s events\n", unit_width, "unit");
|
||||||
|
break;
|
||||||
|
case AGGR_GLOBAL:
|
||||||
|
default:
|
||||||
|
fprintf(output, "# time counts %*s events\n", unit_width, "unit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (++num_print_interval == 25)
|
||||||
|
num_print_interval = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_header(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
struct perf_evsel *counter;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
@ -929,36 +913,53 @@ static void print_stat(int argc, const char **argv)
|
|||||||
fprintf(output, " (%d runs)", run_count);
|
fprintf(output, " (%d runs)", run_count);
|
||||||
fprintf(output, ":\n\n");
|
fprintf(output, ":\n\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_footer(void)
|
||||||
|
{
|
||||||
|
if (!null_run)
|
||||||
|
fprintf(output, "\n");
|
||||||
|
fprintf(output, " %17.9f seconds time elapsed",
|
||||||
|
avg_stats(&walltime_nsecs_stats)/1e9);
|
||||||
|
if (run_count > 1) {
|
||||||
|
fprintf(output, " ");
|
||||||
|
print_noise_pct(stddev_stats(&walltime_nsecs_stats),
|
||||||
|
avg_stats(&walltime_nsecs_stats));
|
||||||
|
}
|
||||||
|
fprintf(output, "\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_counters(struct timespec *ts, int argc, const char **argv)
|
||||||
|
{
|
||||||
|
struct perf_evsel *counter;
|
||||||
|
char buf[64], *prefix = NULL;
|
||||||
|
|
||||||
|
if (interval)
|
||||||
|
print_interval(prefix = buf, ts);
|
||||||
|
else
|
||||||
|
print_header(argc, argv);
|
||||||
|
|
||||||
switch (aggr_mode) {
|
switch (aggr_mode) {
|
||||||
case AGGR_CORE:
|
case AGGR_CORE:
|
||||||
case AGGR_SOCKET:
|
case AGGR_SOCKET:
|
||||||
print_aggr(NULL);
|
print_aggr(prefix);
|
||||||
break;
|
break;
|
||||||
case AGGR_GLOBAL:
|
case AGGR_GLOBAL:
|
||||||
evlist__for_each(evsel_list, counter)
|
evlist__for_each(evsel_list, counter)
|
||||||
print_counter_aggr(counter, NULL);
|
print_counter_aggr(counter, prefix);
|
||||||
break;
|
break;
|
||||||
case AGGR_NONE:
|
case AGGR_NONE:
|
||||||
evlist__for_each(evsel_list, counter)
|
evlist__for_each(evsel_list, counter)
|
||||||
print_counter(counter, NULL);
|
print_counter(counter, prefix);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!csv_output) {
|
if (!interval && !csv_output)
|
||||||
if (!null_run)
|
print_footer();
|
||||||
fprintf(output, "\n");
|
|
||||||
fprintf(output, " %17.9f seconds time elapsed",
|
fflush(output);
|
||||||
avg_stats(&walltime_nsecs_stats)/1e9);
|
|
||||||
if (run_count > 1) {
|
|
||||||
fprintf(output, " ");
|
|
||||||
print_noise_pct(stddev_stats(&walltime_nsecs_stats),
|
|
||||||
avg_stats(&walltime_nsecs_stats));
|
|
||||||
}
|
|
||||||
fprintf(output, "\n\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static volatile int signr = -1;
|
static volatile int signr = -1;
|
||||||
@ -1407,13 +1408,13 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
|
|||||||
|
|
||||||
status = run_perf_stat(argc, argv);
|
status = run_perf_stat(argc, argv);
|
||||||
if (forever && status != -1) {
|
if (forever && status != -1) {
|
||||||
print_stat(argc, argv);
|
print_counters(NULL, argc, argv);
|
||||||
perf_stat__reset_stats();
|
perf_stat__reset_stats();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!forever && status != -1 && !interval)
|
if (!forever && status != -1 && !interval)
|
||||||
print_stat(argc, argv);
|
print_counters(NULL, argc, argv);
|
||||||
|
|
||||||
perf_evlist__free_stats(evsel_list);
|
perf_evlist__free_stats(evsel_list);
|
||||||
out:
|
out:
|
||||||
|
Loading…
Reference in New Issue
Block a user