diff options
Diffstat (limited to 'tools/perf/builtin-stat.c')
-rw-r--r-- | tools/perf/builtin-stat.c | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index a482a191a0ca..8906adfdbd8e 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -43,11 +43,13 @@ | |||
43 | #include "util/parse-options.h" | 43 | #include "util/parse-options.h" |
44 | #include "util/parse-events.h" | 44 | #include "util/parse-events.h" |
45 | #include "util/event.h" | 45 | #include "util/event.h" |
46 | #include "util/evlist.h" | ||
46 | #include "util/evsel.h" | 47 | #include "util/evsel.h" |
47 | #include "util/debug.h" | 48 | #include "util/debug.h" |
48 | #include "util/header.h" | 49 | #include "util/header.h" |
49 | #include "util/cpumap.h" | 50 | #include "util/cpumap.h" |
50 | #include "util/thread.h" | 51 | #include "util/thread.h" |
52 | #include "util/thread_map.h" | ||
51 | 53 | ||
52 | #include <sys/prctl.h> | 54 | #include <sys/prctl.h> |
53 | #include <math.h> | 55 | #include <math.h> |
@@ -71,6 +73,8 @@ static struct perf_event_attr default_attrs[] = { | |||
71 | 73 | ||
72 | }; | 74 | }; |
73 | 75 | ||
76 | struct perf_evlist *evsel_list; | ||
77 | |||
74 | static bool system_wide = false; | 78 | static bool system_wide = false; |
75 | static struct cpu_map *cpus; | 79 | static struct cpu_map *cpus; |
76 | static int run_idx = 0; | 80 | static int run_idx = 0; |
@@ -166,7 +170,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel) | |||
166 | PERF_FORMAT_TOTAL_TIME_RUNNING; | 170 | PERF_FORMAT_TOTAL_TIME_RUNNING; |
167 | 171 | ||
168 | if (system_wide) | 172 | if (system_wide) |
169 | return perf_evsel__open_per_cpu(evsel, cpus); | 173 | return perf_evsel__open_per_cpu(evsel, cpus, false, false); |
170 | 174 | ||
171 | attr->inherit = !no_inherit; | 175 | attr->inherit = !no_inherit; |
172 | if (target_pid == -1 && target_tid == -1) { | 176 | if (target_pid == -1 && target_tid == -1) { |
@@ -174,7 +178,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel) | |||
174 | attr->enable_on_exec = 1; | 178 | attr->enable_on_exec = 1; |
175 | } | 179 | } |
176 | 180 | ||
177 | return perf_evsel__open_per_thread(evsel, threads); | 181 | return perf_evsel__open_per_thread(evsel, threads, false, false); |
178 | } | 182 | } |
179 | 183 | ||
180 | /* | 184 | /* |
@@ -309,7 +313,7 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
309 | close(child_ready_pipe[0]); | 313 | close(child_ready_pipe[0]); |
310 | } | 314 | } |
311 | 315 | ||
312 | list_for_each_entry(counter, &evsel_list, node) { | 316 | list_for_each_entry(counter, &evsel_list->entries, node) { |
313 | if (create_perf_stat_counter(counter) < 0) { | 317 | if (create_perf_stat_counter(counter) < 0) { |
314 | if (errno == -EPERM || errno == -EACCES) { | 318 | if (errno == -EPERM || errno == -EACCES) { |
315 | error("You may not have permission to collect %sstats.\n" | 319 | error("You may not have permission to collect %sstats.\n" |
@@ -347,12 +351,12 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
347 | update_stats(&walltime_nsecs_stats, t1 - t0); | 351 | update_stats(&walltime_nsecs_stats, t1 - t0); |
348 | 352 | ||
349 | if (no_aggr) { | 353 | if (no_aggr) { |
350 | list_for_each_entry(counter, &evsel_list, node) { | 354 | list_for_each_entry(counter, &evsel_list->entries, node) { |
351 | read_counter(counter); | 355 | read_counter(counter); |
352 | perf_evsel__close_fd(counter, cpus->nr, 1); | 356 | perf_evsel__close_fd(counter, cpus->nr, 1); |
353 | } | 357 | } |
354 | } else { | 358 | } else { |
355 | list_for_each_entry(counter, &evsel_list, node) { | 359 | list_for_each_entry(counter, &evsel_list->entries, node) { |
356 | read_counter_aggr(counter); | 360 | read_counter_aggr(counter); |
357 | perf_evsel__close_fd(counter, cpus->nr, threads->nr); | 361 | perf_evsel__close_fd(counter, cpus->nr, threads->nr); |
358 | } | 362 | } |
@@ -555,10 +559,10 @@ static void print_stat(int argc, const char **argv) | |||
555 | } | 559 | } |
556 | 560 | ||
557 | if (no_aggr) { | 561 | if (no_aggr) { |
558 | list_for_each_entry(counter, &evsel_list, node) | 562 | list_for_each_entry(counter, &evsel_list->entries, node) |
559 | print_counter(counter); | 563 | print_counter(counter); |
560 | } else { | 564 | } else { |
561 | list_for_each_entry(counter, &evsel_list, node) | 565 | list_for_each_entry(counter, &evsel_list->entries, node) |
562 | print_counter_aggr(counter); | 566 | print_counter_aggr(counter); |
563 | } | 567 | } |
564 | 568 | ||
@@ -610,7 +614,7 @@ static int stat__set_big_num(const struct option *opt __used, | |||
610 | } | 614 | } |
611 | 615 | ||
612 | static const struct option options[] = { | 616 | static const struct option options[] = { |
613 | OPT_CALLBACK('e', "event", NULL, "event", | 617 | OPT_CALLBACK('e', "event", &evsel_list, "event", |
614 | "event selector. use 'perf list' to list available events", | 618 | "event selector. use 'perf list' to list available events", |
615 | parse_events), | 619 | parse_events), |
616 | OPT_BOOLEAN('i', "no-inherit", &no_inherit, | 620 | OPT_BOOLEAN('i', "no-inherit", &no_inherit, |
@@ -648,6 +652,10 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
648 | 652 | ||
649 | setlocale(LC_ALL, ""); | 653 | setlocale(LC_ALL, ""); |
650 | 654 | ||
655 | evsel_list = perf_evlist__new(); | ||
656 | if (evsel_list == NULL) | ||
657 | return -ENOMEM; | ||
658 | |||
651 | argc = parse_options(argc, argv, options, stat_usage, | 659 | argc = parse_options(argc, argv, options, stat_usage, |
652 | PARSE_OPT_STOP_AT_NON_OPTION); | 660 | PARSE_OPT_STOP_AT_NON_OPTION); |
653 | 661 | ||
@@ -679,17 +687,14 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
679 | usage_with_options(stat_usage, options); | 687 | usage_with_options(stat_usage, options); |
680 | 688 | ||
681 | /* Set attrs and nr_counters if no event is selected and !null_run */ | 689 | /* Set attrs and nr_counters if no event is selected and !null_run */ |
682 | if (!null_run && !nr_counters) { | 690 | if (!null_run && !evsel_list->nr_entries) { |
683 | size_t c; | 691 | size_t c; |
684 | 692 | ||
685 | nr_counters = ARRAY_SIZE(default_attrs); | ||
686 | |||
687 | for (c = 0; c < ARRAY_SIZE(default_attrs); ++c) { | 693 | for (c = 0; c < ARRAY_SIZE(default_attrs); ++c) { |
688 | pos = perf_evsel__new(&default_attrs[c], | 694 | pos = perf_evsel__new(&default_attrs[c], c); |
689 | nr_counters); | ||
690 | if (pos == NULL) | 695 | if (pos == NULL) |
691 | goto out; | 696 | goto out; |
692 | list_add(&pos->node, &evsel_list); | 697 | perf_evlist__add(evsel_list, pos); |
693 | } | 698 | } |
694 | } | 699 | } |
695 | 700 | ||
@@ -713,7 +718,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
713 | return -1; | 718 | return -1; |
714 | } | 719 | } |
715 | 720 | ||
716 | list_for_each_entry(pos, &evsel_list, node) { | 721 | list_for_each_entry(pos, &evsel_list->entries, node) { |
717 | if (perf_evsel__alloc_stat_priv(pos) < 0 || | 722 | if (perf_evsel__alloc_stat_priv(pos) < 0 || |
718 | perf_evsel__alloc_counts(pos, cpus->nr) < 0 || | 723 | perf_evsel__alloc_counts(pos, cpus->nr) < 0 || |
719 | perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0) | 724 | perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0) |
@@ -741,9 +746,9 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
741 | if (status != -1) | 746 | if (status != -1) |
742 | print_stat(argc, argv); | 747 | print_stat(argc, argv); |
743 | out_free_fd: | 748 | out_free_fd: |
744 | list_for_each_entry(pos, &evsel_list, node) | 749 | list_for_each_entry(pos, &evsel_list->entries, node) |
745 | perf_evsel__free_stat_priv(pos); | 750 | perf_evsel__free_stat_priv(pos); |
746 | perf_evsel_list__delete(); | 751 | perf_evlist__delete(evsel_list); |
747 | out: | 752 | out: |
748 | thread_map__delete(threads); | 753 | thread_map__delete(threads); |
749 | threads = NULL; | 754 | threads = NULL; |