aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/evsel.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2011-01-03 14:45:52 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2011-01-03 21:22:55 -0500
commitc52b12ed2511e6c031a0295fd903ea72b93701fb (patch)
tree770915627e789401b820a104c1ed23a212e7bd50 /tools/perf/util/evsel.c
parent70d544d0576775a2b3923a7e68cb49b0313d80c9 (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.c88
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
4struct perf_evsel *perf_evsel__new(u32 type, u64 config, int idx) 6struct 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
26int 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
24void perf_evsel__free_fd(struct perf_evsel *evsel) 33void 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
39void 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
30void perf_evsel__delete(struct perf_evsel *evsel) 50void 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
57int __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
81int __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}