diff options
-rw-r--r-- | tools/perf/builtin-record.c | 14 | ||||
-rw-r--r-- | tools/perf/builtin-stat.c | 36 | ||||
-rw-r--r-- | tools/perf/builtin-top.c | 22 | ||||
-rw-r--r-- | tools/perf/util/cpumap.c | 123 | ||||
-rw-r--r-- | tools/perf/util/cpumap.h | 10 |
5 files changed, 138 insertions, 67 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 052de1780f76..220e6e7f0b97 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -39,7 +39,7 @@ static u64 user_interval = ULLONG_MAX; | |||
39 | static u64 default_interval = 0; | 39 | static u64 default_interval = 0; |
40 | static u64 sample_type; | 40 | static u64 sample_type; |
41 | 41 | ||
42 | static int nr_cpus = 0; | 42 | static struct cpu_map *cpus; |
43 | static unsigned int page_size; | 43 | static unsigned int page_size; |
44 | static unsigned int mmap_pages = 128; | 44 | static unsigned int mmap_pages = 128; |
45 | static unsigned int user_freq = UINT_MAX; | 45 | static unsigned int user_freq = UINT_MAX; |
@@ -670,8 +670,8 @@ static int __cmd_record(int argc, const char **argv) | |||
670 | if (!system_wide && no_inherit && !cpu_list) { | 670 | if (!system_wide && no_inherit && !cpu_list) { |
671 | open_counters(-1); | 671 | open_counters(-1); |
672 | } else { | 672 | } else { |
673 | for (i = 0; i < nr_cpus; i++) | 673 | for (i = 0; i < cpus->nr; i++) |
674 | open_counters(cpumap[i]); | 674 | open_counters(cpus->map[i]); |
675 | } | 675 | } |
676 | 676 | ||
677 | perf_session__set_sample_type(session, sample_type); | 677 | perf_session__set_sample_type(session, sample_type); |
@@ -927,14 +927,14 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
927 | thread_num = 1; | 927 | thread_num = 1; |
928 | } | 928 | } |
929 | 929 | ||
930 | nr_cpus = read_cpu_map(cpu_list); | 930 | cpus = cpu_map__new(cpu_list); |
931 | if (nr_cpus < 1) { | 931 | if (cpus == NULL) { |
932 | perror("failed to collect number of CPUs"); | 932 | perror("failed to parse CPUs map"); |
933 | return -1; | 933 | return -1; |
934 | } | 934 | } |
935 | 935 | ||
936 | list_for_each_entry(pos, &evsel_list, node) { | 936 | list_for_each_entry(pos, &evsel_list, node) { |
937 | if (perf_evsel__alloc_fd(pos, nr_cpus, thread_num) < 0) | 937 | if (perf_evsel__alloc_fd(pos, cpus->nr, thread_num) < 0) |
938 | goto out_free_fd; | 938 | goto out_free_fd; |
939 | } | 939 | } |
940 | event_array = malloc( | 940 | event_array = malloc( |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 065e79eb2142..3f4a431fb5a4 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -72,7 +72,7 @@ static struct perf_event_attr default_attrs[] = { | |||
72 | }; | 72 | }; |
73 | 73 | ||
74 | static bool system_wide = false; | 74 | static bool system_wide = false; |
75 | static int nr_cpus = 0; | 75 | static struct cpu_map *cpus; |
76 | static int run_idx = 0; | 76 | static int run_idx = 0; |
77 | 77 | ||
78 | static int run_count = 1; | 78 | static int run_count = 1; |
@@ -167,7 +167,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel) | |||
167 | PERF_FORMAT_TOTAL_TIME_RUNNING; | 167 | PERF_FORMAT_TOTAL_TIME_RUNNING; |
168 | 168 | ||
169 | if (system_wide) | 169 | if (system_wide) |
170 | return perf_evsel__open_per_cpu(evsel, nr_cpus, cpumap); | 170 | return perf_evsel__open_per_cpu(evsel, cpus->nr, cpus->map); |
171 | 171 | ||
172 | attr->inherit = !no_inherit; | 172 | attr->inherit = !no_inherit; |
173 | if (target_pid == -1 && target_tid == -1) { | 173 | if (target_pid == -1 && target_tid == -1) { |
@@ -200,7 +200,7 @@ static int read_counter_aggr(struct perf_evsel *counter) | |||
200 | u64 *count = counter->counts->aggr.values; | 200 | u64 *count = counter->counts->aggr.values; |
201 | int i; | 201 | int i; |
202 | 202 | ||
203 | if (__perf_evsel__read(counter, nr_cpus, thread_num, scale) < 0) | 203 | if (__perf_evsel__read(counter, cpus->nr, thread_num, scale) < 0) |
204 | return -1; | 204 | return -1; |
205 | 205 | ||
206 | for (i = 0; i < 3; i++) | 206 | for (i = 0; i < 3; i++) |
@@ -233,7 +233,7 @@ static int read_counter(struct perf_evsel *counter) | |||
233 | u64 *count; | 233 | u64 *count; |
234 | int cpu; | 234 | int cpu; |
235 | 235 | ||
236 | for (cpu = 0; cpu < nr_cpus; cpu++) { | 236 | for (cpu = 0; cpu < cpus->nr; cpu++) { |
237 | if (__perf_evsel__read_on_cpu(counter, cpu, 0, scale) < 0) | 237 | if (__perf_evsel__read_on_cpu(counter, cpu, 0, scale) < 0) |
238 | return -1; | 238 | return -1; |
239 | 239 | ||
@@ -259,9 +259,6 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
259 | const bool forks = (argc > 0); | 259 | const bool forks = (argc > 0); |
260 | char buf; | 260 | char buf; |
261 | 261 | ||
262 | if (!system_wide) | ||
263 | nr_cpus = 1; | ||
264 | |||
265 | if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) { | 262 | if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) { |
266 | perror("failed to create pipes"); | 263 | perror("failed to create pipes"); |
267 | exit(1); | 264 | exit(1); |
@@ -351,12 +348,12 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
351 | if (no_aggr) { | 348 | if (no_aggr) { |
352 | list_for_each_entry(counter, &evsel_list, node) { | 349 | list_for_each_entry(counter, &evsel_list, node) { |
353 | read_counter(counter); | 350 | read_counter(counter); |
354 | perf_evsel__close_fd(counter, nr_cpus, 1); | 351 | perf_evsel__close_fd(counter, cpus->nr, 1); |
355 | } | 352 | } |
356 | } else { | 353 | } else { |
357 | list_for_each_entry(counter, &evsel_list, node) { | 354 | list_for_each_entry(counter, &evsel_list, node) { |
358 | read_counter_aggr(counter); | 355 | read_counter_aggr(counter); |
359 | perf_evsel__close_fd(counter, nr_cpus, thread_num); | 356 | perf_evsel__close_fd(counter, cpus->nr, thread_num); |
360 | } | 357 | } |
361 | } | 358 | } |
362 | 359 | ||
@@ -384,7 +381,7 @@ static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg) | |||
384 | if (no_aggr) | 381 | if (no_aggr) |
385 | sprintf(cpustr, "CPU%*d%s", | 382 | sprintf(cpustr, "CPU%*d%s", |
386 | csv_output ? 0 : -4, | 383 | csv_output ? 0 : -4, |
387 | cpumap[cpu], csv_sep); | 384 | cpus->map[cpu], csv_sep); |
388 | 385 | ||
389 | fprintf(stderr, fmt, cpustr, msecs, csv_sep, event_name(evsel)); | 386 | fprintf(stderr, fmt, cpustr, msecs, csv_sep, event_name(evsel)); |
390 | 387 | ||
@@ -412,7 +409,7 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg) | |||
412 | if (no_aggr) | 409 | if (no_aggr) |
413 | sprintf(cpustr, "CPU%*d%s", | 410 | sprintf(cpustr, "CPU%*d%s", |
414 | csv_output ? 0 : -4, | 411 | csv_output ? 0 : -4, |
415 | cpumap[cpu], csv_sep); | 412 | cpus->map[cpu], csv_sep); |
416 | else | 413 | else |
417 | cpu = 0; | 414 | cpu = 0; |
418 | 415 | ||
@@ -498,14 +495,14 @@ static void print_counter(struct perf_evsel *counter) | |||
498 | u64 ena, run, val; | 495 | u64 ena, run, val; |
499 | int cpu; | 496 | int cpu; |
500 | 497 | ||
501 | for (cpu = 0; cpu < nr_cpus; cpu++) { | 498 | for (cpu = 0; cpu < cpus->nr; cpu++) { |
502 | val = counter->counts->cpu[cpu].val; | 499 | val = counter->counts->cpu[cpu].val; |
503 | ena = counter->counts->cpu[cpu].ena; | 500 | ena = counter->counts->cpu[cpu].ena; |
504 | run = counter->counts->cpu[cpu].run; | 501 | run = counter->counts->cpu[cpu].run; |
505 | if (run == 0 || ena == 0) { | 502 | if (run == 0 || ena == 0) { |
506 | fprintf(stderr, "CPU%*d%s%*s%s%-24s", | 503 | fprintf(stderr, "CPU%*d%s%*s%s%-24s", |
507 | csv_output ? 0 : -4, | 504 | csv_output ? 0 : -4, |
508 | cpumap[cpu], csv_sep, | 505 | cpus->map[cpu], csv_sep, |
509 | csv_output ? 0 : 18, | 506 | csv_output ? 0 : 18, |
510 | "<not counted>", csv_sep, | 507 | "<not counted>", csv_sep, |
511 | event_name(counter)); | 508 | event_name(counter)); |
@@ -697,12 +694,15 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
697 | } | 694 | } |
698 | 695 | ||
699 | if (system_wide) | 696 | if (system_wide) |
700 | nr_cpus = read_cpu_map(cpu_list); | 697 | cpus = cpu_map__new(cpu_list); |
701 | else | 698 | else |
702 | nr_cpus = 1; | 699 | cpus = cpu_map__dummy_new(); |
703 | 700 | ||
704 | if (nr_cpus < 1) | 701 | if (cpus == NULL) { |
702 | perror("failed to parse CPUs map"); | ||
705 | usage_with_options(stat_usage, options); | 703 | usage_with_options(stat_usage, options); |
704 | return -1; | ||
705 | } | ||
706 | 706 | ||
707 | if (target_pid != -1) { | 707 | if (target_pid != -1) { |
708 | target_tid = target_pid; | 708 | target_tid = target_pid; |
@@ -723,8 +723,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
723 | 723 | ||
724 | list_for_each_entry(pos, &evsel_list, node) { | 724 | list_for_each_entry(pos, &evsel_list, node) { |
725 | if (perf_evsel__alloc_stat_priv(pos) < 0 || | 725 | if (perf_evsel__alloc_stat_priv(pos) < 0 || |
726 | perf_evsel__alloc_counts(pos, nr_cpus) < 0 || | 726 | perf_evsel__alloc_counts(pos, cpus->nr) < 0 || |
727 | perf_evsel__alloc_fd(pos, nr_cpus, thread_num) < 0) | 727 | perf_evsel__alloc_fd(pos, cpus->nr, thread_num) < 0) |
728 | goto out_free_fd; | 728 | goto out_free_fd; |
729 | } | 729 | } |
730 | 730 | ||
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 27b9c14a0a07..0e426665716d 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -71,7 +71,7 @@ static int target_tid = -1; | |||
71 | static pid_t *all_tids = NULL; | 71 | static pid_t *all_tids = NULL; |
72 | static int thread_num = 0; | 72 | static int thread_num = 0; |
73 | static bool inherit = false; | 73 | static bool inherit = false; |
74 | static int nr_cpus = 0; | 74 | static struct cpu_map *cpus; |
75 | static int realtime_prio = 0; | 75 | static int realtime_prio = 0; |
76 | static bool group = false; | 76 | static bool group = false; |
77 | static unsigned int page_size; | 77 | static unsigned int page_size; |
@@ -564,12 +564,12 @@ static void print_sym_table(void) | |||
564 | printf(" (all"); | 564 | printf(" (all"); |
565 | 565 | ||
566 | if (cpu_list) | 566 | if (cpu_list) |
567 | printf(", CPU%s: %s)\n", nr_cpus > 1 ? "s" : "", cpu_list); | 567 | printf(", CPU%s: %s)\n", cpus->nr > 1 ? "s" : "", cpu_list); |
568 | else { | 568 | else { |
569 | if (target_tid != -1) | 569 | if (target_tid != -1) |
570 | printf(")\n"); | 570 | printf(")\n"); |
571 | else | 571 | else |
572 | printf(", %d CPU%s)\n", nr_cpus, nr_cpus > 1 ? "s" : ""); | 572 | printf(", %d CPU%s)\n", cpus->nr, cpus->nr > 1 ? "s" : ""); |
573 | } | 573 | } |
574 | 574 | ||
575 | printf("%-*.*s\n", win_width, win_width, graph_dotted_line); | 575 | printf("%-*.*s\n", win_width, win_width, graph_dotted_line); |
@@ -1197,7 +1197,7 @@ static void perf_session__mmap_read(struct perf_session *self) | |||
1197 | struct perf_evsel *counter; | 1197 | struct perf_evsel *counter; |
1198 | int i, thread_index; | 1198 | int i, thread_index; |
1199 | 1199 | ||
1200 | for (i = 0; i < nr_cpus; i++) { | 1200 | for (i = 0; i < cpus->nr; i++) { |
1201 | list_for_each_entry(counter, &evsel_list, node) { | 1201 | list_for_each_entry(counter, &evsel_list, node) { |
1202 | for (thread_index = 0; | 1202 | for (thread_index = 0; |
1203 | thread_index < thread_num; | 1203 | thread_index < thread_num; |
@@ -1221,7 +1221,7 @@ static void start_counter(int i, struct perf_evsel *evsel) | |||
1221 | int thread_index; | 1221 | int thread_index; |
1222 | 1222 | ||
1223 | if (target_tid == -1) | 1223 | if (target_tid == -1) |
1224 | cpu = cpumap[i]; | 1224 | cpu = cpus->map[i]; |
1225 | 1225 | ||
1226 | attr = &evsel->attr; | 1226 | attr = &evsel->attr; |
1227 | 1227 | ||
@@ -1310,7 +1310,7 @@ static int __cmd_top(void) | |||
1310 | else | 1310 | else |
1311 | event__synthesize_threads(event__process, session); | 1311 | event__synthesize_threads(event__process, session); |
1312 | 1312 | ||
1313 | for (i = 0; i < nr_cpus; i++) { | 1313 | for (i = 0; i < cpus->nr; i++) { |
1314 | group_fd = -1; | 1314 | group_fd = -1; |
1315 | list_for_each_entry(counter, &evsel_list, node) | 1315 | list_for_each_entry(counter, &evsel_list, node) |
1316 | start_counter(i, counter); | 1316 | start_counter(i, counter); |
@@ -1460,16 +1460,16 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1460 | } | 1460 | } |
1461 | 1461 | ||
1462 | if (target_tid != -1) | 1462 | if (target_tid != -1) |
1463 | nr_cpus = 1; | 1463 | cpus = cpu_map__dummy_new(); |
1464 | else | 1464 | else |
1465 | nr_cpus = read_cpu_map(cpu_list); | 1465 | cpus = cpu_map__new(cpu_list); |
1466 | 1466 | ||
1467 | if (nr_cpus < 1) | 1467 | if (cpus == NULL) |
1468 | usage_with_options(top_usage, options); | 1468 | usage_with_options(top_usage, options); |
1469 | 1469 | ||
1470 | list_for_each_entry(pos, &evsel_list, node) { | 1470 | list_for_each_entry(pos, &evsel_list, node) { |
1471 | if (perf_evsel__alloc_mmap_per_thread(pos, nr_cpus, thread_num) < 0 || | 1471 | if (perf_evsel__alloc_mmap_per_thread(pos, cpus->nr, thread_num) < 0 || |
1472 | perf_evsel__alloc_fd(pos, nr_cpus, thread_num) < 0) | 1472 | perf_evsel__alloc_fd(pos, cpus->nr, thread_num) < 0) |
1473 | goto out_free_fd; | 1473 | goto out_free_fd; |
1474 | /* | 1474 | /* |
1475 | * Fill in the ones not specifically initialized via -c: | 1475 | * Fill in the ones not specifically initialized via -c: |
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index 0f9b8d7a7d7e..3ccaa1043383 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c | |||
@@ -4,32 +4,53 @@ | |||
4 | #include <assert.h> | 4 | #include <assert.h> |
5 | #include <stdio.h> | 5 | #include <stdio.h> |
6 | 6 | ||
7 | int cpumap[MAX_NR_CPUS]; | 7 | static struct cpu_map *cpu_map__default_new(void) |
8 | |||
9 | static int default_cpu_map(void) | ||
10 | { | 8 | { |
11 | int nr_cpus, i; | 9 | struct cpu_map *cpus; |
10 | int nr_cpus; | ||
12 | 11 | ||
13 | nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); | 12 | nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); |
14 | assert(nr_cpus <= MAX_NR_CPUS); | 13 | if (nr_cpus < 0) |
15 | assert((int)nr_cpus >= 0); | 14 | return NULL; |
15 | |||
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; | ||
16 | 21 | ||
17 | for (i = 0; i < nr_cpus; ++i) | 22 | cpus->nr = nr_cpus; |
18 | cpumap[i] = i; | 23 | } |
19 | 24 | ||
20 | return nr_cpus; | 25 | return cpus; |
21 | } | 26 | } |
22 | 27 | ||
23 | static int read_all_cpu_map(void) | 28 | static struct cpu_map *cpu_map__trim_new(int nr_cpus, int *tmp_cpus) |
24 | { | 29 | { |
30 | size_t payload_size = nr_cpus * sizeof(int); | ||
31 | struct cpu_map *cpus = malloc(sizeof(*cpus) + payload_size); | ||
32 | |||
33 | if (cpus != NULL) { | ||
34 | cpus->nr = nr_cpus; | ||
35 | memcpy(cpus->map, tmp_cpus, payload_size); | ||
36 | } | ||
37 | |||
38 | return cpus; | ||
39 | } | ||
40 | |||
41 | static struct cpu_map *cpu_map__read_all_cpu_map(void) | ||
42 | { | ||
43 | struct cpu_map *cpus = NULL; | ||
25 | FILE *onlnf; | 44 | FILE *onlnf; |
26 | int nr_cpus = 0; | 45 | int nr_cpus = 0; |
46 | int *tmp_cpus = NULL, *tmp; | ||
47 | int max_entries = 0; | ||
27 | int n, cpu, prev; | 48 | int n, cpu, prev; |
28 | char sep; | 49 | char sep; |
29 | 50 | ||
30 | onlnf = fopen("/sys/devices/system/cpu/online", "r"); | 51 | onlnf = fopen("/sys/devices/system/cpu/online", "r"); |
31 | if (!onlnf) | 52 | if (!onlnf) |
32 | return default_cpu_map(); | 53 | return cpu_map__default_new(); |
33 | 54 | ||
34 | sep = 0; | 55 | sep = 0; |
35 | prev = -1; | 56 | prev = -1; |
@@ -38,12 +59,28 @@ static int read_all_cpu_map(void) | |||
38 | if (n <= 0) | 59 | if (n <= 0) |
39 | break; | 60 | break; |
40 | if (prev >= 0) { | 61 | if (prev >= 0) { |
41 | assert(nr_cpus + cpu - prev - 1 < MAX_NR_CPUS); | 62 | int new_max = nr_cpus + cpu - prev - 1; |
63 | |||
64 | if (new_max >= max_entries) { | ||
65 | max_entries = new_max + MAX_NR_CPUS / 2; | ||
66 | tmp = realloc(tmp_cpus, max_entries * sizeof(int)); | ||
67 | if (tmp == NULL) | ||
68 | goto out_free_tmp; | ||
69 | tmp_cpus = tmp; | ||
70 | } | ||
71 | |||
42 | while (++prev < cpu) | 72 | while (++prev < cpu) |
43 | cpumap[nr_cpus++] = prev; | 73 | tmp_cpus[nr_cpus++] = prev; |
74 | } | ||
75 | if (nr_cpus == max_entries) { | ||
76 | max_entries += MAX_NR_CPUS; | ||
77 | tmp = realloc(tmp_cpus, max_entries * sizeof(int)); | ||
78 | if (tmp == NULL) | ||
79 | goto out_free_tmp; | ||
80 | tmp_cpus = tmp; | ||
44 | } | 81 | } |
45 | assert (nr_cpus < MAX_NR_CPUS); | 82 | |
46 | cpumap[nr_cpus++] = cpu; | 83 | tmp_cpus[nr_cpus++] = cpu; |
47 | if (n == 2 && sep == '-') | 84 | if (n == 2 && sep == '-') |
48 | prev = cpu; | 85 | prev = cpu; |
49 | else | 86 | else |
@@ -51,24 +88,31 @@ static int read_all_cpu_map(void) | |||
51 | if (n == 1 || sep == '\n') | 88 | if (n == 1 || sep == '\n') |
52 | break; | 89 | break; |
53 | } | 90 | } |
54 | fclose(onlnf); | ||
55 | if (nr_cpus > 0) | ||
56 | return nr_cpus; | ||
57 | 91 | ||
58 | return default_cpu_map(); | 92 | if (nr_cpus > 0) |
93 | cpus = cpu_map__trim_new(nr_cpus, tmp_cpus); | ||
94 | else | ||
95 | cpus = cpu_map__default_new(); | ||
96 | out_free_tmp: | ||
97 | free(tmp_cpus); | ||
98 | fclose(onlnf); | ||
99 | return cpus; | ||
59 | } | 100 | } |
60 | 101 | ||
61 | int read_cpu_map(const char *cpu_list) | 102 | struct cpu_map *cpu_map__new(const char *cpu_list) |
62 | { | 103 | { |
104 | struct cpu_map *cpus = NULL; | ||
63 | unsigned long start_cpu, end_cpu = 0; | 105 | unsigned long start_cpu, end_cpu = 0; |
64 | char *p = NULL; | 106 | char *p = NULL; |
65 | int i, nr_cpus = 0; | 107 | int i, nr_cpus = 0; |
108 | int *tmp_cpus = NULL, *tmp; | ||
109 | int max_entries = 0; | ||
66 | 110 | ||
67 | if (!cpu_list) | 111 | if (!cpu_list) |
68 | return read_all_cpu_map(); | 112 | return cpu_map__read_all_cpu_map(); |
69 | 113 | ||
70 | if (!isdigit(*cpu_list)) | 114 | if (!isdigit(*cpu_list)) |
71 | goto invalid; | 115 | goto out; |
72 | 116 | ||
73 | while (isdigit(*cpu_list)) { | 117 | while (isdigit(*cpu_list)) { |
74 | p = NULL; | 118 | p = NULL; |
@@ -94,21 +138,42 @@ int read_cpu_map(const char *cpu_list) | |||
94 | for (; start_cpu <= end_cpu; start_cpu++) { | 138 | for (; start_cpu <= end_cpu; start_cpu++) { |
95 | /* check for duplicates */ | 139 | /* check for duplicates */ |
96 | for (i = 0; i < nr_cpus; i++) | 140 | for (i = 0; i < nr_cpus; i++) |
97 | if (cpumap[i] == (int)start_cpu) | 141 | if (tmp_cpus[i] == (int)start_cpu) |
98 | goto invalid; | 142 | goto invalid; |
99 | 143 | ||
100 | assert(nr_cpus < MAX_NR_CPUS); | 144 | if (nr_cpus == max_entries) { |
101 | cpumap[nr_cpus++] = (int)start_cpu; | 145 | max_entries += MAX_NR_CPUS; |
146 | tmp = realloc(tmp_cpus, max_entries * sizeof(int)); | ||
147 | if (tmp == NULL) | ||
148 | goto invalid; | ||
149 | tmp_cpus = tmp; | ||
150 | } | ||
151 | tmp_cpus[nr_cpus++] = (int)start_cpu; | ||
102 | } | 152 | } |
103 | if (*p) | 153 | if (*p) |
104 | ++p; | 154 | ++p; |
105 | 155 | ||
106 | cpu_list = p; | 156 | cpu_list = p; |
107 | } | 157 | } |
108 | if (nr_cpus > 0) | ||
109 | return nr_cpus; | ||
110 | 158 | ||
111 | return default_cpu_map(); | 159 | if (nr_cpus > 0) |
160 | cpus = cpu_map__trim_new(nr_cpus, tmp_cpus); | ||
161 | else | ||
162 | cpus = cpu_map__default_new(); | ||
112 | invalid: | 163 | invalid: |
113 | return -1; | 164 | free(tmp_cpus); |
165 | out: | ||
166 | return cpus; | ||
167 | } | ||
168 | |||
169 | struct cpu_map *cpu_map__dummy_new(void) | ||
170 | { | ||
171 | struct cpu_map *cpus = malloc(sizeof(*cpus) + sizeof(int)); | ||
172 | |||
173 | if (cpus != NULL) { | ||
174 | cpus->nr = 1; | ||
175 | cpus->map[0] = -1; | ||
176 | } | ||
177 | |||
178 | return cpus; | ||
114 | } | 179 | } |
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index 3e60f56e490e..f7a4f42f6307 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h | |||
@@ -1,7 +1,13 @@ | |||
1 | #ifndef __PERF_CPUMAP_H | 1 | #ifndef __PERF_CPUMAP_H |
2 | #define __PERF_CPUMAP_H | 2 | #define __PERF_CPUMAP_H |
3 | 3 | ||
4 | extern int read_cpu_map(const char *cpu_list); | 4 | struct cpu_map { |
5 | extern int cpumap[]; | 5 | int nr; |
6 | int map[]; | ||
7 | }; | ||
8 | |||
9 | struct cpu_map *cpu_map__new(const char *cpu_list); | ||
10 | struct cpu_map *cpu_map__dummy_new(void); | ||
11 | void *cpu_map__delete(struct cpu_map *map); | ||
6 | 12 | ||
7 | #endif /* __PERF_CPUMAP_H */ | 13 | #endif /* __PERF_CPUMAP_H */ |