Module Name:    src
Committed By:   maxv
Date:           Fri Jul 13 09:04:31 UTC 2018

Modified Files:
        src/usr.sbin/tprof: tprof.8 tprof.c

Log Message:
Change the arguments of the tprof tool, to match the behavior of pmc(1) and
cpuctl(8). They become:

        tprof list
        tprof monitor -e name:option [-o outfile] command


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/usr.sbin/tprof/tprof.8
cvs rdiff -u -r1.6 -r1.7 src/usr.sbin/tprof/tprof.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.sbin/tprof/tprof.8
diff -u src/usr.sbin/tprof/tprof.8:1.4 src/usr.sbin/tprof/tprof.8:1.5
--- src/usr.sbin/tprof/tprof.8:1.4	Fri Jul 13 07:56:29 2018
+++ src/usr.sbin/tprof/tprof.8	Fri Jul 13 09:04:31 2018
@@ -1,4 +1,4 @@
-.\"	$NetBSD: tprof.8,v 1.4 2018/07/13 07:56:29 maxv Exp $
+.\"	$NetBSD: tprof.8,v 1.5 2018/07/13 09:04:31 maxv Exp $
 .\"
 .\" Copyright (c)2011 YAMAMOTO Takashi,
 .\" All rights reserved.
@@ -32,16 +32,15 @@
 .Nd record tprof profiling samples
 .Sh SYNOPSIS
 .Nm
-.Op Fl l
-.Op Fl e Ar name:option
-.Op Fl c
-.Op Fl o Ar file
-.Ar command ...
+.Ar op
+.Op Ar arguments
 .Sh DESCRIPTION
 The
 .Nm
-is a sampling based profiler.
+tool can be used to monitor hardware events (PMCs) during the execution of
+certain commands.
 .Pp
+The
 .Nm
 utility makes the kernel driver start profiling,
 executes the specified command,
@@ -55,10 +54,21 @@ pseudo driver and a suitable backend sho
 The
 .Nm
 utility accepts the following options.
-.Bl -tag -width hogehoge
-.It Fl l
+The first argument,
+.Ar op ,
+specifies the action to take.
+Valid actions are:
+.Bl -tag -width offline
+.It list
 Display a list of performance counter events available on the system.
-.It Fl e Ar name:option
+.It monitor Xo
+.Fl e
+.Ar name:option
+.Op Fl o Ar outfile
+.Ar command
+.Xc
+Monitor the execution of command
+.Ar command .
 .Ar name
 specifies the name of the event to count; it must be taken from the list of
 available events.
@@ -68,20 +78,16 @@ specifies the source of the event; it mu
 (userland) and
 .Ar k
 (kernel).
-.It Fl o Ar file
-Write the collected samples to the file named
-.Ar file .
+The collected samples are written into the file
+.Ar outfile
+if specified.
 The default is
 .Dq Pa tprof.out .
-.It Fl c
-Write the collected samples to the standard output.
-Note that the output is a binary stream.
 .El
 .Sh EXAMPLES
-The following command profiles the system during 1 second and shows
-the top-10 kernel functions which likely caused LLC misses.
-.Bd -literal
-	tprof -e llc-misses:k -c sleep 1 2>/dev/null | tpfmt -skCLP | head -10
+The following command profiles the system during 20 seconds and writes the
+samples into the file myfile.out.
+.Dl # tprof monitor -e llc-misses:k -o myfile.out sleep 20
 .Ed
 .Sh DIAGNOSTICS
 The

Index: src/usr.sbin/tprof/tprof.c
diff -u src/usr.sbin/tprof/tprof.c:1.6 src/usr.sbin/tprof/tprof.c:1.7
--- src/usr.sbin/tprof/tprof.c:1.6	Fri Jul 13 07:56:29 2018
+++ src/usr.sbin/tprof/tprof.c	Fri Jul 13 09:04:31 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: tprof.c,v 1.6 2018/07/13 07:56:29 maxv Exp $	*/
+/*	$NetBSD: tprof.c,v 1.7 2018/07/13 09:04:31 maxv Exp $	*/
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: tprof.c,v 1.6 2018/07/13 07:56:29 maxv Exp $");
+__RCSID("$NetBSD: tprof.c,v 1.7 2018/07/13 09:04:31 maxv Exp $");
 #endif /* not lint */
 
 #include <sys/ioctl.h>
@@ -83,20 +83,31 @@ __RCSID("$NetBSD: tprof.c,v 1.6 2018/07/
 int devfd;
 int outfd;
 
+static void tprof_list(int, char **);
+static void tprof_monitor(int, char **);
+
+static struct cmdtab {
+	const char *label;
+	bool takesargs;
+	bool argsoptional;
+	void (*func)(int, char **);
+} const tprof_cmdtab[] = {
+	{ "list",	false, false, tprof_list },
+	{ "monitor",	true,  false, tprof_monitor },
+	{ NULL,		false, false, NULL },
+};
+
 __dead static void
 usage(void)
 {
 
-	fprintf(stderr, "%s [options] command ...\n", getprogname());
+	fprintf(stderr, "%s [op] [options] [command]\n", getprogname());
 	fprintf(stderr, "\n");
-	fprintf(stderr, "-e name:{u}{k}\t"
-	    "the event to count.\n");
-	fprintf(stderr, "-l\t\t"
-	    "list the events.\n");
-	fprintf(stderr, "-o filename\t"
-	    "output to the file.  [default: -o tprof.out]\n");
-	fprintf(stderr, "-c\t\t"
-	    "output to stdout.  NOTE: the output is a binary stream.\n");
+	fprintf(stderr, "\tlist\n");
+	fprintf(stderr, "\t\tList the available events.\n");
+	fprintf(stderr, "\tmonitor -e name:option [-o outfile] command\n");
+	fprintf(stderr, "\t\tMonitor the event 'name' with option 'option'\n"
+	    "\t\tcounted during the execution of 'command'.\n");
 
 	exit(EXIT_FAILURE);
 }
@@ -132,48 +143,27 @@ process_samples(void *dummy)
 	return NULL;
 }
 
-int
-main(int argc, char *argv[])
+static void
+tprof_list(int argc, char **argv)
 {
+	tprof_event_list();
+}
+
+static void
+tprof_monitor(int argc, char **argv)
+{
+	const char *outfile = "tprof.out";
 	struct tprof_param param;
-	struct tprof_info info;
 	struct tprof_stat ts;
-	const char *outfile = "tprof.out";
-	bool cflag = false;
 	pid_t pid;
 	pthread_t pt;
-	int error;
-	int ret;
-	int ch;
+	int ret, ch;
 	char *tokens[2];
 
 	memset(&param, 0, sizeof(param));
 
-	devfd = open(_PATH_TPROF, O_RDWR);
-	if (devfd == -1) {
-		err(EXIT_FAILURE, "%s", _PATH_TPROF);
-	}
-
-	ret = ioctl(devfd, TPROF_IOC_GETINFO, &info);
-	if (ret == -1) {
-		err(EXIT_FAILURE, "TPROF_IOC_GETINFO");
-	}
-	if (info.ti_version != TPROF_VERSION) {
-		errx(EXIT_FAILURE, "version mismatch: version=%d, expected=%d",
-		    info.ti_version, TPROF_VERSION);
-	}
-	if (tprof_event_init(info.ti_ident) == -1) {
-		err(EXIT_FAILURE, "cpu not supported");
-	}
-
-	while ((ch = getopt(argc, argv, "clo:e:")) != -1) {
+	while ((ch = getopt(argc, argv, "o:e:")) != -1) {
 		switch (ch) {
-		case 'c':
-			cflag = true;
-			break;
-		case 'l':
-			tprof_event_list();
-			return 0;
 		case 'o':
 			outfile = optarg;
 			break;
@@ -202,13 +192,9 @@ main(int argc, char *argv[])
 		usage();
 	}
 
-	if (cflag) {
-		outfd = STDOUT_FILENO;
-	} else {
-		outfd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
-		if (outfd == -1) {
-			err(EXIT_FAILURE, "%s", outfile);
-		}
+	outfd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+	if (outfd == -1) {
+		err(EXIT_FAILURE, "%s", outfile);
 	}
 
 	ret = ioctl(devfd, TPROF_IOC_START, &param);
@@ -228,9 +214,9 @@ main(int argc, char *argv[])
 
 	signal(SIGINT, SIG_IGN);
 
-	error = pthread_create(&pt, NULL, process_samples, NULL);
-	if (error != 0) {
-		errx(1, "pthread_create: %s", strerror(error));
+	ret = pthread_create(&pt, NULL, process_samples, NULL);
+	if (ret != 0) {
+		errx(1, "pthread_create: %s", strerror(ret));
 	}
 
 	for (;;) {
@@ -270,3 +256,43 @@ main(int argc, char *argv[])
 
 	exit(EXIT_SUCCESS);
 }
+
+int
+main(int argc, char *argv[])
+{
+	struct tprof_info info;
+	const struct cmdtab *ct;
+	int ret;
+
+	setprogname(argv[0]);
+	argv += 1, argc -= 1;
+
+	devfd = open(_PATH_TPROF, O_RDWR);
+	if (devfd == -1) {
+		err(EXIT_FAILURE, "%s", _PATH_TPROF);
+	}
+
+	ret = ioctl(devfd, TPROF_IOC_GETINFO, &info);
+	if (ret == -1) {
+		err(EXIT_FAILURE, "TPROF_IOC_GETINFO");
+	}
+	if (info.ti_version != TPROF_VERSION) {
+		errx(EXIT_FAILURE, "version mismatch: version=%d, expected=%d",
+		    info.ti_version, TPROF_VERSION);
+	}
+	if (tprof_event_init(info.ti_ident) == -1) {
+		err(EXIT_FAILURE, "cpu not supported");
+	}
+
+	for (ct = tprof_cmdtab; ct->label != NULL; ct++) {
+		if (strcmp(argv[0], ct->label) == 0) {
+			if (!ct->argsoptional &&
+			    ((ct->takesargs == 0) ^ (argv[1] == NULL)))
+			{
+				usage();
+			}
+			(*ct->func)(argc, argv);
+			break;
+		}
+	}
+}

Reply via email to