xref: /openbmc/linux/tools/perf/builtin-stat.c (revision df2634f43f5106947f3735a0b61a6527a4b278cd)
1 /*
2  * builtin-stat.c
3  *
4  * Builtin stat command: Give a precise performance counters summary
5  * overview about any workload, CPU or specific PID.
6  *
7  * Sample output:
8 
9    $ perf stat ~/hackbench 10
10    Time: 0.104
11 
12     Performance counter stats for '/home/mingo/hackbench':
13 
14        1255.538611  task clock ticks     #      10.143 CPU utilization factor
15              54011  context switches     #       0.043 M/sec
16                385  CPU migrations       #       0.000 M/sec
17              17755  pagefaults           #       0.014 M/sec
18         3808323185  CPU cycles           #    3033.219 M/sec
19         1575111190  instructions         #    1254.530 M/sec
20           17367895  cache references     #      13.833 M/sec
21            7674421  cache misses         #       6.112 M/sec
22 
23     Wall-clock time elapsed:   123.786620 msecs
24 
25  *
26  * Copyright (C) 2008, Red Hat Inc, Ingo Molnar <mingo@redhat.com>
27  *
28  * Improvements and fixes by:
29  *
30  *   Arjan van de Ven <arjan@linux.intel.com>
31  *   Yanmin Zhang <yanmin.zhang@intel.com>
32  *   Wu Fengguang <fengguang.wu@intel.com>
33  *   Mike Galbraith <efault@gmx.de>
34  *   Paul Mackerras <paulus@samba.org>
35  *   Jaswinder Singh Rajput <jaswinder@kernel.org>
36  *
37  * Released under the GPL v2. (and only v2, not any later version)
38  */
39 
40 #include "perf.h"
41 #include "builtin.h"
42 #include "util/util.h"
43 #include "util/parse-options.h"
44 #include "util/parse-events.h"
45 #include "util/event.h"
46 #include "util/evsel.h"
47 #include "util/debug.h"
48 #include "util/header.h"
49 #include "util/cpumap.h"
50 #include "util/thread.h"
51 
52 #include <sys/prctl.h>
53 #include <math.h>
54 #include <locale.h>
55 
56 #define DEFAULT_SEPARATOR	" "
57 
58 static struct perf_event_attr default_attrs[] = {
59 
60   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK		},
61   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES	},
62   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS		},
63   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS		},
64 
65   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES		},
66   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS		},
67   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS	},
68   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES		},
69   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CACHE_REFERENCES	},
70   { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CACHE_MISSES		},
71 
72 };
73 
74 static bool			system_wide			=  false;
75 static struct cpu_map		*cpus;
76 static int			run_idx				=  0;
77 
78 static int			run_count			=  1;
79 static bool			no_inherit			= false;
80 static bool			scale				=  true;
81 static bool			no_aggr				= false;
82 static pid_t			target_pid			= -1;
83 static pid_t			target_tid			= -1;
84 static struct thread_map	*threads;
85 static pid_t			child_pid			= -1;
86 static bool			null_run			=  false;
87 static bool			big_num				=  true;
88 static int			big_num_opt			=  -1;
89 static const char		*cpu_list;
90 static const char		*csv_sep			= NULL;
91 static bool			csv_output			= false;
92 
93 static volatile int done = 0;
94 
95 struct stats
96 {
97 	double n, mean, M2;
98 };
99 
100 struct perf_stat {
101 	struct stats	  res_stats[3];
102 };
103 
104 static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
105 {
106 	evsel->priv = zalloc(sizeof(struct perf_stat));
107 	return evsel->priv == NULL ? -ENOMEM : 0;
108 }
109 
110 static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
111 {
112 	free(evsel->priv);
113 	evsel->priv = NULL;
114 }
115 
116 static void update_stats(struct stats *stats, u64 val)
117 {
118 	double delta;
119 
120 	stats->n++;
121 	delta = val - stats->mean;
122 	stats->mean += delta / stats->n;
123 	stats->M2 += delta*(val - stats->mean);
124 }
125 
126 static double avg_stats(struct stats *stats)
127 {
128 	return stats->mean;
129 }
130 
131 /*
132  * http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
133  *
134  *       (\Sum n_i^2) - ((\Sum n_i)^2)/n
135  * s^2 = -------------------------------
136  *                  n - 1
137  *
138  * http://en.wikipedia.org/wiki/Stddev
139  *
140  * The std dev of the mean is related to the std dev by:
141  *
142  *             s
143  * s_mean = -------
144  *          sqrt(n)
145  *
146  */
147 static double stddev_stats(struct stats *stats)
148 {
149 	double variance = stats->M2 / (stats->n - 1);
150 	double variance_mean = variance / stats->n;
151 
152 	return sqrt(variance_mean);
153 }
154 
155 struct stats			runtime_nsecs_stats[MAX_NR_CPUS];
156 struct stats			runtime_cycles_stats[MAX_NR_CPUS];
157 struct stats			runtime_branches_stats[MAX_NR_CPUS];
158 struct stats			walltime_nsecs_stats;
159 
160 static int create_perf_stat_counter(struct perf_evsel *evsel)
161 {
162 	struct perf_event_attr *attr = &evsel->attr;
163 
164 	if (scale)
165 		attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
166 				    PERF_FORMAT_TOTAL_TIME_RUNNING;
167 
168 	if (system_wide)
169 		return perf_evsel__open_per_cpu(evsel, cpus);
170 
171 	attr->inherit = !no_inherit;
172 	if (target_pid == -1 && target_tid == -1) {
173 		attr->disabled = 1;
174 		attr->enable_on_exec = 1;
175 	}
176 
177 	return perf_evsel__open_per_thread(evsel, threads);
178 }
179 
180 /*
181  * Does the counter have nsecs as a unit?
182  */
183 static inline int nsec_counter(struct perf_evsel *evsel)
184 {
185 	if (perf_evsel__match(evsel, SOFTWARE, SW_CPU_CLOCK) ||
186 	    perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
187 		return 1;
188 
189 	return 0;
190 }
191 
192 /*
193  * Read out the results of a single counter:
194  * aggregate counts across CPUs in system-wide mode
195  */
196 static int read_counter_aggr(struct perf_evsel *counter)
197 {
198 	struct perf_stat *ps = counter->priv;
199 	u64 *count = counter->counts->aggr.values;
200 	int i;
201 
202 	if (__perf_evsel__read(counter, cpus->nr, threads->nr, scale) < 0)
203 		return -1;
204 
205 	for (i = 0; i < 3; i++)
206 		update_stats(&ps->res_stats[i], count[i]);
207 
208 	if (verbose) {
209 		fprintf(stderr, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
210 			event_name(counter), count[0], count[1], count[2]);
211 	}
212 
213 	/*
214 	 * Save the full runtime - to allow normalization during printout:
215 	 */
216 	if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK))
217 		update_stats(&runtime_nsecs_stats[0], count[0]);
218 	if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
219 		update_stats(&runtime_cycles_stats[0], count[0]);
220 	if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS))
221 		update_stats(&runtime_branches_stats[0], count[0]);
222 
223 	return 0;
224 }
225 
226 /*
227  * Read out the results of a single counter:
228  * do not aggregate counts across CPUs in system-wide mode
229  */
230 static int read_counter(struct perf_evsel *counter)
231 {
232 	u64 *count;
233 	int cpu;
234 
235 	for (cpu = 0; cpu < cpus->nr; cpu++) {
236 		if (__perf_evsel__read_on_cpu(counter, cpu, 0, scale) < 0)
237 			return -1;
238 
239 		count = counter->counts->cpu[cpu].values;
240 
241 		if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK))
242 			update_stats(&runtime_nsecs_stats[cpu], count[0]);
243 		if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
244 			update_stats(&runtime_cycles_stats[cpu], count[0]);
245 		if (perf_evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS))
246 			update_stats(&runtime_branches_stats[cpu], count[0]);
247 	}
248 
249 	return 0;
250 }
251 
252 static int run_perf_stat(int argc __used, const char **argv)
253 {
254 	unsigned long long t0, t1;
255 	struct perf_evsel *counter;
256 	int status = 0;
257 	int child_ready_pipe[2], go_pipe[2];
258 	const bool forks = (argc > 0);
259 	char buf;
260 
261 	if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) {
262 		perror("failed to create pipes");
263 		exit(1);
264 	}
265 
266 	if (forks) {
267 		if ((child_pid = fork()) < 0)
268 			perror("failed to fork");
269 
270 		if (!child_pid) {
271 			close(child_ready_pipe[0]);
272 			close(go_pipe[1]);
273 			fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
274 
275 			/*
276 			 * Do a dummy execvp to get the PLT entry resolved,
277 			 * so we avoid the resolver overhead on the real
278 			 * execvp call.
279 			 */
280 			execvp("", (char **)argv);
281 
282 			/*
283 			 * Tell the parent we're ready to go
284 			 */
285 			close(child_ready_pipe[1]);
286 
287 			/*
288 			 * Wait until the parent tells us to go.
289 			 */
290 			if (read(go_pipe[0], &buf, 1) == -1)
291 				perror("unable to read pipe");
292 
293 			execvp(argv[0], (char **)argv);
294 
295 			perror(argv[0]);
296 			exit(-1);
297 		}
298 
299 		if (target_tid == -1 && target_pid == -1 && !system_wide)
300 			threads->map[0] = child_pid;
301 
302 		/*
303 		 * Wait for the child to be ready to exec.
304 		 */
305 		close(child_ready_pipe[1]);
306 		close(go_pipe[0]);
307 		if (read(child_ready_pipe[0], &buf, 1) == -1)
308 			perror("unable to read pipe");
309 		close(child_ready_pipe[0]);
310 	}
311 
312 	list_for_each_entry(counter, &evsel_list, node) {
313 		if (create_perf_stat_counter(counter) < 0) {
314 			if (errno == -EPERM || errno == -EACCES) {
315 				error("You may not have permission to collect %sstats.\n"
316 				      "\t Consider tweaking"
317 				      " /proc/sys/kernel/perf_event_paranoid or running as root.",
318 				      system_wide ? "system-wide " : "");
319 			} else if (errno == ENOENT) {
320 				error("%s event is not supported. ", event_name(counter));
321 			} else {
322 				error("open_counter returned with %d (%s). "
323 				      "/bin/dmesg may provide additional information.\n",
324 				       errno, strerror(errno));
325 			}
326 			if (child_pid != -1)
327 				kill(child_pid, SIGTERM);
328 			die("Not all events could be opened.\n");
329 			return -1;
330 		}
331 	}
332 
333 	/*
334 	 * Enable counters and exec the command:
335 	 */
336 	t0 = rdclock();
337 
338 	if (forks) {
339 		close(go_pipe[1]);
340 		wait(&status);
341 	} else {
342 		while(!done) sleep(1);
343 	}
344 
345 	t1 = rdclock();
346 
347 	update_stats(&walltime_nsecs_stats, t1 - t0);
348 
349 	if (no_aggr) {
350 		list_for_each_entry(counter, &evsel_list, node) {
351 			read_counter(counter);
352 			perf_evsel__close_fd(counter, cpus->nr, 1);
353 		}
354 	} else {
355 		list_for_each_entry(counter, &evsel_list, node) {
356 			read_counter_aggr(counter);
357 			perf_evsel__close_fd(counter, cpus->nr, threads->nr);
358 		}
359 	}
360 
361 	return WEXITSTATUS(status);
362 }
363 
364 static void print_noise(struct perf_evsel *evsel, double avg)
365 {
366 	struct perf_stat *ps;
367 
368 	if (run_count == 1)
369 		return;
370 
371 	ps = evsel->priv;
372 	fprintf(stderr, "   ( +- %7.3f%% )",
373 			100 * stddev_stats(&ps->res_stats[0]) / avg);
374 }
375 
376 static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg)
377 {
378 	double msecs = avg / 1e6;
379 	char cpustr[16] = { '\0', };
380 	const char *fmt = csv_output ? "%s%.6f%s%s" : "%s%18.6f%s%-24s";
381 
382 	if (no_aggr)
383 		sprintf(cpustr, "CPU%*d%s",
384 			csv_output ? 0 : -4,
385 			cpus->map[cpu], csv_sep);
386 
387 	fprintf(stderr, fmt, cpustr, msecs, csv_sep, event_name(evsel));
388 
389 	if (csv_output)
390 		return;
391 
392 	if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK))
393 		fprintf(stderr, " # %10.3f CPUs ",
394 				avg / avg_stats(&walltime_nsecs_stats));
395 }
396 
397 static void abs_printout(int cpu, struct perf_evsel *evsel, double avg)
398 {
399 	double total, ratio = 0.0;
400 	char cpustr[16] = { '\0', };
401 	const char *fmt;
402 
403 	if (csv_output)
404 		fmt = "%s%.0f%s%s";
405 	else if (big_num)
406 		fmt = "%s%'18.0f%s%-24s";
407 	else
408 		fmt = "%s%18.0f%s%-24s";
409 
410 	if (no_aggr)
411 		sprintf(cpustr, "CPU%*d%s",
412 			csv_output ? 0 : -4,
413 			cpus->map[cpu], csv_sep);
414 	else
415 		cpu = 0;
416 
417 	fprintf(stderr, fmt, cpustr, avg, csv_sep, event_name(evsel));
418 
419 	if (csv_output)
420 		return;
421 
422 	if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) {
423 		total = avg_stats(&runtime_cycles_stats[cpu]);
424 
425 		if (total)
426 			ratio = avg / total;
427 
428 		fprintf(stderr, " # %10.3f IPC  ", ratio);
429 	} else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) &&
430 			runtime_branches_stats[cpu].n != 0) {
431 		total = avg_stats(&runtime_branches_stats[cpu]);
432 
433 		if (total)
434 			ratio = avg * 100 / total;
435 
436 		fprintf(stderr, " # %10.3f %%    ", ratio);
437 
438 	} else if (runtime_nsecs_stats[cpu].n != 0) {
439 		total = avg_stats(&runtime_nsecs_stats[cpu]);
440 
441 		if (total)
442 			ratio = 1000.0 * avg / total;
443 
444 		fprintf(stderr, " # %10.3f M/sec", ratio);
445 	}
446 }
447 
448 /*
449  * Print out the results of a single counter:
450  * aggregated counts in system-wide mode
451  */
452 static void print_counter_aggr(struct perf_evsel *counter)
453 {
454 	struct perf_stat *ps = counter->priv;
455 	double avg = avg_stats(&ps->res_stats[0]);
456 	int scaled = counter->counts->scaled;
457 
458 	if (scaled == -1) {
459 		fprintf(stderr, "%*s%s%-24s\n",
460 			csv_output ? 0 : 18,
461 			"<not counted>", csv_sep, event_name(counter));
462 		return;
463 	}
464 
465 	if (nsec_counter(counter))
466 		nsec_printout(-1, counter, avg);
467 	else
468 		abs_printout(-1, counter, avg);
469 
470 	if (csv_output) {
471 		fputc('\n', stderr);
472 		return;
473 	}
474 
475 	print_noise(counter, avg);
476 
477 	if (scaled) {
478 		double avg_enabled, avg_running;
479 
480 		avg_enabled = avg_stats(&ps->res_stats[1]);
481 		avg_running = avg_stats(&ps->res_stats[2]);
482 
483 		fprintf(stderr, "  (scaled from %.2f%%)",
484 				100 * avg_running / avg_enabled);
485 	}
486 
487 	fprintf(stderr, "\n");
488 }
489 
490 /*
491  * Print out the results of a single counter:
492  * does not use aggregated count in system-wide
493  */
494 static void print_counter(struct perf_evsel *counter)
495 {
496 	u64 ena, run, val;
497 	int cpu;
498 
499 	for (cpu = 0; cpu < cpus->nr; cpu++) {
500 		val = counter->counts->cpu[cpu].val;
501 		ena = counter->counts->cpu[cpu].ena;
502 		run = counter->counts->cpu[cpu].run;
503 		if (run == 0 || ena == 0) {
504 			fprintf(stderr, "CPU%*d%s%*s%s%-24s",
505 				csv_output ? 0 : -4,
506 				cpus->map[cpu], csv_sep,
507 				csv_output ? 0 : 18,
508 				"<not counted>", csv_sep,
509 				event_name(counter));
510 
511 			fprintf(stderr, "\n");
512 			continue;
513 		}
514 
515 		if (nsec_counter(counter))
516 			nsec_printout(cpu, counter, val);
517 		else
518 			abs_printout(cpu, counter, val);
519 
520 		if (!csv_output) {
521 			print_noise(counter, 1.0);
522 
523 			if (run != ena) {
524 				fprintf(stderr, "  (scaled from %.2f%%)",
525 					100.0 * run / ena);
526 			}
527 		}
528 		fprintf(stderr, "\n");
529 	}
530 }
531 
532 static void print_stat(int argc, const char **argv)
533 {
534 	struct perf_evsel *counter;
535 	int i;
536 
537 	fflush(stdout);
538 
539 	if (!csv_output) {
540 		fprintf(stderr, "\n");
541 		fprintf(stderr, " Performance counter stats for ");
542 		if(target_pid == -1 && target_tid == -1) {
543 			fprintf(stderr, "\'%s", argv[0]);
544 			for (i = 1; i < argc; i++)
545 				fprintf(stderr, " %s", argv[i]);
546 		} else if (target_pid != -1)
547 			fprintf(stderr, "process id \'%d", target_pid);
548 		else
549 			fprintf(stderr, "thread id \'%d", target_tid);
550 
551 		fprintf(stderr, "\'");
552 		if (run_count > 1)
553 			fprintf(stderr, " (%d runs)", run_count);
554 		fprintf(stderr, ":\n\n");
555 	}
556 
557 	if (no_aggr) {
558 		list_for_each_entry(counter, &evsel_list, node)
559 			print_counter(counter);
560 	} else {
561 		list_for_each_entry(counter, &evsel_list, node)
562 			print_counter_aggr(counter);
563 	}
564 
565 	if (!csv_output) {
566 		fprintf(stderr, "\n");
567 		fprintf(stderr, " %18.9f  seconds time elapsed",
568 				avg_stats(&walltime_nsecs_stats)/1e9);
569 		if (run_count > 1) {
570 			fprintf(stderr, "   ( +- %7.3f%% )",
571 				100*stddev_stats(&walltime_nsecs_stats) /
572 				avg_stats(&walltime_nsecs_stats));
573 		}
574 		fprintf(stderr, "\n\n");
575 	}
576 }
577 
578 static volatile int signr = -1;
579 
580 static void skip_signal(int signo)
581 {
582 	if(child_pid == -1)
583 		done = 1;
584 
585 	signr = signo;
586 }
587 
588 static void sig_atexit(void)
589 {
590 	if (child_pid != -1)
591 		kill(child_pid, SIGTERM);
592 
593 	if (signr == -1)
594 		return;
595 
596 	signal(signr, SIG_DFL);
597 	kill(getpid(), signr);
598 }
599 
600 static const char * const stat_usage[] = {
601 	"perf stat [<options>] [<command>]",
602 	NULL
603 };
604 
605 static int stat__set_big_num(const struct option *opt __used,
606 			     const char *s __used, int unset)
607 {
608 	big_num_opt = unset ? 0 : 1;
609 	return 0;
610 }
611 
612 static const struct option options[] = {
613 	OPT_CALLBACK('e', "event", NULL, "event",
614 		     "event selector. use 'perf list' to list available events",
615 		     parse_events),
616 	OPT_BOOLEAN('i', "no-inherit", &no_inherit,
617 		    "child tasks do not inherit counters"),
618 	OPT_INTEGER('p', "pid", &target_pid,
619 		    "stat events on existing process id"),
620 	OPT_INTEGER('t', "tid", &target_tid,
621 		    "stat events on existing thread id"),
622 	OPT_BOOLEAN('a', "all-cpus", &system_wide,
623 		    "system-wide collection from all CPUs"),
624 	OPT_BOOLEAN('c', "scale", &scale,
625 		    "scale/normalize counters"),
626 	OPT_INCR('v', "verbose", &verbose,
627 		    "be more verbose (show counter open errors, etc)"),
628 	OPT_INTEGER('r', "repeat", &run_count,
629 		    "repeat command and print average + stddev (max: 100)"),
630 	OPT_BOOLEAN('n', "null", &null_run,
631 		    "null run - dont start any counters"),
632 	OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
633 			   "print large numbers with thousands\' separators",
634 			   stat__set_big_num),
635 	OPT_STRING('C', "cpu", &cpu_list, "cpu",
636 		    "list of cpus to monitor in system-wide"),
637 	OPT_BOOLEAN('A', "no-aggr", &no_aggr,
638 		    "disable CPU count aggregation"),
639 	OPT_STRING('x', "field-separator", &csv_sep, "separator",
640 		   "print counts with custom separator"),
641 	OPT_END()
642 };
643 
644 int cmd_stat(int argc, const char **argv, const char *prefix __used)
645 {
646 	struct perf_evsel *pos;
647 	int status = -ENOMEM;
648 
649 	setlocale(LC_ALL, "");
650 
651 	argc = parse_options(argc, argv, options, stat_usage,
652 		PARSE_OPT_STOP_AT_NON_OPTION);
653 
654 	if (csv_sep)
655 		csv_output = true;
656 	else
657 		csv_sep = DEFAULT_SEPARATOR;
658 
659 	/*
660 	 * let the spreadsheet do the pretty-printing
661 	 */
662 	if (csv_output) {
663 		/* User explicitely passed -B? */
664 		if (big_num_opt == 1) {
665 			fprintf(stderr, "-B option not supported with -x\n");
666 			usage_with_options(stat_usage, options);
667 		} else /* Nope, so disable big number formatting */
668 			big_num = false;
669 	} else if (big_num_opt == 0) /* User passed --no-big-num */
670 		big_num = false;
671 
672 	if (!argc && target_pid == -1 && target_tid == -1)
673 		usage_with_options(stat_usage, options);
674 	if (run_count <= 0)
675 		usage_with_options(stat_usage, options);
676 
677 	/* no_aggr is for system-wide only */
678 	if (no_aggr && !system_wide)
679 		usage_with_options(stat_usage, options);
680 
681 	/* Set attrs and nr_counters if no event is selected and !null_run */
682 	if (!null_run && !nr_counters) {
683 		size_t c;
684 
685 		nr_counters = ARRAY_SIZE(default_attrs);
686 
687 		for (c = 0; c < ARRAY_SIZE(default_attrs); ++c) {
688 			pos = perf_evsel__new(&default_attrs[c],
689 					      nr_counters);
690 			if (pos == NULL)
691 				goto out;
692 			list_add(&pos->node, &evsel_list);
693 		}
694 	}
695 
696 	if (target_pid != -1)
697 		target_tid = target_pid;
698 
699 	threads = thread_map__new(target_pid, target_tid);
700 	if (threads == NULL) {
701 		pr_err("Problems finding threads of monitor\n");
702 		usage_with_options(stat_usage, options);
703 	}
704 
705 	if (system_wide)
706 		cpus = cpu_map__new(cpu_list);
707 	else
708 		cpus = cpu_map__dummy_new();
709 
710 	if (cpus == NULL) {
711 		perror("failed to parse CPUs map");
712 		usage_with_options(stat_usage, options);
713 		return -1;
714 	}
715 
716 	list_for_each_entry(pos, &evsel_list, node) {
717 		if (perf_evsel__alloc_stat_priv(pos) < 0 ||
718 		    perf_evsel__alloc_counts(pos, cpus->nr) < 0 ||
719 		    perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0)
720 			goto out_free_fd;
721 	}
722 
723 	/*
724 	 * We dont want to block the signals - that would cause
725 	 * child tasks to inherit that and Ctrl-C would not work.
726 	 * What we want is for Ctrl-C to work in the exec()-ed
727 	 * task, but being ignored by perf stat itself:
728 	 */
729 	atexit(sig_atexit);
730 	signal(SIGINT,  skip_signal);
731 	signal(SIGALRM, skip_signal);
732 	signal(SIGABRT, skip_signal);
733 
734 	status = 0;
735 	for (run_idx = 0; run_idx < run_count; run_idx++) {
736 		if (run_count != 1 && verbose)
737 			fprintf(stderr, "[ perf stat: executing run #%d ... ]\n", run_idx + 1);
738 		status = run_perf_stat(argc, argv);
739 	}
740 
741 	if (status != -1)
742 		print_stat(argc, argv);
743 out_free_fd:
744 	list_for_each_entry(pos, &evsel_list, node)
745 		perf_evsel__free_stat_priv(pos);
746 	perf_evsel_list__delete();
747 out:
748 	thread_map__delete(threads);
749 	threads = NULL;
750 	return status;
751 }
752