aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorLiming Wang <liming.wang@windriver.com>2009-12-31 03:05:50 -0500
committerIngo Molnar <mingo@elte.hu>2010-01-13 04:09:08 -0500
commit60666c630bdb33983a894b050b588b663f38f368 (patch)
treeec9eef2f18fe94f7ec6d86ad4fcb046081a47283 /tools
parent0fb8ee48d9dfff6a0913ceb0be2068d8be203763 (diff)
perf tools: Fix --pid option for stat
current pid option doesn't work for perf stat. Change it to what perf record --pid acts as. Signed-off-by: Liming Wang <liming.wang@windriver.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> LKML-Reference: <1262246750-2191-1-git-send-email-liming.wang@windriver.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/builtin-stat.c106
1 files changed, 61 insertions, 45 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index c70d72003557..e8c85d5aec41 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -44,6 +44,7 @@
44#include "util/parse-events.h" 44#include "util/parse-events.h"
45#include "util/event.h" 45#include "util/event.h"
46#include "util/debug.h" 46#include "util/debug.h"
47#include "util/header.h"
47 48
48#include <sys/prctl.h> 49#include <sys/prctl.h>
49#include <math.h> 50#include <math.h>
@@ -79,6 +80,8 @@ static int fd[MAX_NR_CPUS][MAX_COUNTERS];
79 80
80static int event_scaled[MAX_COUNTERS]; 81static int event_scaled[MAX_COUNTERS];
81 82
83static volatile int done = 0;
84
82struct stats 85struct stats
83{ 86{
84 double n, mean, M2; 87 double n, mean, M2;
@@ -247,61 +250,64 @@ static int run_perf_stat(int argc __used, const char **argv)
247 unsigned long long t0, t1; 250 unsigned long long t0, t1;
248 int status = 0; 251 int status = 0;
249 int counter; 252 int counter;
250 int pid; 253 int pid = target_pid;
251 int child_ready_pipe[2], go_pipe[2]; 254 int child_ready_pipe[2], go_pipe[2];
255 const bool forks = (target_pid == -1 && argc > 0);
252 char buf; 256 char buf;
253 257
254 if (!system_wide) 258 if (!system_wide)
255 nr_cpus = 1; 259 nr_cpus = 1;
256 260
257 if (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0) { 261 if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) {
258 perror("failed to create pipes"); 262 perror("failed to create pipes");
259 exit(1); 263 exit(1);
260 } 264 }
261 265
262 if ((pid = fork()) < 0) 266 if (forks) {
263 perror("failed to fork"); 267 if ((pid = fork()) < 0)
268 perror("failed to fork");
269
270 if (!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 }
264 298
265 if (!pid) { 299 child_pid = pid;
266 close(child_ready_pipe[0]);
267 close(go_pipe[1]);
268 fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
269 300
270 /* 301 /*
271 * Do a dummy execvp to get the PLT entry resolved, 302 * Wait for the child to be ready to exec.
272 * so we avoid the resolver overhead on the real
273 * execvp call.
274 */
275 execvp("", (char **)argv);
276
277 /*
278 * Tell the parent we're ready to go
279 */ 303 */
280 close(child_ready_pipe[1]); 304 close(child_ready_pipe[1]);
281 305 close(go_pipe[0]);
282 /* 306 if (read(child_ready_pipe[0], &buf, 1) == -1)
283 * Wait until the parent tells us to go.
284 */
285 if (read(go_pipe[0], &buf, 1) == -1)
286 perror("unable to read pipe"); 307 perror("unable to read pipe");
287 308 close(child_ready_pipe[0]);
288 execvp(argv[0], (char **)argv);
289
290 perror(argv[0]);
291 exit(-1);
292 } 309 }
293 310
294 child_pid = pid;
295
296 /*
297 * Wait for the child to be ready to exec.
298 */
299 close(child_ready_pipe[1]);
300 close(go_pipe[0]);
301 if (read(child_ready_pipe[0], &buf, 1) == -1)
302 perror("unable to read pipe");
303 close(child_ready_pipe[0]);
304
305 for (counter = 0; counter < nr_counters; counter++) 311 for (counter = 0; counter < nr_counters; counter++)
306 create_perf_stat_counter(counter, pid); 312 create_perf_stat_counter(counter, pid);
307 313
@@ -310,8 +316,12 @@ static int run_perf_stat(int argc __used, const char **argv)
310 */ 316 */
311 t0 = rdclock(); 317 t0 = rdclock();
312 318
313 close(go_pipe[1]); 319 if (forks) {
314 wait(&status); 320 close(go_pipe[1]);
321 wait(&status);
322 } else {
323 while(!done);
324 }
315 325
316 t1 = rdclock(); 326 t1 = rdclock();
317 327
@@ -417,10 +427,13 @@ static void print_stat(int argc, const char **argv)
417 fflush(stdout); 427 fflush(stdout);
418 428
419 fprintf(stderr, "\n"); 429 fprintf(stderr, "\n");
420 fprintf(stderr, " Performance counter stats for \'%s", argv[0]); 430 fprintf(stderr, " Performance counter stats for ");
421 431 if(target_pid == -1) {
422 for (i = 1; i < argc; i++) 432 fprintf(stderr, "\'%s", argv[0]);
423 fprintf(stderr, " %s", argv[i]); 433 for (i = 1; i < argc; i++)
434 fprintf(stderr, " %s", argv[i]);
435 }else
436 fprintf(stderr, "task pid \'%d", target_pid);
424 437
425 fprintf(stderr, "\'"); 438 fprintf(stderr, "\'");
426 if (run_count > 1) 439 if (run_count > 1)
@@ -445,6 +458,9 @@ static volatile int signr = -1;
445 458
446static void skip_signal(int signo) 459static void skip_signal(int signo)
447{ 460{
461 if(target_pid != -1)
462 done = 1;
463
448 signr = signo; 464 signr = signo;
449} 465}
450 466
@@ -461,7 +477,7 @@ static void sig_atexit(void)
461} 477}
462 478
463static const char * const stat_usage[] = { 479static const char * const stat_usage[] = {
464 "perf stat [<options>] <command>", 480 "perf stat [<options>] [<command>]",
465 NULL 481 NULL
466}; 482};
467 483
@@ -492,7 +508,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
492 508
493 argc = parse_options(argc, argv, options, stat_usage, 509 argc = parse_options(argc, argv, options, stat_usage,
494 PARSE_OPT_STOP_AT_NON_OPTION); 510 PARSE_OPT_STOP_AT_NON_OPTION);
495 if (!argc) 511 if (!argc && target_pid == -1)
496 usage_with_options(stat_usage, options); 512 usage_with_options(stat_usage, options);
497 if (run_count <= 0) 513 if (run_count <= 0)
498 usage_with_options(stat_usage, options); 514 usage_with_options(stat_usage, options);