diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-01-11 17:56:53 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-01-22 16:56:28 -0500 |
commit | 361c99a661a78ed22264649440e87fe4fe8da1f2 (patch) | |
tree | a60bc86f132608f2d41c800760b41f6f54f8e7af /tools/perf/util | |
parent | 00e99a49f6f3a6b5a84ba8bf8f632c9b974bea7a (diff) |
perf evsel: Introduce perf_evlist
Killing two more perf wide global variables: nr_counters and evsel_list
as a list_head.
There are more operations that will need more fields in perf_evlist,
like the pollfd for polling all the fds in a list of evsel instances.
Use option->value to pass the evsel_list to parse_{events,filters}.
LKML-Reference: <new-submission>
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>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/evlist.c | 53 | ||||
-rw-r--r-- | tools/perf/util/evlist.h | 19 | ||||
-rw-r--r-- | tools/perf/util/header.c | 17 | ||||
-rw-r--r-- | tools/perf/util/header.h | 7 | ||||
-rw-r--r-- | tools/perf/util/include/linux/list.h | 1 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 51 | ||||
-rw-r--r-- | tools/perf/util/parse-events.h | 7 |
7 files changed, 97 insertions, 58 deletions
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c new file mode 100644 index 000000000000..7b4faec23737 --- /dev/null +++ b/tools/perf/util/evlist.c | |||
@@ -0,0 +1,53 @@ | |||
1 | #include "evlist.h" | ||
2 | #include "evsel.h" | ||
3 | #include "util.h" | ||
4 | |||
5 | struct perf_evlist *perf_evlist__new(void) | ||
6 | { | ||
7 | struct perf_evlist *evlist = zalloc(sizeof(*evlist)); | ||
8 | |||
9 | if (evlist != NULL) { | ||
10 | INIT_LIST_HEAD(&evlist->entries); | ||
11 | } | ||
12 | |||
13 | return evlist; | ||
14 | } | ||
15 | |||
16 | static void perf_evlist__purge(struct perf_evlist *evlist) | ||
17 | { | ||
18 | struct perf_evsel *pos, *n; | ||
19 | |||
20 | list_for_each_entry_safe(pos, n, &evlist->entries, node) { | ||
21 | list_del_init(&pos->node); | ||
22 | perf_evsel__delete(pos); | ||
23 | } | ||
24 | |||
25 | evlist->nr_entries = 0; | ||
26 | } | ||
27 | |||
28 | void perf_evlist__delete(struct perf_evlist *evlist) | ||
29 | { | ||
30 | perf_evlist__purge(evlist); | ||
31 | free(evlist); | ||
32 | } | ||
33 | |||
34 | void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) | ||
35 | { | ||
36 | list_add_tail(&entry->node, &evlist->entries); | ||
37 | ++evlist->nr_entries; | ||
38 | } | ||
39 | |||
40 | int perf_evlist__add_default(struct perf_evlist *evlist) | ||
41 | { | ||
42 | struct perf_event_attr attr = { | ||
43 | .type = PERF_TYPE_HARDWARE, | ||
44 | .config = PERF_COUNT_HW_CPU_CYCLES, | ||
45 | }; | ||
46 | struct perf_evsel *evsel = perf_evsel__new(&attr, 0); | ||
47 | |||
48 | if (evsel == NULL) | ||
49 | return -ENOMEM; | ||
50 | |||
51 | perf_evlist__add(evlist, evsel); | ||
52 | return 0; | ||
53 | } | ||
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h new file mode 100644 index 000000000000..48db91a8abf3 --- /dev/null +++ b/tools/perf/util/evlist.h | |||
@@ -0,0 +1,19 @@ | |||
1 | #ifndef __PERF_EVLIST_H | ||
2 | #define __PERF_EVLIST_H 1 | ||
3 | |||
4 | #include <linux/list.h> | ||
5 | |||
6 | struct perf_evlist { | ||
7 | struct list_head entries; | ||
8 | int nr_entries; | ||
9 | }; | ||
10 | |||
11 | struct perf_evsel; | ||
12 | |||
13 | struct perf_evlist *perf_evlist__new(void); | ||
14 | void perf_evlist__delete(struct perf_evlist *evlist); | ||
15 | |||
16 | void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry); | ||
17 | int perf_evlist__add_default(struct perf_evlist *evlist); | ||
18 | |||
19 | #endif /* __PERF_EVLIST_H */ | ||
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index f6a929e74981..f0138d472339 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/list.h> | 8 | #include <linux/list.h> |
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | 10 | ||
11 | #include "evlist.h" | ||
11 | #include "util.h" | 12 | #include "util.h" |
12 | #include "header.h" | 13 | #include "header.h" |
13 | #include "../perf.h" | 14 | #include "../perf.h" |
@@ -428,7 +429,8 @@ static bool perf_session__read_build_ids(struct perf_session *self, bool with_hi | |||
428 | return ret; | 429 | return ret; |
429 | } | 430 | } |
430 | 431 | ||
431 | static int perf_header__adds_write(struct perf_header *self, int fd) | 432 | static int perf_header__adds_write(struct perf_header *self, |
433 | struct perf_evlist *evlist, int fd) | ||
432 | { | 434 | { |
433 | int nr_sections; | 435 | int nr_sections; |
434 | struct perf_session *session; | 436 | struct perf_session *session; |
@@ -463,7 +465,7 @@ static int perf_header__adds_write(struct perf_header *self, int fd) | |||
463 | 465 | ||
464 | /* Write trace info */ | 466 | /* Write trace info */ |
465 | trace_sec->offset = lseek(fd, 0, SEEK_CUR); | 467 | trace_sec->offset = lseek(fd, 0, SEEK_CUR); |
466 | read_tracing_data(fd, &evsel_list); | 468 | read_tracing_data(fd, &evlist->entries); |
467 | trace_sec->size = lseek(fd, 0, SEEK_CUR) - trace_sec->offset; | 469 | trace_sec->size = lseek(fd, 0, SEEK_CUR) - trace_sec->offset; |
468 | } | 470 | } |
469 | 471 | ||
@@ -513,7 +515,8 @@ int perf_header__write_pipe(int fd) | |||
513 | return 0; | 515 | return 0; |
514 | } | 516 | } |
515 | 517 | ||
516 | int perf_header__write(struct perf_header *self, int fd, bool at_exit) | 518 | int perf_header__write(struct perf_header *self, struct perf_evlist *evlist, |
519 | int fd, bool at_exit) | ||
517 | { | 520 | { |
518 | struct perf_file_header f_header; | 521 | struct perf_file_header f_header; |
519 | struct perf_file_attr f_attr; | 522 | struct perf_file_attr f_attr; |
@@ -566,7 +569,7 @@ int perf_header__write(struct perf_header *self, int fd, bool at_exit) | |||
566 | self->data_offset = lseek(fd, 0, SEEK_CUR); | 569 | self->data_offset = lseek(fd, 0, SEEK_CUR); |
567 | 570 | ||
568 | if (at_exit) { | 571 | if (at_exit) { |
569 | err = perf_header__adds_write(self, fd); | 572 | err = perf_header__adds_write(self, evlist, fd); |
570 | if (err < 0) | 573 | if (err < 0) |
571 | return err; | 574 | return err; |
572 | } | 575 | } |
@@ -1133,7 +1136,7 @@ int event__process_event_type(event_t *self, | |||
1133 | return 0; | 1136 | return 0; |
1134 | } | 1137 | } |
1135 | 1138 | ||
1136 | int event__synthesize_tracing_data(int fd, struct list_head *pattrs, | 1139 | int event__synthesize_tracing_data(int fd, struct perf_evlist *evlist, |
1137 | event__handler_t process, | 1140 | event__handler_t process, |
1138 | struct perf_session *session __unused) | 1141 | struct perf_session *session __unused) |
1139 | { | 1142 | { |
@@ -1144,7 +1147,7 @@ int event__synthesize_tracing_data(int fd, struct list_head *pattrs, | |||
1144 | memset(&ev, 0, sizeof(ev)); | 1147 | memset(&ev, 0, sizeof(ev)); |
1145 | 1148 | ||
1146 | ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA; | 1149 | ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA; |
1147 | size = read_tracing_data_size(fd, pattrs); | 1150 | size = read_tracing_data_size(fd, &evlist->entries); |
1148 | if (size <= 0) | 1151 | if (size <= 0) |
1149 | return size; | 1152 | return size; |
1150 | aligned_size = ALIGN(size, sizeof(u64)); | 1153 | aligned_size = ALIGN(size, sizeof(u64)); |
@@ -1154,7 +1157,7 @@ int event__synthesize_tracing_data(int fd, struct list_head *pattrs, | |||
1154 | 1157 | ||
1155 | process(&ev, NULL, session); | 1158 | process(&ev, NULL, session); |
1156 | 1159 | ||
1157 | err = read_tracing_data(fd, pattrs); | 1160 | err = read_tracing_data(fd, &evlist->entries); |
1158 | write_padded(fd, NULL, 0, padding); | 1161 | write_padded(fd, NULL, 0, padding); |
1159 | 1162 | ||
1160 | return aligned_size; | 1163 | return aligned_size; |
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index 33f16be7b72f..65afd7f74e0d 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h | |||
@@ -65,8 +65,11 @@ struct perf_header { | |||
65 | int perf_header__init(struct perf_header *self); | 65 | int perf_header__init(struct perf_header *self); |
66 | void perf_header__exit(struct perf_header *self); | 66 | void perf_header__exit(struct perf_header *self); |
67 | 67 | ||
68 | struct perf_evlist; | ||
69 | |||
68 | int perf_header__read(struct perf_session *session, int fd); | 70 | int perf_header__read(struct perf_session *session, int fd); |
69 | int perf_header__write(struct perf_header *self, int fd, bool at_exit); | 71 | int perf_header__write(struct perf_header *self, struct perf_evlist *evlist, |
72 | int fd, bool at_exit); | ||
70 | int perf_header__write_pipe(int fd); | 73 | int perf_header__write_pipe(int fd); |
71 | 74 | ||
72 | int perf_header__add_attr(struct perf_header *self, | 75 | int perf_header__add_attr(struct perf_header *self, |
@@ -113,7 +116,7 @@ int event__synthesize_event_types(event__handler_t process, | |||
113 | int event__process_event_type(event_t *self, | 116 | int event__process_event_type(event_t *self, |
114 | struct perf_session *session); | 117 | struct perf_session *session); |
115 | 118 | ||
116 | int event__synthesize_tracing_data(int fd, struct list_head *pattrs, | 119 | int event__synthesize_tracing_data(int fd, struct perf_evlist *evlist, |
117 | event__handler_t process, | 120 | event__handler_t process, |
118 | struct perf_session *session); | 121 | struct perf_session *session); |
119 | int event__process_tracing_data(event_t *self, | 122 | int event__process_tracing_data(event_t *self, |
diff --git a/tools/perf/util/include/linux/list.h b/tools/perf/util/include/linux/list.h index f5ca26e53fbb..356c7e467b83 100644 --- a/tools/perf/util/include/linux/list.h +++ b/tools/perf/util/include/linux/list.h | |||
@@ -1,3 +1,4 @@ | |||
1 | #include <linux/kernel.h> | ||
1 | #include "../../../../include/linux/list.h" | 2 | #include "../../../../include/linux/list.h" |
2 | 3 | ||
3 | #ifndef PERF_LIST_H | 4 | #ifndef PERF_LIST_H |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 135f69baf966..d3086cecd2dd 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 "evlist.h" | ||
4 | #include "evsel.h" | 5 | #include "evsel.h" |
5 | #include "parse-options.h" | 6 | #include "parse-options.h" |
6 | #include "parse-events.h" | 7 | #include "parse-events.h" |
@@ -11,10 +12,6 @@ | |||
11 | #include "header.h" | 12 | #include "header.h" |
12 | #include "debugfs.h" | 13 | #include "debugfs.h" |
13 | 14 | ||
14 | int nr_counters; | ||
15 | |||
16 | LIST_HEAD(evsel_list); | ||
17 | |||
18 | struct event_symbol { | 15 | struct event_symbol { |
19 | u8 type; | 16 | u8 type; |
20 | u64 config; | 17 | u64 config; |
@@ -778,8 +775,9 @@ modifier: | |||
778 | return ret; | 775 | return ret; |
779 | } | 776 | } |
780 | 777 | ||
781 | int parse_events(const struct option *opt __used, const char *str, int unset __used) | 778 | int parse_events(const struct option *opt, const char *str, int unset __used) |
782 | { | 779 | { |
780 | struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; | ||
783 | struct perf_event_attr attr; | 781 | struct perf_event_attr attr; |
784 | enum event_result ret; | 782 | enum event_result ret; |
785 | 783 | ||
@@ -794,12 +792,10 @@ int parse_events(const struct option *opt __used, const char *str, int unset __u | |||
794 | 792 | ||
795 | if (ret != EVT_HANDLED_ALL) { | 793 | if (ret != EVT_HANDLED_ALL) { |
796 | struct perf_evsel *evsel; | 794 | struct perf_evsel *evsel; |
797 | evsel = perf_evsel__new(&attr, | 795 | evsel = perf_evsel__new(&attr, evlist->nr_entries); |
798 | nr_counters); | ||
799 | if (evsel == NULL) | 796 | if (evsel == NULL) |
800 | return -1; | 797 | return -1; |
801 | list_add_tail(&evsel->node, &evsel_list); | 798 | perf_evlist__add(evlist, evsel); |
802 | ++nr_counters; | ||
803 | } | 799 | } |
804 | 800 | ||
805 | if (*str == 0) | 801 | if (*str == 0) |
@@ -813,13 +809,14 @@ int parse_events(const struct option *opt __used, const char *str, int unset __u | |||
813 | return 0; | 809 | return 0; |
814 | } | 810 | } |
815 | 811 | ||
816 | int parse_filter(const struct option *opt __used, const char *str, | 812 | int parse_filter(const struct option *opt, const char *str, |
817 | int unset __used) | 813 | int unset __used) |
818 | { | 814 | { |
815 | struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; | ||
819 | struct perf_evsel *last = NULL; | 816 | struct perf_evsel *last = NULL; |
820 | 817 | ||
821 | if (!list_empty(&evsel_list)) | 818 | if (evlist->nr_entries > 0) |
822 | last = list_entry(evsel_list.prev, struct perf_evsel, node); | 819 | last = list_entry(evlist->entries.prev, struct perf_evsel, node); |
823 | 820 | ||
824 | if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) { | 821 | if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) { |
825 | fprintf(stderr, | 822 | fprintf(stderr, |
@@ -981,33 +978,3 @@ void print_events(void) | |||
981 | 978 | ||
982 | exit(129); | 979 | exit(129); |
983 | } | 980 | } |
984 | |||
985 | int perf_evsel_list__create_default(void) | ||
986 | { | ||
987 | struct perf_evsel *evsel; | ||
988 | struct perf_event_attr attr; | ||
989 | |||
990 | memset(&attr, 0, sizeof(attr)); | ||
991 | attr.type = PERF_TYPE_HARDWARE; | ||
992 | attr.config = PERF_COUNT_HW_CPU_CYCLES; | ||
993 | |||
994 | evsel = perf_evsel__new(&attr, 0); | ||
995 | |||
996 | if (evsel == NULL) | ||
997 | return -ENOMEM; | ||
998 | |||
999 | list_add(&evsel->node, &evsel_list); | ||
1000 | ++nr_counters; | ||
1001 | return 0; | ||
1002 | } | ||
1003 | |||
1004 | void perf_evsel_list__delete(void) | ||
1005 | { | ||
1006 | struct perf_evsel *pos, *n; | ||
1007 | |||
1008 | list_for_each_entry_safe(pos, n, &evsel_list, node) { | ||
1009 | list_del_init(&pos->node); | ||
1010 | perf_evsel__delete(pos); | ||
1011 | } | ||
1012 | nr_counters = 0; | ||
1013 | } | ||
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 458e3ecf17af..cf7e94abb676 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h | |||
@@ -9,11 +9,6 @@ | |||
9 | struct list_head; | 9 | struct list_head; |
10 | struct perf_evsel; | 10 | struct perf_evsel; |
11 | 11 | ||
12 | extern struct list_head evsel_list; | ||
13 | |||
14 | int perf_evsel_list__create_default(void); | ||
15 | void perf_evsel_list__delete(void); | ||
16 | |||
17 | struct option; | 12 | struct option; |
18 | 13 | ||
19 | struct tracepoint_path { | 14 | struct tracepoint_path { |
@@ -25,8 +20,6 @@ struct tracepoint_path { | |||
25 | extern struct tracepoint_path *tracepoint_id_to_path(u64 config); | 20 | extern struct tracepoint_path *tracepoint_id_to_path(u64 config); |
26 | extern bool have_tracepoints(struct list_head *evlist); | 21 | extern bool have_tracepoints(struct list_head *evlist); |
27 | 22 | ||
28 | extern int nr_counters; | ||
29 | |||
30 | const char *event_name(struct perf_evsel *event); | 23 | const char *event_name(struct perf_evsel *event); |
31 | extern const char *__event_name(int type, u64 config); | 24 | extern const char *__event_name(int type, u64 config); |
32 | 25 | ||