diff options
Diffstat (limited to 'tools/perf/util/evsel.c')
-rw-r--r-- | tools/perf/util/evsel.c | 82 |
1 files changed, 49 insertions, 33 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 1a5591d7a245..f5cfed60af98 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -127,59 +127,75 @@ int __perf_evsel__read(struct perf_evsel *evsel, | |||
127 | return 0; | 127 | return 0; |
128 | } | 128 | } |
129 | 129 | ||
130 | int perf_evsel__open_per_cpu(struct perf_evsel *evsel, struct cpu_map *cpus) | 130 | static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, |
131 | struct thread_map *threads) | ||
131 | { | 132 | { |
132 | int cpu; | 133 | int cpu, thread; |
133 | 134 | ||
134 | if (evsel->fd == NULL && perf_evsel__alloc_fd(evsel, cpus->nr, 1) < 0) | 135 | if (evsel->fd == NULL && |
136 | perf_evsel__alloc_fd(evsel, cpus->nr, threads->nr) < 0) | ||
135 | return -1; | 137 | return -1; |
136 | 138 | ||
137 | for (cpu = 0; cpu < cpus->nr; cpu++) { | 139 | for (cpu = 0; cpu < cpus->nr; cpu++) { |
138 | FD(evsel, cpu, 0) = sys_perf_event_open(&evsel->attr, -1, | 140 | for (thread = 0; thread < threads->nr; thread++) { |
139 | cpus->map[cpu], -1, 0); | 141 | FD(evsel, cpu, thread) = sys_perf_event_open(&evsel->attr, |
140 | if (FD(evsel, cpu, 0) < 0) | 142 | threads->map[thread], |
141 | goto out_close; | 143 | cpus->map[cpu], -1, 0); |
144 | if (FD(evsel, cpu, thread) < 0) | ||
145 | goto out_close; | ||
146 | } | ||
142 | } | 147 | } |
143 | 148 | ||
144 | return 0; | 149 | return 0; |
145 | 150 | ||
146 | out_close: | 151 | out_close: |
147 | while (--cpu >= 0) { | 152 | do { |
148 | close(FD(evsel, cpu, 0)); | 153 | while (--thread >= 0) { |
149 | FD(evsel, cpu, 0) = -1; | 154 | close(FD(evsel, cpu, thread)); |
150 | } | 155 | FD(evsel, cpu, thread) = -1; |
156 | } | ||
157 | thread = threads->nr; | ||
158 | } while (--cpu >= 0); | ||
151 | return -1; | 159 | return -1; |
152 | } | 160 | } |
153 | 161 | ||
154 | int perf_evsel__open_per_thread(struct perf_evsel *evsel, struct thread_map *threads) | 162 | static struct { |
163 | struct cpu_map map; | ||
164 | int cpus[1]; | ||
165 | } empty_cpu_map = { | ||
166 | .map.nr = 1, | ||
167 | .cpus = { -1, }, | ||
168 | }; | ||
169 | |||
170 | static struct { | ||
171 | struct thread_map map; | ||
172 | int threads[1]; | ||
173 | } empty_thread_map = { | ||
174 | .map.nr = 1, | ||
175 | .threads = { -1, }, | ||
176 | }; | ||
177 | |||
178 | int perf_evsel__open(struct perf_evsel *evsel, | ||
179 | struct cpu_map *cpus, struct thread_map *threads) | ||
155 | { | 180 | { |
156 | int thread; | ||
157 | |||
158 | if (evsel->fd == NULL && perf_evsel__alloc_fd(evsel, 1, threads->nr)) | ||
159 | return -1; | ||
160 | 181 | ||
161 | for (thread = 0; thread < threads->nr; thread++) { | 182 | if (cpus == NULL) { |
162 | FD(evsel, 0, thread) = sys_perf_event_open(&evsel->attr, | 183 | /* Work around old compiler warnings about strict aliasing */ |
163 | threads->map[thread], -1, -1, 0); | 184 | cpus = &empty_cpu_map.map; |
164 | if (FD(evsel, 0, thread) < 0) | ||
165 | goto out_close; | ||
166 | } | 185 | } |
167 | 186 | ||
168 | return 0; | 187 | if (threads == NULL) |
188 | threads = &empty_thread_map.map; | ||
169 | 189 | ||
170 | out_close: | 190 | return __perf_evsel__open(evsel, cpus, threads); |
171 | while (--thread >= 0) { | ||
172 | close(FD(evsel, 0, thread)); | ||
173 | FD(evsel, 0, thread) = -1; | ||
174 | } | ||
175 | return -1; | ||
176 | } | 191 | } |
177 | 192 | ||
178 | int perf_evsel__open(struct perf_evsel *evsel, | 193 | int perf_evsel__open_per_cpu(struct perf_evsel *evsel, struct cpu_map *cpus) |
179 | struct cpu_map *cpus, struct thread_map *threads) | ||
180 | { | 194 | { |
181 | if (threads == NULL) | 195 | return __perf_evsel__open(evsel, cpus, &empty_thread_map.map); |
182 | return perf_evsel__open_per_cpu(evsel, cpus); | 196 | } |
183 | 197 | ||
184 | return perf_evsel__open_per_thread(evsel, threads); | 198 | int perf_evsel__open_per_thread(struct perf_evsel *evsel, struct thread_map *threads) |
199 | { | ||
200 | return __perf_evsel__open(evsel, &empty_cpu_map.map, threads); | ||
185 | } | 201 | } |