diff options
| author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-01-03 14:49:48 -0500 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-01-03 21:23:55 -0500 |
| commit | 60d567e2d9187379d642f6aba7c8a52b3fd5d261 (patch) | |
| tree | 7d6bd6f6805ff68f4fab3c0e08b7139cc5206b7d /tools | |
| parent | 48290609c0d265f5dac0fca6fd4e3c5732542f67 (diff) | |
perf tools: Refactor cpumap to hold nr and the map
So that later, we can pass the cpu_map instance instead of (nr_cpus, cpu_map)
for things like perf_evsel__open and friends.
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
| -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 */ |
