diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-01-03 13:39:04 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-01-03 13:39:04 -0500 |
commit | 69aad6f1ee69546dea8535ab8f3da9f445d57328 (patch) | |
tree | b328ec140a6a90703a049fcc661d623025d7e81f /tools/perf/util/parse-events.c | |
parent | 56f4c400349157289b474a3fd49ee96acab0a4d7 (diff) |
perf tools: Introduce event selectors
Out of ad-hoc code and global arrays with hard coded sizes.
This is the first step on having a library that will be first
used on regression tests in the 'perf test' tool.
[acme@felicio linux]$ size /tmp/perf.before
text data bss dec hex filename
1273776 97384 5104416 6475576 62cf38 /tmp/perf.before
[acme@felicio linux]$ size /tmp/perf.new
text data bss dec hex filename
1275422 97416 1392416 2765254 2a31c6 /tmp/perf.new
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/parse-events.c')
-rw-r--r-- | tools/perf/util/parse-events.c | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index c305305a3884..2d948ad471f4 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -1,6 +1,7 @@ | |||
1 | #include "../../../include/linux/hw_breakpoint.h" | 1 | #include "../../../include/linux/hw_breakpoint.h" |
2 | #include "util.h" | 2 | #include "util.h" |
3 | #include "../perf.h" | 3 | #include "../perf.h" |
4 | #include "evsel.h" | ||
4 | #include "parse-options.h" | 5 | #include "parse-options.h" |
5 | #include "parse-events.h" | 6 | #include "parse-events.h" |
6 | #include "exec_cmd.h" | 7 | #include "exec_cmd.h" |
@@ -12,8 +13,7 @@ | |||
12 | 13 | ||
13 | int nr_counters; | 14 | int nr_counters; |
14 | 15 | ||
15 | struct perf_event_attr attrs[MAX_COUNTERS]; | 16 | LIST_HEAD(evsel_list); |
16 | char *filters[MAX_COUNTERS]; | ||
17 | 17 | ||
18 | struct event_symbol { | 18 | struct event_symbol { |
19 | u8 type; | 19 | u8 type; |
@@ -266,10 +266,10 @@ static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result) | |||
266 | return name; | 266 | return name; |
267 | } | 267 | } |
268 | 268 | ||
269 | const char *event_name(int counter) | 269 | const char *event_name(struct perf_evsel *evsel) |
270 | { | 270 | { |
271 | u64 config = attrs[counter].config; | 271 | u64 config = evsel->attr.config; |
272 | int type = attrs[counter].type; | 272 | int type = evsel->attr.type; |
273 | 273 | ||
274 | return __event_name(type, config); | 274 | return __event_name(type, config); |
275 | } | 275 | } |
@@ -814,9 +814,6 @@ int parse_events(const struct option *opt __used, const char *str, int unset __u | |||
814 | return -1; | 814 | return -1; |
815 | 815 | ||
816 | for (;;) { | 816 | for (;;) { |
817 | if (nr_counters == MAX_COUNTERS) | ||
818 | return -1; | ||
819 | |||
820 | memset(&attr, 0, sizeof(attr)); | 817 | memset(&attr, 0, sizeof(attr)); |
821 | ret = parse_event_symbols(&str, &attr); | 818 | ret = parse_event_symbols(&str, &attr); |
822 | if (ret == EVT_FAILED) | 819 | if (ret == EVT_FAILED) |
@@ -826,8 +823,13 @@ int parse_events(const struct option *opt __used, const char *str, int unset __u | |||
826 | return -1; | 823 | return -1; |
827 | 824 | ||
828 | if (ret != EVT_HANDLED_ALL) { | 825 | if (ret != EVT_HANDLED_ALL) { |
829 | attrs[nr_counters] = attr; | 826 | struct perf_evsel *evsel; |
830 | nr_counters++; | 827 | evsel = perf_evsel__new(attr.type, attr.config, |
828 | nr_counters); | ||
829 | if (evsel == NULL) | ||
830 | return -1; | ||
831 | list_add_tail(&evsel->node, &evsel_list); | ||
832 | ++nr_counters; | ||
831 | } | 833 | } |
832 | 834 | ||
833 | if (*str == 0) | 835 | if (*str == 0) |
@@ -844,21 +846,22 @@ int parse_events(const struct option *opt __used, const char *str, int unset __u | |||
844 | int parse_filter(const struct option *opt __used, const char *str, | 846 | int parse_filter(const struct option *opt __used, const char *str, |
845 | int unset __used) | 847 | int unset __used) |
846 | { | 848 | { |
847 | int i = nr_counters - 1; | 849 | struct perf_evsel *last = NULL; |
848 | int len = strlen(str); | ||
849 | 850 | ||
850 | if (i < 0 || attrs[i].type != PERF_TYPE_TRACEPOINT) { | 851 | if (!list_empty(&evsel_list)) |
852 | last = list_entry(evsel_list.prev, struct perf_evsel, node); | ||
853 | |||
854 | if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) { | ||
851 | fprintf(stderr, | 855 | fprintf(stderr, |
852 | "-F option should follow a -e tracepoint option\n"); | 856 | "-F option should follow a -e tracepoint option\n"); |
853 | return -1; | 857 | return -1; |
854 | } | 858 | } |
855 | 859 | ||
856 | filters[i] = malloc(len + 1); | 860 | last->filter = strdup(str); |
857 | if (!filters[i]) { | 861 | if (last->filter == NULL) { |
858 | fprintf(stderr, "not enough memory to hold filter string\n"); | 862 | fprintf(stderr, "not enough memory to hold filter string\n"); |
859 | return -1; | 863 | return -1; |
860 | } | 864 | } |
861 | strcpy(filters[i], str); | ||
862 | 865 | ||
863 | return 0; | 866 | return 0; |
864 | } | 867 | } |
@@ -967,3 +970,15 @@ void print_events(void) | |||
967 | 970 | ||
968 | exit(129); | 971 | exit(129); |
969 | } | 972 | } |
973 | |||
974 | int perf_evsel_list__create_default(void) | ||
975 | { | ||
976 | struct perf_evsel *evsel = perf_evsel__new(PERF_TYPE_HARDWARE, | ||
977 | PERF_COUNT_HW_CPU_CYCLES, 0); | ||
978 | if (evsel == NULL) | ||
979 | return -ENOMEM; | ||
980 | |||
981 | list_add(&evsel->node, &evsel_list); | ||
982 | ++nr_counters; | ||
983 | return 0; | ||
984 | } | ||