aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/pmcstat/pmcstat.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/pmcstat/pmcstat.c')
-rw-r--r--usr.sbin/pmcstat/pmcstat.c162
1 files changed, 14 insertions, 148 deletions
diff --git a/usr.sbin/pmcstat/pmcstat.c b/usr.sbin/pmcstat/pmcstat.c
index b87444339600..853acc6dd11f 100644
--- a/usr.sbin/pmcstat/pmcstat.c
+++ b/usr.sbin/pmcstat/pmcstat.c
@@ -64,6 +64,8 @@ __FBSDID("$FreeBSD$");
#include <sysexits.h>
#include <unistd.h>
+#include <libpmcstat.h>
+
#include "pmcstat.h"
/*
@@ -114,38 +116,6 @@ static struct kinfo_proc *pmcstat_plist;
struct pmcstat_args args;
static void
-pmcstat_clone_event_descriptor(struct pmcstat_ev *ev, const cpuset_t *cpumask)
-{
- int cpu;
- struct pmcstat_ev *ev_clone;
-
- for (cpu = 0; cpu < CPU_SETSIZE; cpu++) {
- if (!CPU_ISSET(cpu, cpumask))
- continue;
-
- if ((ev_clone = malloc(sizeof(*ev_clone))) == NULL)
- errx(EX_SOFTWARE, "ERROR: Out of memory");
- (void) memset(ev_clone, 0, sizeof(*ev_clone));
-
- ev_clone->ev_count = ev->ev_count;
- ev_clone->ev_cpu = cpu;
- ev_clone->ev_cumulative = ev->ev_cumulative;
- ev_clone->ev_flags = ev->ev_flags;
- ev_clone->ev_mode = ev->ev_mode;
- ev_clone->ev_name = strdup(ev->ev_name);
- if (ev_clone->ev_name == NULL)
- errx(EX_SOFTWARE, "ERROR: Out of memory");
- ev_clone->ev_pmcid = ev->ev_pmcid;
- ev_clone->ev_saved = ev->ev_saved;
- ev_clone->ev_spec = strdup(ev->ev_spec);
- if (ev_clone->ev_spec == NULL)
- errx(EX_SOFTWARE, "ERROR: Out of memory");
-
- STAILQ_INSERT_TAIL(&args.pa_events, ev_clone, ev_next);
- }
-}
-
-static void
pmcstat_get_cpumask(const char *cpuspec, cpuset_t *cpumask)
{
int cpu;
@@ -168,32 +138,6 @@ pmcstat_get_cpumask(const char *cpuspec, cpuset_t *cpumask)
}
void
-pmcstat_attach_pmcs(void)
-{
- struct pmcstat_ev *ev;
- struct pmcstat_target *pt;
- int count;
-
- /* Attach all process PMCs to target processes. */
- count = 0;
- STAILQ_FOREACH(ev, &args.pa_events, ev_next) {
- if (PMC_IS_SYSTEM_MODE(ev->ev_mode))
- continue;
- SLIST_FOREACH(pt, &args.pa_targets, pt_next)
- if (pmc_attach(ev->ev_pmcid, pt->pt_pid) == 0)
- count++;
- else if (errno != ESRCH)
- err(EX_OSERR,
-"ERROR: cannot attach pmc \"%s\" to process %d",
- ev->ev_name, (int)pt->pt_pid);
- }
-
- if (count == 0)
- errx(EX_DATAERR, "ERROR: No processes were attached to.");
-}
-
-
-void
pmcstat_cleanup(void)
{
struct pmcstat_ev *ev;
@@ -220,66 +164,7 @@ pmcstat_cleanup(void)
args.pa_logparser = NULL;
}
- pmcstat_shutdown_logging();
-}
-
-void
-pmcstat_create_process(void)
-{
- char token;
- pid_t pid;
- struct kevent kev;
- struct pmcstat_target *pt;
-
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, pmcstat_sockpair) < 0)
- err(EX_OSERR, "ERROR: cannot create socket pair");
-
- switch (pid = fork()) {
- case -1:
- err(EX_OSERR, "ERROR: cannot fork");
- /*NOTREACHED*/
-
- case 0: /* child */
- (void) close(pmcstat_sockpair[PARENTSOCKET]);
-
- /* Write a token to tell our parent we've started executing. */
- if (write(pmcstat_sockpair[CHILDSOCKET], "+", 1) != 1)
- err(EX_OSERR, "ERROR (child): cannot write token");
-
- /* Wait for our parent to signal us to start. */
- if (read(pmcstat_sockpair[CHILDSOCKET], &token, 1) < 0)
- err(EX_OSERR, "ERROR (child): cannot read token");
- (void) close(pmcstat_sockpair[CHILDSOCKET]);
-
- /* exec() the program requested */
- execvp(*args.pa_argv, args.pa_argv);
- /* and if that fails, notify the parent */
- kill(getppid(), SIGCHLD);
- err(EX_OSERR, "ERROR: execvp \"%s\" failed", *args.pa_argv);
- /*NOTREACHED*/
-
- default: /* parent */
- (void) close(pmcstat_sockpair[CHILDSOCKET]);
- break;
- }
-
- /* Ask to be notified via a kevent when the target process exits. */
- EV_SET(&kev, pid, EVFILT_PROC, EV_ADD|EV_ONESHOT, NOTE_EXIT, 0,
- NULL);
- if (kevent(pmcstat_kq, &kev, 1, NULL, 0, NULL) < 0)
- err(EX_OSERR, "ERROR: cannot monitor child process %d", pid);
-
- if ((pt = malloc(sizeof(*pt))) == NULL)
- errx(EX_SOFTWARE, "ERROR: Out of memory.");
-
- pt->pt_pid = pid;
- SLIST_INSERT_HEAD(&args.pa_targets, pt, pt_next);
-
- /* Wait for the child to signal that its ready to go. */
- if (read(pmcstat_sockpair[PARENTSOCKET], &token, 1) < 0)
- err(EX_OSERR, "ERROR (parent): cannot read token");
-
- return;
+ pmcstat_log_shutdown_logging();
}
void
@@ -377,7 +262,6 @@ pmcstat_start_pmcs(void)
exit(EX_OSERR);
}
}
-
}
void
@@ -465,24 +349,6 @@ pmcstat_print_pmcs(void)
return;
}
-/*
- * Do process profiling
- *
- * If a pid was specified, attach each allocated PMC to the target
- * process. Otherwise, fork a child and attach the PMCs to the child,
- * and have the child exec() the target program.
- */
-
-void
-pmcstat_start_process(void)
-{
- /* Signal the child to proceed. */
- if (write(pmcstat_sockpair[PARENTSOCKET], "!", 1) != 1)
- err(EX_OSERR, "ERROR (parent): write of token failed");
-
- (void) close(pmcstat_sockpair[PARENTSOCKET]);
-}
-
void
pmcstat_show_usage(void)
{
@@ -772,7 +638,7 @@ main(int argc, char **argv)
if (option == 's' || option == 'S')
args.pa_flags |= FLAG_HAS_SYSTEM_PMCS;
- ev->ev_spec = strdup(optarg);
+ ev->ev_spec = strdup(optarg);
if (ev->ev_spec == NULL)
errx(EX_SOFTWARE, "ERROR: Out of memory.");
@@ -813,7 +679,7 @@ main(int argc, char **argv)
if (option == 's' || option == 'S') {
CPU_CLR(ev->ev_cpu, &cpumask);
- pmcstat_clone_event_descriptor(ev, &cpumask);
+ pmcstat_clone_event_descriptor(ev, &cpumask, &args);
CPU_SET(ev->ev_cpu, &cpumask);
}
@@ -1157,7 +1023,7 @@ main(int argc, char **argv)
if ((args.pa_flags & FLAG_DO_ANALYSIS) == 0)
args.pa_flags |= FLAG_DO_PRINT;
- pmcstat_initialize_logging();
+ pmcstat_log_initialize_logging();
rfd = pmcstat_open_log(args.pa_inputpath,
PMCSTAT_OPEN_FOR_READ);
if ((args.pa_logparser = pmclog_open(rfd)) == NULL)
@@ -1333,7 +1199,7 @@ main(int argc, char **argv)
/* attach PMCs to the target process, starting it if specified */
if (args.pa_flags & FLAG_HAS_COMMANDLINE)
- pmcstat_create_process();
+ pmcstat_create_process(pmcstat_sockpair, &args, pmcstat_kq);
if (check_driver_stats && pmc_get_driver_stats(&ds_start) < 0)
err(EX_OSERR, "ERROR: Cannot retrieve driver statistics");
@@ -1344,7 +1210,7 @@ main(int argc, char **argv)
errx(EX_DATAERR,
"ERROR: No matching target processes.");
if (args.pa_flags & FLAG_HAS_PROCESS_PMCS)
- pmcstat_attach_pmcs();
+ pmcstat_attach_pmcs(&args);
if (pmcstat_kvm) {
kvm_close(pmcstat_kvm);
@@ -1357,10 +1223,10 @@ main(int argc, char **argv)
/* start the (commandline) process if needed */
if (args.pa_flags & FLAG_HAS_COMMANDLINE)
- pmcstat_start_process();
+ pmcstat_start_process(pmcstat_sockpair);
/* initialize logging */
- pmcstat_initialize_logging();
+ pmcstat_log_initialize_logging();
/* Handle SIGINT using the kqueue loop */
sa.sa_handler = SIG_IGN;
@@ -1424,7 +1290,7 @@ main(int argc, char **argv)
switch (kev.filter) {
case EVFILT_PROC: /* target has exited */
- runstate = pmcstat_close_log();
+ runstate = pmcstat_close_log(&args);
do_print = 1;
break;
@@ -1432,7 +1298,7 @@ main(int argc, char **argv)
if (kev.ident == (unsigned)fileno(stdin) &&
(args.pa_flags & FLAG_DO_TOP)) {
if (pmcstat_keypress_log())
- runstate = pmcstat_close_log();
+ runstate = pmcstat_close_log(&args);
} else {
do_read = 0;
runstate = pmcstat_process_log();
@@ -1455,13 +1321,13 @@ main(int argc, char **argv)
* of its targets, or if logfile
* writes encounter an error.
*/
- runstate = pmcstat_close_log();
+ runstate = pmcstat_close_log(&args);
do_print = 1; /* print PMCs at exit */
} else if (kev.ident == SIGINT) {
/* Kill the child process if we started it */
if (args.pa_flags & FLAG_HAS_COMMANDLINE)
pmcstat_kill_process();
- runstate = pmcstat_close_log();
+ runstate = pmcstat_close_log(&args);
} else if (kev.ident == SIGWINCH) {
if (ioctl(fileno(args.pa_printfile),
TIOCGWINSZ, &ws) < 0)