diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-01-03 14:45:52 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-01-03 21:22:55 -0500 |
commit | c52b12ed2511e6c031a0295fd903ea72b93701fb (patch) | |
tree | 770915627e789401b820a104c1ed23a212e7bd50 /tools/perf/util/evsel.c | |
parent | 70d544d0576775a2b3923a7e68cb49b0313d80c9 (diff) |
perf evsel: Steal the counter reading routines from stat
Making them hopefully generic enough to be used in 'perf test',
well see.
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/evsel.c')
-rw-r--r-- | tools/perf/util/evsel.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 6539ec912c70..3f5de5196231 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -1,6 +1,8 @@ | |||
1 | #include "evsel.h" | 1 | #include "evsel.h" |
2 | #include "util.h" | 2 | #include "util.h" |
3 | 3 | ||
4 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) | ||
5 | |||
4 | struct perf_evsel *perf_evsel__new(u32 type, u64 config, int idx) | 6 | struct perf_evsel *perf_evsel__new(u32 type, u64 config, int idx) |
5 | { | 7 | { |
6 | struct perf_evsel *evsel = zalloc(sizeof(*evsel)); | 8 | struct perf_evsel *evsel = zalloc(sizeof(*evsel)); |
@@ -21,15 +23,101 @@ int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) | |||
21 | return evsel->fd != NULL ? 0 : -ENOMEM; | 23 | return evsel->fd != NULL ? 0 : -ENOMEM; |
22 | } | 24 | } |
23 | 25 | ||
26 | int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus) | ||
27 | { | ||
28 | evsel->counts = zalloc((sizeof(*evsel->counts) + | ||
29 | (ncpus * sizeof(struct perf_counts_values)))); | ||
30 | return evsel->counts != NULL ? 0 : -ENOMEM; | ||
31 | } | ||
32 | |||
24 | void perf_evsel__free_fd(struct perf_evsel *evsel) | 33 | void perf_evsel__free_fd(struct perf_evsel *evsel) |
25 | { | 34 | { |
26 | xyarray__delete(evsel->fd); | 35 | xyarray__delete(evsel->fd); |
27 | evsel->fd = NULL; | 36 | evsel->fd = NULL; |
28 | } | 37 | } |
29 | 38 | ||
39 | void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads) | ||
40 | { | ||
41 | int cpu, thread; | ||
42 | |||
43 | for (cpu = 0; cpu < ncpus; cpu++) | ||
44 | for (thread = 0; thread < nthreads; ++thread) { | ||
45 | close(FD(evsel, cpu, thread)); | ||
46 | FD(evsel, cpu, thread) = -1; | ||
47 | } | ||
48 | } | ||
49 | |||
30 | void perf_evsel__delete(struct perf_evsel *evsel) | 50 | void perf_evsel__delete(struct perf_evsel *evsel) |
31 | { | 51 | { |
32 | assert(list_empty(&evsel->node)); | 52 | assert(list_empty(&evsel->node)); |
33 | xyarray__delete(evsel->fd); | 53 | xyarray__delete(evsel->fd); |
34 | free(evsel); | 54 | free(evsel); |
35 | } | 55 | } |
56 | |||
57 | int __perf_evsel__read_on_cpu(struct perf_evsel *evsel, | ||
58 | int cpu, int thread, bool scale) | ||
59 | { | ||
60 | struct perf_counts_values count; | ||
61 | size_t nv = scale ? 3 : 1; | ||
62 | |||
63 | if (FD(evsel, cpu, thread) < 0) | ||
64 | return -EINVAL; | ||
65 | |||
66 | if (readn(FD(evsel, cpu, thread), &count, nv * sizeof(u64)) < 0) | ||
67 | return -errno; | ||
68 | |||
69 | if (scale) { | ||
70 | if (count.run == 0) | ||
71 | count.val = 0; | ||
72 | else if (count.run < count.ena) | ||
73 | count.val = (u64)((double)count.val * count.ena / count.run + 0.5); | ||
74 | } else | ||
75 | count.ena = count.run = 0; | ||
76 | |||
77 | evsel->counts->cpu[cpu] = count; | ||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | int __perf_evsel__read(struct perf_evsel *evsel, | ||
82 | int ncpus, int nthreads, bool scale) | ||
83 | { | ||
84 | size_t nv = scale ? 3 : 1; | ||
85 | int cpu, thread; | ||
86 | struct perf_counts_values *aggr = &evsel->counts->aggr, count; | ||
87 | |||
88 | aggr->val = 0; | ||
89 | |||
90 | for (cpu = 0; cpu < ncpus; cpu++) { | ||
91 | for (thread = 0; thread < nthreads; thread++) { | ||
92 | if (FD(evsel, cpu, thread) < 0) | ||
93 | continue; | ||
94 | |||
95 | if (readn(FD(evsel, cpu, thread), | ||
96 | &count, nv * sizeof(u64)) < 0) | ||
97 | return -errno; | ||
98 | |||
99 | aggr->val += count.val; | ||
100 | if (scale) { | ||
101 | aggr->ena += count.ena; | ||
102 | aggr->run += count.run; | ||
103 | } | ||
104 | } | ||
105 | } | ||
106 | |||
107 | evsel->counts->scaled = 0; | ||
108 | if (scale) { | ||
109 | if (aggr->run == 0) { | ||
110 | evsel->counts->scaled = -1; | ||
111 | aggr->val = 0; | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | if (aggr->run < aggr->ena) { | ||
116 | evsel->counts->scaled = 1; | ||
117 | aggr->val = (u64)((double)aggr->val * aggr->ena / aggr->run + 0.5); | ||
118 | } | ||
119 | } else | ||
120 | aggr->ena = aggr->run = 0; | ||
121 | |||
122 | return 0; | ||
123 | } | ||