ARM: tegra: trimslice: add gpio-poweroff node to DT
[linux-2.6/btrfs-unstable.git] / tools / perf / util / cpumap.c
blob2b32ffa9ebdb188e8edeb31fc4176380d99b2337
1 #include "util.h"
2 #include "../perf.h"
3 #include "cpumap.h"
4 #include <assert.h>
5 #include <stdio.h>
7 static struct cpu_map *cpu_map__default_new(void)
9 struct cpu_map *cpus;
10 int nr_cpus;
12 nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
13 if (nr_cpus < 0)
14 return NULL;
16 cpus = malloc(sizeof(*cpus) + nr_cpus * sizeof(int));
17 if (cpus != NULL) {
18 int i;
19 for (i = 0; i < nr_cpus; ++i)
20 cpus->map[i] = i;
22 cpus->nr = nr_cpus;
25 return cpus;
28 static struct cpu_map *cpu_map__trim_new(int nr_cpus, int *tmp_cpus)
30 size_t payload_size = nr_cpus * sizeof(int);
31 struct cpu_map *cpus = malloc(sizeof(*cpus) + payload_size);
33 if (cpus != NULL) {
34 cpus->nr = nr_cpus;
35 memcpy(cpus->map, tmp_cpus, payload_size);
38 return cpus;
41 struct cpu_map *cpu_map__read(FILE *file)
43 struct cpu_map *cpus = NULL;
44 int nr_cpus = 0;
45 int *tmp_cpus = NULL, *tmp;
46 int max_entries = 0;
47 int n, cpu, prev;
48 char sep;
50 sep = 0;
51 prev = -1;
52 for (;;) {
53 n = fscanf(file, "%u%c", &cpu, &sep);
54 if (n <= 0)
55 break;
56 if (prev >= 0) {
57 int new_max = nr_cpus + cpu - prev - 1;
59 if (new_max >= max_entries) {
60 max_entries = new_max + MAX_NR_CPUS / 2;
61 tmp = realloc(tmp_cpus, max_entries * sizeof(int));
62 if (tmp == NULL)
63 goto out_free_tmp;
64 tmp_cpus = tmp;
67 while (++prev < cpu)
68 tmp_cpus[nr_cpus++] = prev;
70 if (nr_cpus == max_entries) {
71 max_entries += MAX_NR_CPUS;
72 tmp = realloc(tmp_cpus, max_entries * sizeof(int));
73 if (tmp == NULL)
74 goto out_free_tmp;
75 tmp_cpus = tmp;
78 tmp_cpus[nr_cpus++] = cpu;
79 if (n == 2 && sep == '-')
80 prev = cpu;
81 else
82 prev = -1;
83 if (n == 1 || sep == '\n')
84 break;
87 if (nr_cpus > 0)
88 cpus = cpu_map__trim_new(nr_cpus, tmp_cpus);
89 else
90 cpus = cpu_map__default_new();
91 out_free_tmp:
92 free(tmp_cpus);
93 return cpus;
96 static struct cpu_map *cpu_map__read_all_cpu_map(void)
98 struct cpu_map *cpus = NULL;
99 FILE *onlnf;
101 onlnf = fopen("/sys/devices/system/cpu/online", "r");
102 if (!onlnf)
103 return cpu_map__default_new();
105 cpus = cpu_map__read(onlnf);
106 fclose(onlnf);
107 return cpus;
110 struct cpu_map *cpu_map__new(const char *cpu_list)
112 struct cpu_map *cpus = NULL;
113 unsigned long start_cpu, end_cpu = 0;
114 char *p = NULL;
115 int i, nr_cpus = 0;
116 int *tmp_cpus = NULL, *tmp;
117 int max_entries = 0;
119 if (!cpu_list)
120 return cpu_map__read_all_cpu_map();
122 if (!isdigit(*cpu_list))
123 goto out;
125 while (isdigit(*cpu_list)) {
126 p = NULL;
127 start_cpu = strtoul(cpu_list, &p, 0);
128 if (start_cpu >= INT_MAX
129 || (*p != '\0' && *p != ',' && *p != '-'))
130 goto invalid;
132 if (*p == '-') {
133 cpu_list = ++p;
134 p = NULL;
135 end_cpu = strtoul(cpu_list, &p, 0);
137 if (end_cpu >= INT_MAX || (*p != '\0' && *p != ','))
138 goto invalid;
140 if (end_cpu < start_cpu)
141 goto invalid;
142 } else {
143 end_cpu = start_cpu;
146 for (; start_cpu <= end_cpu; start_cpu++) {
147 /* check for duplicates */
148 for (i = 0; i < nr_cpus; i++)
149 if (tmp_cpus[i] == (int)start_cpu)
150 goto invalid;
152 if (nr_cpus == max_entries) {
153 max_entries += MAX_NR_CPUS;
154 tmp = realloc(tmp_cpus, max_entries * sizeof(int));
155 if (tmp == NULL)
156 goto invalid;
157 tmp_cpus = tmp;
159 tmp_cpus[nr_cpus++] = (int)start_cpu;
161 if (*p)
162 ++p;
164 cpu_list = p;
167 if (nr_cpus > 0)
168 cpus = cpu_map__trim_new(nr_cpus, tmp_cpus);
169 else
170 cpus = cpu_map__default_new();
171 invalid:
172 free(tmp_cpus);
173 out:
174 return cpus;
177 size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp)
179 int i;
180 size_t printed = fprintf(fp, "%d cpu%s: ",
181 map->nr, map->nr > 1 ? "s" : "");
182 for (i = 0; i < map->nr; ++i)
183 printed += fprintf(fp, "%s%d", i ? ", " : "", map->map[i]);
185 return printed + fprintf(fp, "\n");
188 struct cpu_map *cpu_map__dummy_new(void)
190 struct cpu_map *cpus = malloc(sizeof(*cpus) + sizeof(int));
192 if (cpus != NULL) {
193 cpus->nr = 1;
194 cpus->map[0] = -1;
197 return cpus;
200 void cpu_map__delete(struct cpu_map *map)
202 free(map);