aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/cpumap.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/cpumap.c')
-rw-r--r--tools/perf/util/cpumap.c86
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
8static struct cpu_map *cpu_map__default_new(void) 9static 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
234int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp) 235static int cmp_ids(const void *a, const void *b)
235{ 236{
236 struct cpu_map *sock; 237 return *(int *)a - *(int *)b;
238}
239
240static 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
270int 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
311int 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
316int 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}