18919eed4SGarrett Wollman /*
28919eed4SGarrett Wollman * Copyright 1996 Massachusetts Institute of Technology
38919eed4SGarrett Wollman *
48919eed4SGarrett Wollman * Permission to use, copy, modify, and distribute this software and
58919eed4SGarrett Wollman * its documentation for any purpose and without fee is hereby
68919eed4SGarrett Wollman * granted, provided that both the above copyright notice and this
78919eed4SGarrett Wollman * permission notice appear in all copies, that both the above
88919eed4SGarrett Wollman * copyright notice and this permission notice appear in all
98919eed4SGarrett Wollman * supporting documentation, and that the name of M.I.T. not be used
108919eed4SGarrett Wollman * in advertising or publicity pertaining to distribution of the
118919eed4SGarrett Wollman * software without specific, written prior permission. M.I.T. makes
128919eed4SGarrett Wollman * no representations about the suitability of this software for any
138919eed4SGarrett Wollman * purpose. It is provided "as is" without express or implied
148919eed4SGarrett Wollman * warranty.
158919eed4SGarrett Wollman *
168919eed4SGarrett Wollman * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
178919eed4SGarrett Wollman * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
188919eed4SGarrett Wollman * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
198919eed4SGarrett Wollman * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
208919eed4SGarrett Wollman * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
218919eed4SGarrett Wollman * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
228919eed4SGarrett Wollman * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
238919eed4SGarrett Wollman * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
248919eed4SGarrett Wollman * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
258919eed4SGarrett Wollman * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
268919eed4SGarrett Wollman * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
278919eed4SGarrett Wollman * SUCH DAMAGE.
288919eed4SGarrett Wollman */
298919eed4SGarrett Wollman
308919eed4SGarrett Wollman #include <sys/types.h>
318919eed4SGarrett Wollman #include <sys/ioctl.h>
328919eed4SGarrett Wollman
33*a29cc9a3SAndriy Gapon #include <machine/cpu.h>
348919eed4SGarrett Wollman #include <machine/perfmon.h>
358919eed4SGarrett Wollman
368919eed4SGarrett Wollman #include <stdio.h>
378919eed4SGarrett Wollman #include <stdlib.h>
388919eed4SGarrett Wollman #include <string.h>
398919eed4SGarrett Wollman #include <err.h>
408919eed4SGarrett Wollman #include <unistd.h>
418919eed4SGarrett Wollman #include <fcntl.h>
428919eed4SGarrett Wollman #include <limits.h>
438919eed4SGarrett Wollman #include <errno.h>
448919eed4SGarrett Wollman
458919eed4SGarrett Wollman static int getnum(const char *, int, int);
469018a5cbSBruce Evans static void usage(const char *) __dead2;
478919eed4SGarrett Wollman
488919eed4SGarrett Wollman int
main(int argc,char ** argv)498919eed4SGarrett Wollman main(int argc, char **argv)
508919eed4SGarrett Wollman {
518919eed4SGarrett Wollman int c, fd, num;
528919eed4SGarrett Wollman int loops, i, sleeptime;
539018a5cbSBruce Evans char *cmd;
548919eed4SGarrett Wollman struct pmc pmc;
558919eed4SGarrett Wollman struct pmc_tstamp then, now;
568919eed4SGarrett Wollman struct pmc_data value;
578919eed4SGarrett Wollman quad_t *buf;
588919eed4SGarrett Wollman double total;
598919eed4SGarrett Wollman
608919eed4SGarrett Wollman pmc.pmc_num = 0;
618919eed4SGarrett Wollman pmc.pmc_event = 0;
628919eed4SGarrett Wollman pmc.pmc_unit = 0;
638919eed4SGarrett Wollman pmc.pmc_flags = 0;
648919eed4SGarrett Wollman pmc.pmc_mask = 0;
659018a5cbSBruce Evans cmd = NULL;
668919eed4SGarrett Wollman loops = 50;
678919eed4SGarrett Wollman sleeptime = 0;
688919eed4SGarrett Wollman
699018a5cbSBruce Evans while ((c = getopt(argc, argv, "s:l:uoeiU:m:c:")) != -1) {
708919eed4SGarrett Wollman switch(c) {
718919eed4SGarrett Wollman case 'u':
728919eed4SGarrett Wollman pmc.pmc_flags |= PMCF_USR;
738919eed4SGarrett Wollman break;
748919eed4SGarrett Wollman case 'o':
758919eed4SGarrett Wollman pmc.pmc_flags |= PMCF_OS;
768919eed4SGarrett Wollman break;
778919eed4SGarrett Wollman case 'e':
788919eed4SGarrett Wollman pmc.pmc_flags |= PMCF_E;
798919eed4SGarrett Wollman break;
808919eed4SGarrett Wollman case 'i':
818919eed4SGarrett Wollman pmc.pmc_flags |= PMCF_INV;
828919eed4SGarrett Wollman break;
838919eed4SGarrett Wollman case 'U':
848919eed4SGarrett Wollman pmc.pmc_unit = getnum(optarg, 0, 256);
858919eed4SGarrett Wollman break;
868919eed4SGarrett Wollman case 'm':
878919eed4SGarrett Wollman pmc.pmc_mask = getnum(optarg, 0, 256);
888919eed4SGarrett Wollman break;
898919eed4SGarrett Wollman case 'l':
908919eed4SGarrett Wollman loops = getnum(optarg, 1, INT_MAX - 1);
918919eed4SGarrett Wollman break;
928919eed4SGarrett Wollman case 's':
938919eed4SGarrett Wollman sleeptime = getnum(optarg, 0, INT_MAX - 1);
948919eed4SGarrett Wollman break;
959018a5cbSBruce Evans case 'c':
969018a5cbSBruce Evans cmd = optarg;
979018a5cbSBruce Evans break;
988919eed4SGarrett Wollman default:
998919eed4SGarrett Wollman usage(argv[0]);
1008919eed4SGarrett Wollman }
1018919eed4SGarrett Wollman }
1028919eed4SGarrett Wollman
1038919eed4SGarrett Wollman if (argc - optind != 1)
1048919eed4SGarrett Wollman usage(argv[0]);
1058919eed4SGarrett Wollman
1068919eed4SGarrett Wollman pmc.pmc_event = getnum(argv[optind], 0, 255);
1078919eed4SGarrett Wollman
1088919eed4SGarrett Wollman buf = malloc((loops + 1) * sizeof *buf);
1098919eed4SGarrett Wollman if (!buf)
1108919eed4SGarrett Wollman err(1, "malloc(%lu)", (unsigned long)(loops +1) * sizeof *buf);
1118919eed4SGarrett Wollman
1128919eed4SGarrett Wollman fd = open(_PATH_PERFMON, O_RDWR, 0);
1138919eed4SGarrett Wollman if (fd < 0)
1148919eed4SGarrett Wollman err(1, "open: " _PATH_PERFMON);
1158919eed4SGarrett Wollman
1168919eed4SGarrett Wollman if (ioctl(fd, PMIOSETUP, &pmc) < 0)
1178919eed4SGarrett Wollman err(1, "ioctl(PMIOSETUP)");
1188919eed4SGarrett Wollman
1198919eed4SGarrett Wollman if (ioctl(fd, PMIOTSTAMP, &then) < 0)
1208919eed4SGarrett Wollman err(1, "ioctl(PMIOTSTAMP)");
1218919eed4SGarrett Wollman
1228919eed4SGarrett Wollman num = 0;
1238919eed4SGarrett Wollman if (ioctl(fd, PMIOSTART, &num) < 0)
1248919eed4SGarrett Wollman err(1, "ioctl(PMIOSTART)");
1258919eed4SGarrett Wollman
1268919eed4SGarrett Wollman value.pmcd_num = 0;
1278919eed4SGarrett Wollman for (i = 0; i < loops; i++) {
1288919eed4SGarrett Wollman if (ioctl(fd, PMIOSTOP, &num) < 0)
1298919eed4SGarrett Wollman err(1, "ioctl(PMIOSTOP)");
1308919eed4SGarrett Wollman if (ioctl(fd, PMIOREAD, &value) < 0)
1318919eed4SGarrett Wollman err(1, "ioctl(PMIOREAD)");
1328919eed4SGarrett Wollman buf[i] = value.pmcd_value;
1338919eed4SGarrett Wollman if (ioctl(fd, PMIORESET, &value.pmcd_num) < 0)
1348919eed4SGarrett Wollman err(1, "ioctl(PMIORESET)");
1358919eed4SGarrett Wollman if (ioctl(fd, PMIOSTART, &num) < 0)
1368919eed4SGarrett Wollman err(1, "ioctl(PMIOSTART)");
1379018a5cbSBruce Evans if (sleeptime)
1389018a5cbSBruce Evans sleep(sleeptime);
1399018a5cbSBruce Evans if (cmd)
1409018a5cbSBruce Evans system(cmd);
1418919eed4SGarrett Wollman }
1428919eed4SGarrett Wollman
1438919eed4SGarrett Wollman if (ioctl(fd, PMIOSTOP, &num) < 0)
1448919eed4SGarrett Wollman err(1, "ioctl(PMIOSTOP)");
1458919eed4SGarrett Wollman if (ioctl(fd, PMIOREAD, &value) < 0)
1468919eed4SGarrett Wollman err(1, "ioctl(PMIOREAD)");
1478919eed4SGarrett Wollman buf[i] = value.pmcd_value;
1488919eed4SGarrett Wollman if (ioctl(fd, PMIOTSTAMP, &now) < 0)
1498919eed4SGarrett Wollman err(1, "ioctl(PMIOTSTAMP)");
1508919eed4SGarrett Wollman
1518919eed4SGarrett Wollman total = 0;
1528919eed4SGarrett Wollman for (i = 1; i <= loops; i++) {
1538919eed4SGarrett Wollman printf("%d: %qd\n", i, buf[i]);
1548919eed4SGarrett Wollman total += buf[i];
1558919eed4SGarrett Wollman }
1568919eed4SGarrett Wollman printf("total: %f\nmean: %f\n", total, total / loops);
1578919eed4SGarrett Wollman
1588919eed4SGarrett Wollman printf("clocks (at %d-MHz): %qd\n", now.pmct_rate,
1598919eed4SGarrett Wollman now.pmct_value - then.pmct_value);
1608919eed4SGarrett Wollman
1618919eed4SGarrett Wollman return 0;
1628919eed4SGarrett Wollman }
1638919eed4SGarrett Wollman
1648919eed4SGarrett Wollman static int
getnum(const char * buf,int min,int max)1658919eed4SGarrett Wollman getnum(const char *buf, int min, int max)
1668919eed4SGarrett Wollman {
1678919eed4SGarrett Wollman char *ep;
1688919eed4SGarrett Wollman long l;
1698919eed4SGarrett Wollman
1708919eed4SGarrett Wollman errno = 0;
1718919eed4SGarrett Wollman l = strtol(buf, &ep, 0);
1728919eed4SGarrett Wollman if (*buf && !*ep && !errno) {
1738919eed4SGarrett Wollman if (l < min || l > max) {
174258c09afSKevin Lo errx(1, "%s: must be between %d and %d",
1758919eed4SGarrett Wollman buf, min, max);
1768919eed4SGarrett Wollman }
1778919eed4SGarrett Wollman return (int)l;
1788919eed4SGarrett Wollman }
179258c09afSKevin Lo
180258c09afSKevin Lo errx(1, "%s: parameter must be an integer", buf);
1818919eed4SGarrett Wollman }
1828919eed4SGarrett Wollman
1838919eed4SGarrett Wollman static void
usage(const char * pname)1848919eed4SGarrett Wollman usage(const char *pname)
1858919eed4SGarrett Wollman {
1868919eed4SGarrett Wollman fprintf(stderr,
1879018a5cbSBruce Evans "usage: %s [-eiou] [-c command] [-l nloops] [-m mask] [-s sleeptime]\n"
1889018a5cbSBruce Evans " [-U unit] counter\n",
1899018a5cbSBruce Evans pname);
1908919eed4SGarrett Wollman exit(1);
1918919eed4SGarrett Wollman }
192