aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-stat.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2011-01-30 08:59:43 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2011-01-31 09:40:52 -0500
commit7e2ed097538c57ff5268e9a6bced7c0b885809c8 (patch)
tree44f9998cc6054d5bef07d6c2979afb0e81ddf13c /tools/perf/builtin-stat.c
parentf8a9530939ed87b9a1b1a038b90e355098b679a2 (diff)
perf evlist: Store pointer to the cpu and thread maps
So that we don't have to pass it around to the several methods that needs it, simplifying usage. There is one case where we don't have the thread/cpu map in advance, which is in the parsing routines used by top, stat, record, that we have to wait till all options are parsed to know if a cpu or thread list was passed to then create those maps. For that case consolidate the cpu and thread map creation via perf_evlist__create_maps() out of the code in top and record, while also providing a perf_evlist__set_maps() for cases where multiple evlists share maps or for when maps that represent CPU sockets, for instance, get crafted out of topology information or subsets of threads in a particular application are to be monitored, providing more granularity in specifying which cpus and threads to monitor. 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/perf/builtin-stat.c')
-rw-r--r--tools/perf/builtin-stat.c45
1 files changed, 22 insertions, 23 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 8906adfdbd8e..e0f95755361b 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -76,7 +76,6 @@ static struct perf_event_attr default_attrs[] = {
76struct perf_evlist *evsel_list; 76struct perf_evlist *evsel_list;
77 77
78static bool system_wide = false; 78static bool system_wide = false;
79static struct cpu_map *cpus;
80static int run_idx = 0; 79static int run_idx = 0;
81 80
82static int run_count = 1; 81static int run_count = 1;
@@ -85,7 +84,6 @@ static bool scale = true;
85static bool no_aggr = false; 84static bool no_aggr = false;
86static pid_t target_pid = -1; 85static pid_t target_pid = -1;
87static pid_t target_tid = -1; 86static pid_t target_tid = -1;
88static struct thread_map *threads;
89static pid_t child_pid = -1; 87static pid_t child_pid = -1;
90static bool null_run = false; 88static bool null_run = false;
91static bool big_num = true; 89static bool big_num = true;
@@ -170,7 +168,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)
170 PERF_FORMAT_TOTAL_TIME_RUNNING; 168 PERF_FORMAT_TOTAL_TIME_RUNNING;
171 169
172 if (system_wide) 170 if (system_wide)
173 return perf_evsel__open_per_cpu(evsel, cpus, false, false); 171 return perf_evsel__open_per_cpu(evsel, evsel_list->cpus, false, false);
174 172
175 attr->inherit = !no_inherit; 173 attr->inherit = !no_inherit;
176 if (target_pid == -1 && target_tid == -1) { 174 if (target_pid == -1 && target_tid == -1) {
@@ -178,7 +176,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)
178 attr->enable_on_exec = 1; 176 attr->enable_on_exec = 1;
179 } 177 }
180 178
181 return perf_evsel__open_per_thread(evsel, threads, false, false); 179 return perf_evsel__open_per_thread(evsel, evsel_list->threads, false, false);
182} 180}
183 181
184/* 182/*
@@ -203,7 +201,8 @@ static int read_counter_aggr(struct perf_evsel *counter)
203 u64 *count = counter->counts->aggr.values; 201 u64 *count = counter->counts->aggr.values;
204 int i; 202 int i;
205 203
206 if (__perf_evsel__read(counter, cpus->nr, threads->nr, scale) < 0) 204 if (__perf_evsel__read(counter, evsel_list->cpus->nr,
205 evsel_list->threads->nr, scale) < 0)
207 return -1; 206 return -1;
208 207
209 for (i = 0; i < 3; i++) 208 for (i = 0; i < 3; i++)
@@ -236,7 +235,7 @@ static int read_counter(struct perf_evsel *counter)
236 u64 *count; 235 u64 *count;
237 int cpu; 236 int cpu;
238 237
239 for (cpu = 0; cpu < cpus->nr; cpu++) { 238 for (cpu = 0; cpu < evsel_list->cpus->nr; cpu++) {
240 if (__perf_evsel__read_on_cpu(counter, cpu, 0, scale) < 0) 239 if (__perf_evsel__read_on_cpu(counter, cpu, 0, scale) < 0)
241 return -1; 240 return -1;
242 241
@@ -301,7 +300,7 @@ static int run_perf_stat(int argc __used, const char **argv)
301 } 300 }
302 301
303 if (target_tid == -1 && target_pid == -1 && !system_wide) 302 if (target_tid == -1 && target_pid == -1 && !system_wide)
304 threads->map[0] = child_pid; 303 evsel_list->threads->map[0] = child_pid;
305 304
306 /* 305 /*
307 * Wait for the child to be ready to exec. 306 * Wait for the child to be ready to exec.
@@ -353,12 +352,13 @@ static int run_perf_stat(int argc __used, const char **argv)
353 if (no_aggr) { 352 if (no_aggr) {
354 list_for_each_entry(counter, &evsel_list->entries, node) { 353 list_for_each_entry(counter, &evsel_list->entries, node) {
355 read_counter(counter); 354 read_counter(counter);
356 perf_evsel__close_fd(counter, cpus->nr, 1); 355 perf_evsel__close_fd(counter, evsel_list->cpus->nr, 1);
357 } 356 }
358 } else { 357 } else {
359 list_for_each_entry(counter, &evsel_list->entries, node) { 358 list_for_each_entry(counter, &evsel_list->entries, node) {
360 read_counter_aggr(counter); 359 read_counter_aggr(counter);
361 perf_evsel__close_fd(counter, cpus->nr, threads->nr); 360 perf_evsel__close_fd(counter, evsel_list->cpus->nr,
361 evsel_list->threads->nr);
362 } 362 }
363 } 363 }
364 364
@@ -386,7 +386,7 @@ static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg)
386 if (no_aggr) 386 if (no_aggr)
387 sprintf(cpustr, "CPU%*d%s", 387 sprintf(cpustr, "CPU%*d%s",
388 csv_output ? 0 : -4, 388 csv_output ? 0 : -4,
389 cpus->map[cpu], csv_sep); 389 evsel_list->cpus->map[cpu], csv_sep);
390 390
391 fprintf(stderr, fmt, cpustr, msecs, csv_sep, event_name(evsel)); 391 fprintf(stderr, fmt, cpustr, msecs, csv_sep, event_name(evsel));
392 392
@@ -414,7 +414,7 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
414 if (no_aggr) 414 if (no_aggr)
415 sprintf(cpustr, "CPU%*d%s", 415 sprintf(cpustr, "CPU%*d%s",
416 csv_output ? 0 : -4, 416 csv_output ? 0 : -4,
417 cpus->map[cpu], csv_sep); 417 evsel_list->cpus->map[cpu], csv_sep);
418 else 418 else
419 cpu = 0; 419 cpu = 0;
420 420
@@ -500,14 +500,14 @@ static void print_counter(struct perf_evsel *counter)
500 u64 ena, run, val; 500 u64 ena, run, val;
501 int cpu; 501 int cpu;
502 502
503 for (cpu = 0; cpu < cpus->nr; cpu++) { 503 for (cpu = 0; cpu < evsel_list->cpus->nr; cpu++) {
504 val = counter->counts->cpu[cpu].val; 504 val = counter->counts->cpu[cpu].val;
505 ena = counter->counts->cpu[cpu].ena; 505 ena = counter->counts->cpu[cpu].ena;
506 run = counter->counts->cpu[cpu].run; 506 run = counter->counts->cpu[cpu].run;
507 if (run == 0 || ena == 0) { 507 if (run == 0 || ena == 0) {
508 fprintf(stderr, "CPU%*d%s%*s%s%-24s", 508 fprintf(stderr, "CPU%*d%s%*s%s%-24s",
509 csv_output ? 0 : -4, 509 csv_output ? 0 : -4,
510 cpus->map[cpu], csv_sep, 510 evsel_list->cpus->map[cpu], csv_sep,
511 csv_output ? 0 : 18, 511 csv_output ? 0 : 18,
512 "<not counted>", csv_sep, 512 "<not counted>", csv_sep,
513 event_name(counter)); 513 event_name(counter));
@@ -652,7 +652,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
652 652
653 setlocale(LC_ALL, ""); 653 setlocale(LC_ALL, "");
654 654
655 evsel_list = perf_evlist__new(); 655 evsel_list = perf_evlist__new(NULL, NULL);
656 if (evsel_list == NULL) 656 if (evsel_list == NULL)
657 return -ENOMEM; 657 return -ENOMEM;
658 658
@@ -701,18 +701,18 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
701 if (target_pid != -1) 701 if (target_pid != -1)
702 target_tid = target_pid; 702 target_tid = target_pid;
703 703
704 threads = thread_map__new(target_pid, target_tid); 704 evsel_list->threads = thread_map__new(target_pid, target_tid);
705 if (threads == NULL) { 705 if (evsel_list->threads == NULL) {
706 pr_err("Problems finding threads of monitor\n"); 706 pr_err("Problems finding threads of monitor\n");
707 usage_with_options(stat_usage, options); 707 usage_with_options(stat_usage, options);
708 } 708 }
709 709
710 if (system_wide) 710 if (system_wide)
711 cpus = cpu_map__new(cpu_list); 711 evsel_list->cpus = cpu_map__new(cpu_list);
712 else 712 else
713 cpus = cpu_map__dummy_new(); 713 evsel_list->cpus = cpu_map__dummy_new();
714 714
715 if (cpus == NULL) { 715 if (evsel_list->cpus == NULL) {
716 perror("failed to parse CPUs map"); 716 perror("failed to parse CPUs map");
717 usage_with_options(stat_usage, options); 717 usage_with_options(stat_usage, options);
718 return -1; 718 return -1;
@@ -720,8 +720,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
720 720
721 list_for_each_entry(pos, &evsel_list->entries, node) { 721 list_for_each_entry(pos, &evsel_list->entries, node) {
722 if (perf_evsel__alloc_stat_priv(pos) < 0 || 722 if (perf_evsel__alloc_stat_priv(pos) < 0 ||
723 perf_evsel__alloc_counts(pos, cpus->nr) < 0 || 723 perf_evsel__alloc_counts(pos, evsel_list->cpus->nr) < 0 ||
724 perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0) 724 perf_evsel__alloc_fd(pos, evsel_list->cpus->nr, evsel_list->threads->nr) < 0)
725 goto out_free_fd; 725 goto out_free_fd;
726 } 726 }
727 727
@@ -750,7 +750,6 @@ out_free_fd:
750 perf_evsel__free_stat_priv(pos); 750 perf_evsel__free_stat_priv(pos);
751 perf_evlist__delete(evsel_list); 751 perf_evlist__delete(evsel_list);
752out: 752out:
753 thread_map__delete(threads); 753 perf_evlist__delete_maps(evsel_list);
754 threads = NULL;
755 return status; 754 return status;
756} 755}