diff options
Diffstat (limited to 'tools/perf/util/cpumap.c')
| -rw-r--r-- | tools/perf/util/cpumap.c | 40 | 
1 files changed, 28 insertions, 12 deletions
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index f817046e22b..7bb8e87a584 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -4,6 +4,7 @@  #include "cpumap.h"  #include <assert.h>  #include <stdio.h> +#include <stdlib.h>  static struct cpu_map *cpu_map__default_new(void)  { @@ -219,7 +220,7 @@ int cpu_map__get_socket(struct cpu_map *map, int idx)  	if (!mnt)  		return -1; -	sprintf(path, +	snprintf(path, PATH_MAX,  		"%s/devices/system/cpu/cpu%d/topology/physical_package_id",  		mnt, cpu); @@ -231,27 +232,42 @@ int cpu_map__get_socket(struct cpu_map *map, int idx)  	return ret == 1 ? cpu : -1;  } -int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp) +static int cmp_ids(const void *a, const void *b)  { -	struct cpu_map *sock; +	return *(int *)a - *(int *)b; +} + +static int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res, +			      int (*f)(struct cpu_map *map, int cpu)) +{ +	struct cpu_map *c;  	int nr = cpus->nr;  	int cpu, s1, s2; -	sock = calloc(1, sizeof(*sock) + nr * sizeof(int)); -	if (!sock) +	/* allocate as much as possible */ +	c = calloc(1, sizeof(*c) + nr * sizeof(int)); +	if (!c)  		return -1;  	for (cpu = 0; cpu < nr; cpu++) { -		s1 = cpu_map__get_socket(cpus, cpu); -		for (s2 = 0; s2 < sock->nr; s2++) { -			if (s1 == sock->map[s2]) +		s1 = f(cpus, cpu); +		for (s2 = 0; s2 < c->nr; s2++) { +			if (s1 == c->map[s2])  				break;  		} -		if (s2 == sock->nr) { -			sock->map[sock->nr] = s1; -			sock->nr++; +		if (s2 == c->nr) { +			c->map[c->nr] = s1; +			c->nr++;  		}  	} -	*sockp = sock; +	/* ensure we process id in increasing order */ +	qsort(c->map, c->nr, sizeof(int), cmp_ids); + +	*res = c;  	return 0;  } + +int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp) +{ +	return cpu_map__build_map(cpus, sockp, cpu_map__get_socket); +}  |