diff options
Diffstat (limited to 'tools/perf/util/cpumap.c')
-rw-r--r-- | tools/perf/util/cpumap.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index 10af1e752..fa935093a 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -5,6 +5,7 @@ #include <assert.h> #include <stdio.h> #include <stdlib.h> +#include <linux/bitmap.h> #include "asm/bug.h" static struct cpu_map *cpu_map__default_new(void) @@ -179,6 +180,56 @@ out: return cpus; } +static struct cpu_map *cpu_map__from_entries(struct cpu_map_entries *cpus) +{ + struct cpu_map *map; + + map = cpu_map__empty_new(cpus->nr); + if (map) { + unsigned i; + + for (i = 0; i < cpus->nr; i++) { + /* + * Special treatment for -1, which is not real cpu number, + * and we need to use (int) -1 to initialize map[i], + * otherwise it would become 65535. + */ + if (cpus->cpu[i] == (u16) -1) + map->map[i] = -1; + else + map->map[i] = (int) cpus->cpu[i]; + } + } + + return map; +} + +static struct cpu_map *cpu_map__from_mask(struct cpu_map_mask *mask) +{ + struct cpu_map *map; + int nr, nbits = mask->nr * mask->long_size * BITS_PER_BYTE; + + nr = bitmap_weight(mask->mask, nbits); + + map = cpu_map__empty_new(nr); + if (map) { + int cpu, i = 0; + + for_each_set_bit(cpu, mask->mask, nbits) + map->map[i++] = cpu; + } + return map; + +} + +struct cpu_map *cpu_map__new_data(struct cpu_map_data *data) +{ + if (data->type == PERF_CPU_MAP__CPUS) + return cpu_map__from_entries((struct cpu_map_entries *)data->data); + else + return cpu_map__from_mask((struct cpu_map_mask *)data->data); +} + size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp) { int i; |