diff options
Diffstat (limited to 'tools/perf/util/cpumap.c')
-rw-r--r-- | tools/perf/util/cpumap.c | 86 |
1 files changed, 74 insertions, 12 deletions
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index f817046e22b1..beb8cf9f9976 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include "cpumap.h" | 4 | #include "cpumap.h" |
5 | #include <assert.h> | 5 | #include <assert.h> |
6 | #include <stdio.h> | 6 | #include <stdio.h> |
7 | #include <stdlib.h> | ||
7 | 8 | ||
8 | static struct cpu_map *cpu_map__default_new(void) | 9 | static struct cpu_map *cpu_map__default_new(void) |
9 | { | 10 | { |
@@ -219,7 +220,7 @@ int cpu_map__get_socket(struct cpu_map *map, int idx) | |||
219 | if (!mnt) | 220 | if (!mnt) |
220 | return -1; | 221 | return -1; |
221 | 222 | ||
222 | sprintf(path, | 223 | snprintf(path, PATH_MAX, |
223 | "%s/devices/system/cpu/cpu%d/topology/physical_package_id", | 224 | "%s/devices/system/cpu/cpu%d/topology/physical_package_id", |
224 | mnt, cpu); | 225 | mnt, cpu); |
225 | 226 | ||
@@ -231,27 +232,88 @@ int cpu_map__get_socket(struct cpu_map *map, int idx) | |||
231 | return ret == 1 ? cpu : -1; | 232 | return ret == 1 ? cpu : -1; |
232 | } | 233 | } |
233 | 234 | ||
234 | int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp) | 235 | static int cmp_ids(const void *a, const void *b) |
235 | { | 236 | { |
236 | struct cpu_map *sock; | 237 | return *(int *)a - *(int *)b; |
238 | } | ||
239 | |||
240 | static int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res, | ||
241 | int (*f)(struct cpu_map *map, int cpu)) | ||
242 | { | ||
243 | struct cpu_map *c; | ||
237 | int nr = cpus->nr; | 244 | int nr = cpus->nr; |
238 | int cpu, s1, s2; | 245 | int cpu, s1, s2; |
239 | 246 | ||
240 | sock = calloc(1, sizeof(*sock) + nr * sizeof(int)); | 247 | /* allocate as much as possible */ |
241 | if (!sock) | 248 | c = calloc(1, sizeof(*c) + nr * sizeof(int)); |
249 | if (!c) | ||
242 | return -1; | 250 | return -1; |
243 | 251 | ||
244 | for (cpu = 0; cpu < nr; cpu++) { | 252 | for (cpu = 0; cpu < nr; cpu++) { |
245 | s1 = cpu_map__get_socket(cpus, cpu); | 253 | s1 = f(cpus, cpu); |
246 | for (s2 = 0; s2 < sock->nr; s2++) { | 254 | for (s2 = 0; s2 < c->nr; s2++) { |
247 | if (s1 == sock->map[s2]) | 255 | if (s1 == c->map[s2]) |
248 | break; | 256 | break; |
249 | } | 257 | } |
250 | if (s2 == sock->nr) { | 258 | if (s2 == c->nr) { |
251 | sock->map[sock->nr] = s1; | 259 | c->map[c->nr] = s1; |
252 | sock->nr++; | 260 | c->nr++; |
253 | } | 261 | } |
254 | } | 262 | } |
255 | *sockp = sock; | 263 | /* ensure we process id in increasing order */ |
264 | qsort(c->map, c->nr, sizeof(int), cmp_ids); | ||
265 | |||
266 | *res = c; | ||
256 | return 0; | 267 | return 0; |
257 | } | 268 | } |
269 | |||
270 | int cpu_map__get_core(struct cpu_map *map, int idx) | ||
271 | { | ||
272 | FILE *fp; | ||
273 | const char *mnt; | ||
274 | char path[PATH_MAX]; | ||
275 | int cpu, ret, s; | ||
276 | |||
277 | if (idx > map->nr) | ||
278 | return -1; | ||
279 | |||
280 | cpu = map->map[idx]; | ||
281 | |||
282 | mnt = sysfs_find_mountpoint(); | ||
283 | if (!mnt) | ||
284 | return -1; | ||
285 | |||
286 | snprintf(path, PATH_MAX, | ||
287 | "%s/devices/system/cpu/cpu%d/topology/core_id", | ||
288 | mnt, cpu); | ||
289 | |||
290 | fp = fopen(path, "r"); | ||
291 | if (!fp) | ||
292 | return -1; | ||
293 | ret = fscanf(fp, "%d", &cpu); | ||
294 | fclose(fp); | ||
295 | if (ret != 1) | ||
296 | return -1; | ||
297 | |||
298 | s = cpu_map__get_socket(map, idx); | ||
299 | if (s == -1) | ||
300 | return -1; | ||
301 | |||
302 | /* | ||
303 | * encode socket in upper 16 bits | ||
304 | * core_id is relative to socket, and | ||
305 | * we need a global id. So we combine | ||
306 | * socket+ core id | ||
307 | */ | ||
308 | return (s << 16) | (cpu & 0xffff); | ||
309 | } | ||
310 | |||
311 | int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp) | ||
312 | { | ||
313 | return cpu_map__build_map(cpus, sockp, cpu_map__get_socket); | ||
314 | } | ||
315 | |||
316 | int cpu_map__build_core_map(struct cpu_map *cpus, struct cpu_map **corep) | ||
317 | { | ||
318 | return cpu_map__build_map(cpus, corep, cpu_map__get_core); | ||
319 | } | ||