pmcstat.c (153704) | pmcstat.c (157144) |
---|---|
1/*- | 1/*- |
2 * Copyright (c) 2003-2005, Joseph Koshy | 2 * Copyright (c) 2003-2006, Joseph Koshy |
3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright --- 9 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright --- 9 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/usr.sbin/pmcstat/pmcstat.c 153704 2005-12-24 17:00:33Z jkoshy $"); | 28__FBSDID("$FreeBSD: head/usr.sbin/pmcstat/pmcstat.c 157144 2006-03-26 12:20:54Z jkoshy $"); |
29 30#include <sys/types.h> 31#include <sys/event.h> 32#include <sys/queue.h> 33#include <sys/socket.h> 34#include <sys/stat.h> 35#include <sys/time.h> 36#include <sys/ttycom.h> 37#include <sys/wait.h> 38 39#include <assert.h> 40#include <err.h> 41#include <errno.h> 42#include <fcntl.h> | 29 30#include <sys/types.h> 31#include <sys/event.h> 32#include <sys/queue.h> 33#include <sys/socket.h> 34#include <sys/stat.h> 35#include <sys/time.h> 36#include <sys/ttycom.h> 37#include <sys/wait.h> 38 39#include <assert.h> 40#include <err.h> 41#include <errno.h> 42#include <fcntl.h> |
43#include <libgen.h> |
|
43#include <limits.h> 44#include <math.h> 45#include <pmc.h> 46#include <pmclog.h> 47#include <signal.h> 48#include <stdarg.h> 49#include <stdint.h> 50#include <stdio.h> --- 54 unchanged lines hidden (view full) --- 105 (void) pmc_configure_logfile(-1); 106 107 if (a->pa_logparser) { 108 pmclog_close(a->pa_logparser); 109 a->pa_logparser = NULL; 110 } 111 112 if (a->pa_flags & (FLAG_HAS_PIPE | FLAG_HAS_OUTPUT_LOGFILE)) | 44#include <limits.h> 45#include <math.h> 46#include <pmc.h> 47#include <pmclog.h> 48#include <signal.h> 49#include <stdarg.h> 50#include <stdint.h> 51#include <stdio.h> --- 54 unchanged lines hidden (view full) --- 106 (void) pmc_configure_logfile(-1); 107 108 if (a->pa_logparser) { 109 pmclog_close(a->pa_logparser); 110 a->pa_logparser = NULL; 111 } 112 113 if (a->pa_flags & (FLAG_HAS_PIPE | FLAG_HAS_OUTPUT_LOGFILE)) |
113 pmcstat_shutdown_logging(); | 114 pmcstat_shutdown_logging(a); |
114} 115 116void 117pmcstat_start_pmcs(struct pmcstat_args *a) 118{ 119 struct pmcstat_ev *ev; 120 121 STAILQ_FOREACH(ev, &args.pa_head, ev_next) { --- 190 unchanged lines hidden (view full) --- 312 errx(EX_USAGE, 313 "[options] [commandline]\n" 314 "\t Measure process and/or system performance using hardware\n" 315 "\t performance monitoring counters.\n" 316 "\t Options include:\n" 317 "\t -C\t\t (toggle) show cumulative counts\n" 318 "\t -D path\t create profiles in directory \"path\"\n" 319 "\t -E\t\t (toggle) show counts at process exit\n" | 115} 116 117void 118pmcstat_start_pmcs(struct pmcstat_args *a) 119{ 120 struct pmcstat_ev *ev; 121 122 STAILQ_FOREACH(ev, &args.pa_head, ev_next) { --- 190 unchanged lines hidden (view full) --- 313 errx(EX_USAGE, 314 "[options] [commandline]\n" 315 "\t Measure process and/or system performance using hardware\n" 316 "\t performance monitoring counters.\n" 317 "\t Options include:\n" 318 "\t -C\t\t (toggle) show cumulative counts\n" 319 "\t -D path\t create profiles in directory \"path\"\n" 320 "\t -E\t\t (toggle) show counts at process exit\n" |
321 "\t -M file\t print executable/gmon file map to \"file\"\n" |
|
320 "\t -O file\t send log output to \"file\"\n" 321 "\t -P spec\t allocate a process-private sampling PMC\n" 322 "\t -R file\t read events from \"file\"\n" 323 "\t -S spec\t allocate a system-wide sampling PMC\n" 324 "\t -W\t\t (toggle) show counts per context switch\n" 325 "\t -c cpu\t\t set cpu for subsequent system-wide PMCs\n" 326 "\t -d\t\t (toggle) track descendants\n" 327 "\t -g\t\t produce gprof(1) compatible profiles\n" | 322 "\t -O file\t send log output to \"file\"\n" 323 "\t -P spec\t allocate a process-private sampling PMC\n" 324 "\t -R file\t read events from \"file\"\n" 325 "\t -S spec\t allocate a system-wide sampling PMC\n" 326 "\t -W\t\t (toggle) show counts per context switch\n" 327 "\t -c cpu\t\t set cpu for subsequent system-wide PMCs\n" 328 "\t -d\t\t (toggle) track descendants\n" 329 "\t -g\t\t produce gprof(1) compatible profiles\n" |
328 "\t -k file\t set the path to the kernel\n" | 330 "\t -k dir\t set the path to the kernel\n" |
329 "\t -n rate\t set sampling rate\n" 330 "\t -o file\t send print output to \"file\"\n" 331 "\t -p spec\t allocate a process-private counting PMC\n" | 331 "\t -n rate\t set sampling rate\n" 332 "\t -o file\t send print output to \"file\"\n" 333 "\t -p spec\t allocate a process-private counting PMC\n" |
334 "\t -q\t\t suppress verbosity\n" 335 "\t -r fsroot\t specify FS root directory\n" |
|
332 "\t -s spec\t allocate a system-wide counting PMC\n" 333 "\t -t pid\t\t attach to running process with pid \"pid\"\n" | 336 "\t -s spec\t allocate a system-wide counting PMC\n" 337 "\t -t pid\t\t attach to running process with pid \"pid\"\n" |
338 "\t -v\t\t increase verbosity\n" |
|
334 "\t -w secs\t set printing time interval" 335 ); 336} 337 338/* 339 * Main 340 */ 341 342int 343main(int argc, char **argv) 344{ 345 double interval; 346 int option, npmc, ncpu; 347 int c, check_driver_stats, current_cpu, current_sampling_count; 348 int do_print, do_descendants; 349 int do_logproccsw, do_logprocexit; 350 int pipefd[2]; 351 int use_cumulative_counts; 352 pid_t pid; | 339 "\t -w secs\t set printing time interval" 340 ); 341} 342 343/* 344 * Main 345 */ 346 347int 348main(int argc, char **argv) 349{ 350 double interval; 351 int option, npmc, ncpu; 352 int c, check_driver_stats, current_cpu, current_sampling_count; 353 int do_print, do_descendants; 354 int do_logproccsw, do_logprocexit; 355 int pipefd[2]; 356 int use_cumulative_counts; 357 pid_t pid; |
353 char *end; | 358 char *end, *tmp; |
354 const char *errmsg; 355 enum pmcstat_state runstate; 356 struct pmc_driverstats ds_start, ds_end; 357 struct pmcstat_ev *ev; 358 struct sigaction sa; 359 struct kevent kev; 360 struct winsize ws; 361 struct stat sb; | 359 const char *errmsg; 360 enum pmcstat_state runstate; 361 struct pmc_driverstats ds_start, ds_end; 362 struct pmcstat_ev *ev; 363 struct sigaction sa; 364 struct kevent kev; 365 struct winsize ws; 366 struct stat sb; |
367 char buffer[PATH_MAX]; |
|
362 363 check_driver_stats = 0; 364 current_cpu = 0; 365 current_sampling_count = DEFAULT_SAMPLE_COUNT; 366 do_descendants = 0; 367 do_logproccsw = 0; 368 do_logprocexit = 0; 369 use_cumulative_counts = 0; 370 args.pa_required = 0; 371 args.pa_flags = 0; | 368 369 check_driver_stats = 0; 370 current_cpu = 0; 371 current_sampling_count = DEFAULT_SAMPLE_COUNT; 372 do_descendants = 0; 373 do_logproccsw = 0; 374 do_logprocexit = 0; 375 use_cumulative_counts = 0; 376 args.pa_required = 0; 377 args.pa_flags = 0; |
378 args.pa_verbosity = 1; |
|
372 args.pa_pid = (pid_t) -1; 373 args.pa_logfd = -1; | 379 args.pa_pid = (pid_t) -1; 380 args.pa_logfd = -1; |
381 args.pa_fsroot = ""; 382 args.pa_kernel = strdup("/boot/kernel"); |
|
374 args.pa_samplesdir = "."; | 383 args.pa_samplesdir = "."; |
375 args.pa_kernel = "/boot/kernel/kernel"; | |
376 args.pa_printfile = stderr; 377 args.pa_interval = DEFAULT_WAIT_INTERVAL; | 384 args.pa_printfile = stderr; 385 args.pa_interval = DEFAULT_WAIT_INTERVAL; |
386 args.pa_mapfilename = NULL; |
|
378 STAILQ_INIT(&args.pa_head); 379 bzero(&ds_start, sizeof(ds_start)); 380 bzero(&ds_end, sizeof(ds_end)); 381 ev = NULL; 382 | 387 STAILQ_INIT(&args.pa_head); 388 bzero(&ds_start, sizeof(ds_start)); 389 bzero(&ds_end, sizeof(ds_end)); 390 ev = NULL; 391 |
383 while ((option = getopt(argc, argv, "CD:EO:P:R:S:Wc:dgk:n:o:p:s:t:w:")) 384 != -1) | 392 while ((option = getopt(argc, argv, 393 "CD:EM:O:P:R:S:Wc:dgk:n:o:p:qr:s:t:vw:")) != -1) |
385 switch (option) { 386 case 'C': /* cumulative values */ 387 use_cumulative_counts = !use_cumulative_counts; 388 args.pa_required |= FLAG_HAS_COUNTING_PMCS; 389 break; 390 391 case 'c': /* CPU */ 392 current_cpu = strtol(optarg, &end, 0); --- 21 unchanged lines hidden (view full) --- 414 args.pa_required |= FLAG_HAS_PROCESS_PMCS; 415 break; 416 417 case 'g': /* produce gprof compatible profiles */ 418 args.pa_flags |= FLAG_DO_GPROF; 419 break; 420 421 case 'k': /* pathname to the kernel */ | 394 switch (option) { 395 case 'C': /* cumulative values */ 396 use_cumulative_counts = !use_cumulative_counts; 397 args.pa_required |= FLAG_HAS_COUNTING_PMCS; 398 break; 399 400 case 'c': /* CPU */ 401 current_cpu = strtol(optarg, &end, 0); --- 21 unchanged lines hidden (view full) --- 423 args.pa_required |= FLAG_HAS_PROCESS_PMCS; 424 break; 425 426 case 'g': /* produce gprof compatible profiles */ 427 args.pa_flags |= FLAG_DO_GPROF; 428 break; 429 430 case 'k': /* pathname to the kernel */ |
422 args.pa_kernel = optarg; | 431 free(args.pa_kernel); 432 args.pa_kernel = strdup(optarg); |
423 args.pa_required |= FLAG_DO_GPROF; 424 args.pa_flags |= FLAG_HAS_KERNELPATH; 425 break; 426 427 case 'E': /* log process exit */ 428 do_logprocexit = !do_logprocexit; 429 args.pa_required |= (FLAG_HAS_PROCESS_PMCS | 430 FLAG_HAS_COUNTING_PMCS | FLAG_HAS_OUTPUT_LOGFILE); 431 break; 432 | 433 args.pa_required |= FLAG_DO_GPROF; 434 args.pa_flags |= FLAG_HAS_KERNELPATH; 435 break; 436 437 case 'E': /* log process exit */ 438 do_logprocexit = !do_logprocexit; 439 args.pa_required |= (FLAG_HAS_PROCESS_PMCS | 440 FLAG_HAS_COUNTING_PMCS | FLAG_HAS_OUTPUT_LOGFILE); 441 break; 442 |
443 case 'M': /* mapfile */ 444 args.pa_mapfilename = optarg; 445 break; 446 |
|
433 case 'p': /* process virtual counting PMC */ 434 case 's': /* system-wide counting PMC */ 435 case 'P': /* process virtual sampling PMC */ 436 case 'S': /* system-wide sampling PMC */ 437 if ((ev = malloc(sizeof(*ev))) == NULL) 438 errx(EX_SOFTWARE, "ERROR: Out of memory."); 439 440 switch (option) { --- 77 unchanged lines hidden (view full) --- 518 case 'O': /* sampling output */ 519 if (args.pa_outputpath) 520 errx(EX_USAGE, "ERROR: option -O may only be " 521 "specified once."); 522 args.pa_outputpath = optarg; 523 args.pa_flags |= FLAG_HAS_OUTPUT_LOGFILE; 524 break; 525 | 447 case 'p': /* process virtual counting PMC */ 448 case 's': /* system-wide counting PMC */ 449 case 'P': /* process virtual sampling PMC */ 450 case 'S': /* system-wide sampling PMC */ 451 if ((ev = malloc(sizeof(*ev))) == NULL) 452 errx(EX_SOFTWARE, "ERROR: Out of memory."); 453 454 switch (option) { --- 77 unchanged lines hidden (view full) --- 532 case 'O': /* sampling output */ 533 if (args.pa_outputpath) 534 errx(EX_USAGE, "ERROR: option -O may only be " 535 "specified once."); 536 args.pa_outputpath = optarg; 537 args.pa_flags |= FLAG_HAS_OUTPUT_LOGFILE; 538 break; 539 |
540 case 'q': /* quiet mode */ 541 args.pa_verbosity = 0; 542 break; 543 544 case 'r': /* root FS path */ 545 args.pa_fsroot = optarg; 546 break; 547 |
|
526 case 'R': /* read an existing log file */ 527 if (args.pa_logparser != NULL) 528 errx(EX_USAGE, "ERROR: option -R may only be " 529 "specified once."); 530 args.pa_inputpath = optarg; 531 if (args.pa_printfile == stderr) 532 args.pa_printfile = stdout; 533 args.pa_flags |= FLAG_READ_LOGFILE; --- 5 unchanged lines hidden (view full) --- 539 errx(EX_USAGE, "ERROR: Illegal pid value " 540 "\"%s\".", optarg); 541 542 args.pa_flags |= FLAG_HAS_PID; 543 args.pa_required |= FLAG_HAS_PROCESS_PMCS; 544 args.pa_pid = pid; 545 break; 546 | 548 case 'R': /* read an existing log file */ 549 if (args.pa_logparser != NULL) 550 errx(EX_USAGE, "ERROR: option -R may only be " 551 "specified once."); 552 args.pa_inputpath = optarg; 553 if (args.pa_printfile == stderr) 554 args.pa_printfile = stdout; 555 args.pa_flags |= FLAG_READ_LOGFILE; --- 5 unchanged lines hidden (view full) --- 561 errx(EX_USAGE, "ERROR: Illegal pid value " 562 "\"%s\".", optarg); 563 564 args.pa_flags |= FLAG_HAS_PID; 565 args.pa_required |= FLAG_HAS_PROCESS_PMCS; 566 args.pa_pid = pid; 567 break; 568 |
569 case 'v': /* verbose */ 570 args.pa_verbosity++; 571 break; 572 |
|
547 case 'w': /* wait interval */ 548 interval = strtod(optarg, &end); 549 if (*end != '\0' || interval <= 0) 550 errx(EX_USAGE, "ERROR: Illegal wait interval " 551 "value \"%s\".", optarg); 552 args.pa_flags |= FLAG_HAS_WAIT_INTERVAL; 553 args.pa_required |= FLAG_HAS_COUNTING_PMCS; 554 args.pa_interval = interval; --- 98 unchanged lines hidden (view full) --- 653 654 /* check if -O was spuriously specified */ 655 if ((args.pa_flags & FLAG_HAS_OUTPUT_LOGFILE) && 656 (args.pa_required & FLAG_HAS_OUTPUT_LOGFILE) == 0) 657 errx(EX_USAGE, 658 "ERROR: option -O is used only with options " 659 "-E, -P, -S and -W."); 660 | 573 case 'w': /* wait interval */ 574 interval = strtod(optarg, &end); 575 if (*end != '\0' || interval <= 0) 576 errx(EX_USAGE, "ERROR: Illegal wait interval " 577 "value \"%s\".", optarg); 578 args.pa_flags |= FLAG_HAS_WAIT_INTERVAL; 579 args.pa_required |= FLAG_HAS_COUNTING_PMCS; 580 args.pa_interval = interval; --- 98 unchanged lines hidden (view full) --- 679 680 /* check if -O was spuriously specified */ 681 if ((args.pa_flags & FLAG_HAS_OUTPUT_LOGFILE) && 682 (args.pa_required & FLAG_HAS_OUTPUT_LOGFILE) == 0) 683 errx(EX_USAGE, 684 "ERROR: option -O is used only with options " 685 "-E, -P, -S and -W."); 686 |
661 /* -D dir and -k kernel path require -g */ | 687 /* -D dir and -k kernel path require -g or -R */ |
662 if ((args.pa_flags & FLAG_HAS_KERNELPATH) && | 688 if ((args.pa_flags & FLAG_HAS_KERNELPATH) && |
663 ((args.pa_flags & FLAG_DO_GPROF) == 0)) 664 errx(EX_USAGE, "ERROR: option -k is only used with -g."); | 689 (args.pa_flags & FLAG_DO_GPROF) == 0 && 690 (args.pa_flags & FLAG_READ_LOGFILE) == 0) 691 errx(EX_USAGE, "ERROR: option -k is only used with -g/-R."); |
665 666 if ((args.pa_flags & FLAG_HAS_SAMPLESDIR) && | 692 693 if ((args.pa_flags & FLAG_HAS_SAMPLESDIR) && |
667 ((args.pa_flags & FLAG_DO_GPROF) == 0)) 668 errx(EX_USAGE, "ERROR: option -D is only used with -g."); | 694 (args.pa_flags & FLAG_DO_GPROF) == 0 && 695 (args.pa_flags & FLAG_READ_LOGFILE) == 0) 696 errx(EX_USAGE, "ERROR: option -D is only used with -g/-R."); |
669 | 697 |
698 /* -M mapfile requires -g or -R */ 699 if (args.pa_mapfilename != NULL && 700 (args.pa_flags & FLAG_DO_GPROF) == 0 && 701 (args.pa_flags & FLAG_READ_LOGFILE) == 0) 702 errx(EX_USAGE, "ERROR: option -M is only used with -g/-R."); 703 |
|
670 /* 671 * Disallow textual output of sampling PMCs if counting PMCs 672 * have also been asked for, mostly because the combined output 673 * is difficult to make sense of. 674 */ 675 if ((args.pa_flags & FLAG_HAS_COUNTING_PMCS) && 676 (args.pa_flags & FLAG_HAS_SAMPLING_PMCS) && 677 ((args.pa_required & FLAG_HAS_OUTPUT_LOGFILE) == 0)) 678 errx(EX_USAGE, "ERROR: option -O is required if counting and " 679 "sampling PMCs are specified together."); 680 | 704 /* 705 * Disallow textual output of sampling PMCs if counting PMCs 706 * have also been asked for, mostly because the combined output 707 * is difficult to make sense of. 708 */ 709 if ((args.pa_flags & FLAG_HAS_COUNTING_PMCS) && 710 (args.pa_flags & FLAG_HAS_SAMPLING_PMCS) && 711 ((args.pa_required & FLAG_HAS_OUTPUT_LOGFILE) == 0)) 712 errx(EX_USAGE, "ERROR: option -O is required if counting and " 713 "sampling PMCs are specified together."); 714 |
715 /* 716 * Check if "-k kerneldir" was specified, and if whether 'kerneldir' 717 * actually refers to a a file. If so, use `dirname path` to determine 718 * the kernel directory. 719 */ 720 if (args.pa_flags & FLAG_HAS_KERNELPATH) { 721 (void) snprintf(buffer, sizeof(buffer), "%s%s", args.pa_fsroot, 722 args.pa_kernel); 723 if (stat(buffer, &sb) < 0) 724 err(EX_OSERR, "ERROR: Cannot locate kernel \"%s\"", 725 buffer); 726 if (!S_ISREG(sb.st_mode) && !S_ISDIR(sb.st_mode)) 727 errx(EX_USAGE, "ERROR: \"%s\": Unsupported file type.", 728 buffer); 729 if (!S_ISDIR(sb.st_mode)) { 730 tmp = args.pa_kernel; 731 args.pa_kernel = strdup(dirname(args.pa_kernel)); 732 free(tmp); 733 (void) snprintf(buffer, sizeof(buffer), "%s%s", 734 args.pa_fsroot, args.pa_kernel); 735 if (stat(buffer, &sb) < 0) 736 err(EX_OSERR, "ERROR: Cannot stat \"%s\"", 737 buffer); 738 if (!S_ISDIR(sb.st_mode)) 739 errx(EX_USAGE, "ERROR: \"%s\" is not a " 740 "directory.", buffer); 741 } 742 } 743 |
|
681 /* if we've been asked to process a log file, do that and exit */ 682 if (args.pa_flags & FLAG_READ_LOGFILE) { 683 /* 684 * Print the log in textual form if we haven't been 685 * asked to generate gmon.out files. 686 */ 687 if ((args.pa_flags & FLAG_DO_GPROF) == 0) 688 args.pa_flags |= FLAG_DO_PRINT; 689 690 pmcstat_initialize_logging(&args); | 744 /* if we've been asked to process a log file, do that and exit */ 745 if (args.pa_flags & FLAG_READ_LOGFILE) { 746 /* 747 * Print the log in textual form if we haven't been 748 * asked to generate gmon.out files. 749 */ 750 if ((args.pa_flags & FLAG_DO_GPROF) == 0) 751 args.pa_flags |= FLAG_DO_PRINT; 752 753 pmcstat_initialize_logging(&args); |
691 if ((args.pa_logfd = pmcstat_open(args.pa_inputpath, | 754 if ((args.pa_logfd = pmcstat_open_log(args.pa_inputpath, |
692 PMCSTAT_OPEN_FOR_READ)) < 0) 693 err(EX_OSERR, "ERROR: Cannot open \"%s\" for " 694 "reading", args.pa_inputpath); 695 if ((args.pa_logparser = pmclog_open(args.pa_logfd)) == NULL) 696 err(EX_OSERR, "ERROR: Cannot create parser"); 697 pmcstat_process_log(&args); | 755 PMCSTAT_OPEN_FOR_READ)) < 0) 756 err(EX_OSERR, "ERROR: Cannot open \"%s\" for " 757 "reading", args.pa_inputpath); 758 if ((args.pa_logparser = pmclog_open(args.pa_logfd)) == NULL) 759 err(EX_OSERR, "ERROR: Cannot create parser"); 760 pmcstat_process_log(&args); |
761 pmcstat_shutdown_logging(&args); |
|
698 exit(EX_OK); 699 } 700 701 /* otherwise, we've been asked to collect data */ 702 if (pmc_init() < 0) 703 err(EX_UNAVAILABLE, 704 "ERROR: Initialization of the pmc(3) library failed"); 705 --- 10 unchanged lines hidden (view full) --- 716 err(EX_OSERR, "ERROR: Cannot allocate kqueue"); 717 718 /* 719 * Configure the specified log file or setup a default log 720 * consumer via a pipe. 721 */ 722 if (args.pa_required & FLAG_HAS_OUTPUT_LOGFILE) { 723 if (args.pa_outputpath) { | 762 exit(EX_OK); 763 } 764 765 /* otherwise, we've been asked to collect data */ 766 if (pmc_init() < 0) 767 err(EX_UNAVAILABLE, 768 "ERROR: Initialization of the pmc(3) library failed"); 769 --- 10 unchanged lines hidden (view full) --- 780 err(EX_OSERR, "ERROR: Cannot allocate kqueue"); 781 782 /* 783 * Configure the specified log file or setup a default log 784 * consumer via a pipe. 785 */ 786 if (args.pa_required & FLAG_HAS_OUTPUT_LOGFILE) { 787 if (args.pa_outputpath) { |
724 if ((args.pa_logfd = pmcstat_open(args.pa_outputpath, | 788 if ((args.pa_logfd = 789 pmcstat_open_log(args.pa_outputpath, |
725 PMCSTAT_OPEN_FOR_WRITE)) < 0) 726 err(EX_OSERR, "ERROR: Cannot open \"%s\" for " 727 "writing", args.pa_outputpath); 728 } else { 729 /* 730 * process the log on the fly by reading it in 731 * through a pipe. 732 */ --- 228 unchanged lines hidden (view full) --- 961 } while (runstate != PMCSTAT_FINISHED); 962 963 /* flush any pending log entries */ 964 if (args.pa_flags & (FLAG_HAS_OUTPUT_LOGFILE | FLAG_HAS_PIPE)) 965 pmc_flush_logfile(); 966 967 pmcstat_cleanup(&args); 968 | 790 PMCSTAT_OPEN_FOR_WRITE)) < 0) 791 err(EX_OSERR, "ERROR: Cannot open \"%s\" for " 792 "writing", args.pa_outputpath); 793 } else { 794 /* 795 * process the log on the fly by reading it in 796 * through a pipe. 797 */ --- 228 unchanged lines hidden (view full) --- 1026 } while (runstate != PMCSTAT_FINISHED); 1027 1028 /* flush any pending log entries */ 1029 if (args.pa_flags & (FLAG_HAS_OUTPUT_LOGFILE | FLAG_HAS_PIPE)) 1030 pmc_flush_logfile(); 1031 1032 pmcstat_cleanup(&args); 1033 |
1034 free(args.pa_kernel); 1035 |
|
969 /* check if the driver lost any samples or events */ 970 if (check_driver_stats) { 971 if (pmc_get_driver_stats(&ds_end) < 0) 972 err(EX_OSERR, "ERROR: Cannot retrieve driver " 973 "statistics"); | 1036 /* check if the driver lost any samples or events */ 1037 if (check_driver_stats) { 1038 if (pmc_get_driver_stats(&ds_end) < 0) 1039 err(EX_OSERR, "ERROR: Cannot retrieve driver " 1040 "statistics"); |
974 if (ds_start.pm_intr_bufferfull != ds_end.pm_intr_bufferfull) | 1041 if (ds_start.pm_intr_bufferfull != ds_end.pm_intr_bufferfull && 1042 args.pa_verbosity > 0) |
975 warnx("WARNING: some samples were dropped. Please " 976 "consider tuning the \"kern.hwpmc.nsamples\" " 977 "tunable."); 978 if (ds_start.pm_buffer_requests_failed != | 1043 warnx("WARNING: some samples were dropped. Please " 1044 "consider tuning the \"kern.hwpmc.nsamples\" " 1045 "tunable."); 1046 if (ds_start.pm_buffer_requests_failed != |
979 ds_end.pm_buffer_requests_failed) | 1047 ds_end.pm_buffer_requests_failed && 1048 args.pa_verbosity > 0) |
980 warnx("WARNING: some events were discarded. Please " 981 "consider tuning the \"kern.hwpmc.nbuffers\" " 982 "tunable."); 983 } 984 985 exit(EX_OK); 986} | 1049 warnx("WARNING: some events were discarded. Please " 1050 "consider tuning the \"kern.hwpmc.nbuffers\" " 1051 "tunable."); 1052 } 1053 1054 exit(EX_OK); 1055} |