diff options
| author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-10-09 14:29:51 -0400 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-10-14 16:32:03 -0400 |
| commit | ce8ccff5dd6b87dfe3495c7e9c5d56169bbacf58 (patch) | |
| tree | e40b13129e87e5f7a9e0544776f151d4e5084965 | |
| parent | 2a1731fb85ec96a1f6a326fb2d52cd93494dafa2 (diff) | |
perf evsel: Subclassing
Provide a method to be called at tool start to config the perf_evsel
instance size, together with optional constructor and destructor.
This will be used so that perf_evsel doesn't always include a struct
hists, tools that works with hists/hist_entries, like report, top and
annotate, will, at start, tell the evsel class the size they need per
instance.
v2: Don't use exit as a name of a member of function parameter, as this
breaks the build on at least fedora14 and rhel6.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David Ahern <dsahern@gmail.com>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-7t8cay0ieryox4gqosie85ek@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
| -rw-r--r-- | tools/perf/util/evsel.c | 48 | ||||
| -rw-r--r-- | tools/perf/util/evsel.h | 4 |
2 files changed, 50 insertions, 2 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index e0868a901c4a..0580b13df2e6 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
| @@ -32,6 +32,48 @@ static struct { | |||
| 32 | bool cloexec; | 32 | bool cloexec; |
| 33 | } perf_missing_features; | 33 | } perf_missing_features; |
| 34 | 34 | ||
| 35 | static int perf_evsel__no_extra_init(struct perf_evsel *evsel __maybe_unused) | ||
| 36 | { | ||
| 37 | return 0; | ||
| 38 | } | ||
| 39 | |||
| 40 | static void perf_evsel__no_extra_fini(struct perf_evsel *evsel __maybe_unused) | ||
| 41 | { | ||
| 42 | } | ||
| 43 | |||
| 44 | static struct { | ||
| 45 | size_t size; | ||
| 46 | int (*init)(struct perf_evsel *evsel); | ||
| 47 | void (*fini)(struct perf_evsel *evsel); | ||
| 48 | } perf_evsel__object = { | ||
| 49 | .size = sizeof(struct perf_evsel), | ||
| 50 | .init = perf_evsel__no_extra_init, | ||
| 51 | .fini = perf_evsel__no_extra_fini, | ||
| 52 | }; | ||
| 53 | |||
| 54 | int perf_evsel__object_config(size_t object_size, | ||
| 55 | int (*init)(struct perf_evsel *evsel), | ||
| 56 | void (*fini)(struct perf_evsel *evsel)) | ||
| 57 | { | ||
| 58 | |||
| 59 | if (object_size == 0) | ||
| 60 | goto set_methods; | ||
| 61 | |||
| 62 | if (perf_evsel__object.size > object_size) | ||
| 63 | return -EINVAL; | ||
| 64 | |||
| 65 | perf_evsel__object.size = object_size; | ||
| 66 | |||
| 67 | set_methods: | ||
| 68 | if (init != NULL) | ||
| 69 | perf_evsel__object.init = init; | ||
| 70 | |||
| 71 | if (fini != NULL) | ||
| 72 | perf_evsel__object.fini = fini; | ||
| 73 | |||
| 74 | return 0; | ||
| 75 | } | ||
| 76 | |||
| 35 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) | 77 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) |
| 36 | 78 | ||
| 37 | int __perf_evsel__sample_size(u64 sample_type) | 79 | int __perf_evsel__sample_size(u64 sample_type) |
| @@ -169,13 +211,14 @@ void perf_evsel__init(struct perf_evsel *evsel, | |||
| 169 | evsel->scale = 1.0; | 211 | evsel->scale = 1.0; |
| 170 | INIT_LIST_HEAD(&evsel->node); | 212 | INIT_LIST_HEAD(&evsel->node); |
| 171 | hists__init(&evsel->hists); | 213 | hists__init(&evsel->hists); |
| 214 | perf_evsel__object.init(evsel); | ||
| 172 | evsel->sample_size = __perf_evsel__sample_size(attr->sample_type); | 215 | evsel->sample_size = __perf_evsel__sample_size(attr->sample_type); |
| 173 | perf_evsel__calc_id_pos(evsel); | 216 | perf_evsel__calc_id_pos(evsel); |
| 174 | } | 217 | } |
| 175 | 218 | ||
| 176 | struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) | 219 | struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) |
| 177 | { | 220 | { |
| 178 | struct perf_evsel *evsel = zalloc(sizeof(*evsel)); | 221 | struct perf_evsel *evsel = zalloc(perf_evsel__object.size); |
| 179 | 222 | ||
| 180 | if (evsel != NULL) | 223 | if (evsel != NULL) |
| 181 | perf_evsel__init(evsel, attr, idx); | 224 | perf_evsel__init(evsel, attr, idx); |
| @@ -185,7 +228,7 @@ struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) | |||
| 185 | 228 | ||
| 186 | struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx) | 229 | struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx) |
| 187 | { | 230 | { |
| 188 | struct perf_evsel *evsel = zalloc(sizeof(*evsel)); | 231 | struct perf_evsel *evsel = zalloc(perf_evsel__object.size); |
| 189 | 232 | ||
| 190 | if (evsel != NULL) { | 233 | if (evsel != NULL) { |
| 191 | struct perf_event_attr attr = { | 234 | struct perf_event_attr attr = { |
| @@ -817,6 +860,7 @@ void perf_evsel__exit(struct perf_evsel *evsel) | |||
| 817 | assert(list_empty(&evsel->node)); | 860 | assert(list_empty(&evsel->node)); |
| 818 | perf_evsel__free_fd(evsel); | 861 | perf_evsel__free_fd(evsel); |
| 819 | perf_evsel__free_id(evsel); | 862 | perf_evsel__free_id(evsel); |
| 863 | perf_evsel__object.fini(evsel); | ||
| 820 | } | 864 | } |
| 821 | 865 | ||
| 822 | void perf_evsel__delete(struct perf_evsel *evsel) | 866 | void perf_evsel__delete(struct perf_evsel *evsel) |
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index ff72ce058724..d6325106c8fd 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
| @@ -112,6 +112,10 @@ struct thread_map; | |||
| 112 | struct perf_evlist; | 112 | struct perf_evlist; |
| 113 | struct record_opts; | 113 | struct record_opts; |
| 114 | 114 | ||
| 115 | int perf_evsel__object_config(size_t object_size, | ||
| 116 | int (*init)(struct perf_evsel *evsel), | ||
| 117 | void (*fini)(struct perf_evsel *evsel)); | ||
| 118 | |||
| 115 | struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx); | 119 | struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx); |
| 116 | 120 | ||
| 117 | static inline struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr) | 121 | static inline struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr) |
