18d2fbde5SJustin T. Gibbs /* 28d2fbde5SJustin T. Gibbs * Copyright (c) 1997, 1998 Kenneth D. Merry. 38d2fbde5SJustin T. Gibbs * All rights reserved. 48d2fbde5SJustin T. Gibbs * 58d2fbde5SJustin T. Gibbs * Redistribution and use in source and binary forms, with or without 68d2fbde5SJustin T. Gibbs * modification, are permitted provided that the following conditions 78d2fbde5SJustin T. Gibbs * are met: 88d2fbde5SJustin T. Gibbs * 1. Redistributions of source code must retain the above copyright 98d2fbde5SJustin T. Gibbs * notice, this list of conditions and the following disclaimer. 108d2fbde5SJustin T. Gibbs * 2. Redistributions in binary form must reproduce the above copyright 118d2fbde5SJustin T. Gibbs * notice, this list of conditions and the following disclaimer in the 128d2fbde5SJustin T. Gibbs * documentation and/or other materials provided with the distribution. 138d2fbde5SJustin T. Gibbs * 3. The name of the author may not be used to endorse or promote products 148d2fbde5SJustin T. Gibbs * derived from this software without specific prior written permission. 158d2fbde5SJustin T. Gibbs * 168d2fbde5SJustin T. Gibbs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 178d2fbde5SJustin T. Gibbs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 188d2fbde5SJustin T. Gibbs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 198d2fbde5SJustin T. Gibbs * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 208d2fbde5SJustin T. Gibbs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 218d2fbde5SJustin T. Gibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 228d2fbde5SJustin T. Gibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 238d2fbde5SJustin T. Gibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 248d2fbde5SJustin T. Gibbs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 258d2fbde5SJustin T. Gibbs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 268d2fbde5SJustin T. Gibbs * SUCH DAMAGE. 278d2fbde5SJustin T. Gibbs * 28bcc6a3daSKenneth D. Merry * $Id: iostat.c,v 1.11 1998/09/16 23:14:47 ken Exp $ 298d2fbde5SJustin T. Gibbs */ 308d2fbde5SJustin T. Gibbs /* 318d2fbde5SJustin T. Gibbs * Parts of this program are derived from the original FreeBSD iostat 328d2fbde5SJustin T. Gibbs * program: 338d2fbde5SJustin T. Gibbs */ 34dea673e9SRodney W. Grimes /*- 35dea673e9SRodney W. Grimes * Copyright (c) 1986, 1991, 1993 36dea673e9SRodney W. Grimes * The Regents of the University of California. All rights reserved. 37dea673e9SRodney W. Grimes * 38dea673e9SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 39dea673e9SRodney W. Grimes * modification, are permitted provided that the following conditions 40dea673e9SRodney W. Grimes * are met: 41dea673e9SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 42dea673e9SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 43dea673e9SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 44dea673e9SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 45dea673e9SRodney W. Grimes * documentation and/or other materials provided with the distribution. 46dea673e9SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 47dea673e9SRodney W. Grimes * must display the following acknowledgement: 48dea673e9SRodney W. Grimes * This product includes software developed by the University of 49dea673e9SRodney W. Grimes * California, Berkeley and its contributors. 50dea673e9SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 51dea673e9SRodney W. Grimes * may be used to endorse or promote products derived from this software 52dea673e9SRodney W. Grimes * without specific prior written permission. 53dea673e9SRodney W. Grimes * 54dea673e9SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 55dea673e9SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 56dea673e9SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 57dea673e9SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 58dea673e9SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 59dea673e9SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 60dea673e9SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 61dea673e9SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 62dea673e9SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 63dea673e9SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 64dea673e9SRodney W. Grimes * SUCH DAMAGE. 65dea673e9SRodney W. Grimes */ 668d2fbde5SJustin T. Gibbs /* 678d2fbde5SJustin T. Gibbs * Ideas for the new iostat statistics output modes taken from the NetBSD 688d2fbde5SJustin T. Gibbs * version of iostat: 698d2fbde5SJustin T. Gibbs */ 708d2fbde5SJustin T. Gibbs /* 718d2fbde5SJustin T. Gibbs * Copyright (c) 1996 John M. Vinopal 728d2fbde5SJustin T. Gibbs * All rights reserved. 738d2fbde5SJustin T. Gibbs * 748d2fbde5SJustin T. Gibbs * Redistribution and use in source and binary forms, with or without 758d2fbde5SJustin T. Gibbs * modification, are permitted provided that the following conditions 768d2fbde5SJustin T. Gibbs * are met: 778d2fbde5SJustin T. Gibbs * 1. Redistributions of source code must retain the above copyright 788d2fbde5SJustin T. Gibbs * notice, this list of conditions and the following disclaimer. 798d2fbde5SJustin T. Gibbs * 2. Redistributions in binary form must reproduce the above copyright 808d2fbde5SJustin T. Gibbs * notice, this list of conditions and the following disclaimer in the 818d2fbde5SJustin T. Gibbs * documentation and/or other materials provided with the distribution. 828d2fbde5SJustin T. Gibbs * 3. All advertising materials mentioning features or use of this software 838d2fbde5SJustin T. Gibbs * must display the following acknowledgement: 848d2fbde5SJustin T. Gibbs * This product includes software developed for the NetBSD Project 858d2fbde5SJustin T. Gibbs * by John M. Vinopal. 868d2fbde5SJustin T. Gibbs * 4. The name of the author may not be used to endorse or promote products 878d2fbde5SJustin T. Gibbs * derived from this software without specific prior written permission. 888d2fbde5SJustin T. Gibbs * 898d2fbde5SJustin T. Gibbs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 908d2fbde5SJustin T. Gibbs * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 918d2fbde5SJustin T. Gibbs * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 928d2fbde5SJustin T. Gibbs * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 938d2fbde5SJustin T. Gibbs * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 948d2fbde5SJustin T. Gibbs * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 958d2fbde5SJustin T. Gibbs * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 968d2fbde5SJustin T. Gibbs * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 978d2fbde5SJustin T. Gibbs * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 988d2fbde5SJustin T. Gibbs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 998d2fbde5SJustin T. Gibbs * SUCH DAMAGE. 1008d2fbde5SJustin T. Gibbs */ 101dea673e9SRodney W. Grimes 102dea673e9SRodney W. Grimes 103dea673e9SRodney W. Grimes #include <sys/param.h> 1048d2fbde5SJustin T. Gibbs #include <sys/types.h> 1058d2fbde5SJustin T. Gibbs #include <sys/errno.h> 106dea673e9SRodney W. Grimes #include <sys/dkstat.h> 107dea673e9SRodney W. Grimes 108dea673e9SRodney W. Grimes #include <err.h> 109dea673e9SRodney W. Grimes #include <ctype.h> 110dea673e9SRodney W. Grimes #include <fcntl.h> 111dea673e9SRodney W. Grimes #include <kvm.h> 112dea673e9SRodney W. Grimes #include <stdio.h> 113dea673e9SRodney W. Grimes #include <stdlib.h> 114dea673e9SRodney W. Grimes #include <string.h> 115dea673e9SRodney W. Grimes #include <unistd.h> 1168d2fbde5SJustin T. Gibbs #include <limits.h> 1178d2fbde5SJustin T. Gibbs #include <devstat.h> 118dea673e9SRodney W. Grimes 119dea673e9SRodney W. Grimes struct nlist namelist[] = { 1208d2fbde5SJustin T. Gibbs #define X_TK_NIN 0 121dea673e9SRodney W. Grimes { "_tk_nin" }, 1228d2fbde5SJustin T. Gibbs #define X_TK_NOUT 1 123dea673e9SRodney W. Grimes { "_tk_nout" }, 1248d2fbde5SJustin T. Gibbs #define X_CP_TIME 2 125dea673e9SRodney W. Grimes { "_cp_time" }, 1268d2fbde5SJustin T. Gibbs #define X_HZ 3 127dea673e9SRodney W. Grimes { "_hz" }, 1288d2fbde5SJustin T. Gibbs #define X_STATHZ 4 129dea673e9SRodney W. Grimes { "_stathz" }, 1308d2fbde5SJustin T. Gibbs #define X_END 4 131dea673e9SRodney W. Grimes { NULL }, 132dea673e9SRodney W. Grimes }; 133dea673e9SRodney W. Grimes 1348d2fbde5SJustin T. Gibbs struct statinfo cur, last; 1358d2fbde5SJustin T. Gibbs int num_devices; 1368d2fbde5SJustin T. Gibbs struct device_selection *dev_select; 1378d2fbde5SJustin T. Gibbs int maxshowdevs; 1382fa4aaa0SMatthew Dillon int dflag = 0, Iflag = 0, Cflag = 0, Tflag = 0, oflag = 0, Kflag = 0; 139dea673e9SRodney W. Grimes 140dea673e9SRodney W. Grimes #define nlread(x, v) \ 141dea673e9SRodney W. Grimes kvm_read(kd, namelist[x].n_value, &(v), sizeof(v)) 142dea673e9SRodney W. Grimes 1438d2fbde5SJustin T. Gibbs /* local function declarations */ 1448d2fbde5SJustin T. Gibbs static void usage(void); 1458d2fbde5SJustin T. Gibbs static void phdr(int signo); 1468d2fbde5SJustin T. Gibbs static void devstats(int perf_select); 1478d2fbde5SJustin T. Gibbs static void cpustats(void); 148dea673e9SRodney W. Grimes 1498d2fbde5SJustin T. Gibbs static void 1508d2fbde5SJustin T. Gibbs usage(void) 1518d2fbde5SJustin T. Gibbs { 1528d2fbde5SJustin T. Gibbs /* 1538d2fbde5SJustin T. Gibbs * We also support the following 'traditional' syntax: 1548d2fbde5SJustin T. Gibbs * iostat [drives] [wait [count]] 1558d2fbde5SJustin T. Gibbs * This isn't mentioned in the man page, or the usage statement, 1568d2fbde5SJustin T. Gibbs * but it is supported. 1578d2fbde5SJustin T. Gibbs */ 158bcc6a3daSKenneth D. Merry fprintf(stderr, "usage: iostat [-CdhIKoT?] [-c count] [-M core]" 1598d2fbde5SJustin T. Gibbs " [-n devs] [-N system]\n" 1608d2fbde5SJustin T. Gibbs "\t [-t type,if,pass] [-w wait] [drives]\n"); 1618d2fbde5SJustin T. Gibbs } 162dea673e9SRodney W. Grimes 163dea673e9SRodney W. Grimes int 1648d2fbde5SJustin T. Gibbs main(int argc, char **argv) 165dea673e9SRodney W. Grimes { 1668d2fbde5SJustin T. Gibbs int c; 167dea673e9SRodney W. Grimes register int i; 1688d2fbde5SJustin T. Gibbs int tflag = 0, hflag = 0, cflag = 0, wflag = 0, nflag = 0; 1698d2fbde5SJustin T. Gibbs int count = 0, waittime = 0; 1708d2fbde5SJustin T. Gibbs char *memf = NULL, *nlistf = NULL; 1718d2fbde5SJustin T. Gibbs struct devstat_match *matches; 1728d2fbde5SJustin T. Gibbs int num_matches = 0; 173dea673e9SRodney W. Grimes char errbuf[_POSIX2_LINE_MAX]; 1748d2fbde5SJustin T. Gibbs char *err_str; 1758d2fbde5SJustin T. Gibbs kvm_t *kd; 1768d2fbde5SJustin T. Gibbs int hz, stathz; 1778d2fbde5SJustin T. Gibbs int headercount; 178bcc6a3daSKenneth D. Merry long generation; 1798d2fbde5SJustin T. Gibbs int num_devices_specified; 180bcc6a3daSKenneth D. Merry int num_selected, num_selections; 181bcc6a3daSKenneth D. Merry long select_generation; 1828d2fbde5SJustin T. Gibbs char **specified_devices; 1838d2fbde5SJustin T. Gibbs devstat_select_mode select_mode; 184dea673e9SRodney W. Grimes 1858d2fbde5SJustin T. Gibbs matches = NULL; 1868d2fbde5SJustin T. Gibbs maxshowdevs = 3; 1878d2fbde5SJustin T. Gibbs 188e4d7fe02SKenneth D. Merry while ((c = getopt(argc, argv, "c:CdhIKM:n:N:ot:Tw:?")) != -1) { 1898d2fbde5SJustin T. Gibbs switch(c) { 190dea673e9SRodney W. Grimes case 'c': 1918d2fbde5SJustin T. Gibbs cflag++; 1928d2fbde5SJustin T. Gibbs count = atoi(optarg); 1938d2fbde5SJustin T. Gibbs if (count < 1) 1948d2fbde5SJustin T. Gibbs errx(1, "count %d is < 1", count); 1958d2fbde5SJustin T. Gibbs break; 1968d2fbde5SJustin T. Gibbs case 'C': 1978d2fbde5SJustin T. Gibbs Cflag++; 1988d2fbde5SJustin T. Gibbs break; 1998d2fbde5SJustin T. Gibbs case 'd': 2008d2fbde5SJustin T. Gibbs dflag++; 2018d2fbde5SJustin T. Gibbs break; 2028d2fbde5SJustin T. Gibbs case 'h': 2038d2fbde5SJustin T. Gibbs hflag++; 2048d2fbde5SJustin T. Gibbs break; 2058d2fbde5SJustin T. Gibbs case 'I': 2068d2fbde5SJustin T. Gibbs Iflag++; 207dea673e9SRodney W. Grimes break; 208e4d7fe02SKenneth D. Merry case 'K': 209e4d7fe02SKenneth D. Merry Kflag++; 210e4d7fe02SKenneth D. Merry break; 211dea673e9SRodney W. Grimes case 'M': 212dea673e9SRodney W. Grimes memf = optarg; 213dea673e9SRodney W. Grimes break; 2148d2fbde5SJustin T. Gibbs case 'n': 2158d2fbde5SJustin T. Gibbs nflag++; 2168d2fbde5SJustin T. Gibbs maxshowdevs = atoi(optarg); 2178d2fbde5SJustin T. Gibbs if (maxshowdevs < 0) 2188d2fbde5SJustin T. Gibbs errx(1, "number of devcies %d is < 0", 2198d2fbde5SJustin T. Gibbs maxshowdevs); 2208d2fbde5SJustin T. Gibbs break; 221dea673e9SRodney W. Grimes case 'N': 222dea673e9SRodney W. Grimes nlistf = optarg; 223dea673e9SRodney W. Grimes break; 2248d2fbde5SJustin T. Gibbs case 'o': 2258d2fbde5SJustin T. Gibbs oflag++; 226dea673e9SRodney W. Grimes break; 2278d2fbde5SJustin T. Gibbs case 't': 2288d2fbde5SJustin T. Gibbs tflag++; 2298d2fbde5SJustin T. Gibbs if (buildmatch(optarg, &matches, 2308d2fbde5SJustin T. Gibbs &num_matches) != 0) 2318d2fbde5SJustin T. Gibbs errx(1, "%s", devstat_errbuf); 2328d2fbde5SJustin T. Gibbs break; 2338d2fbde5SJustin T. Gibbs case 'T': 2348d2fbde5SJustin T. Gibbs Tflag++; 2358d2fbde5SJustin T. Gibbs break; 2368d2fbde5SJustin T. Gibbs case 'w': 2378d2fbde5SJustin T. Gibbs wflag++; 2388d2fbde5SJustin T. Gibbs waittime = atoi(optarg); 2398d2fbde5SJustin T. Gibbs if (waittime < 1) 2408d2fbde5SJustin T. Gibbs errx(1, "wait time is < 1"); 2418d2fbde5SJustin T. Gibbs break; 242dea673e9SRodney W. Grimes default: 243dea673e9SRodney W. Grimes usage(); 2448d2fbde5SJustin T. Gibbs exit(1); 2458d2fbde5SJustin T. Gibbs break; 246dea673e9SRodney W. Grimes } 2478d2fbde5SJustin T. Gibbs } 2488d2fbde5SJustin T. Gibbs 249dea673e9SRodney W. Grimes argc -= optind; 250dea673e9SRodney W. Grimes argv += optind; 251dea673e9SRodney W. Grimes 252dea673e9SRodney W. Grimes /* 253dea673e9SRodney W. Grimes * Discard setgid privileges if not the running kernel so that bad 254dea673e9SRodney W. Grimes * guys can't print interesting stuff from kernel memory. 255dea673e9SRodney W. Grimes */ 256dea673e9SRodney W. Grimes if (nlistf != NULL || memf != NULL) 257dea673e9SRodney W. Grimes setgid(getgid()); 258dea673e9SRodney W. Grimes 2598d2fbde5SJustin T. Gibbs /* 2608d2fbde5SJustin T. Gibbs * Make sure that the userland devstat version matches the kernel 2618d2fbde5SJustin T. Gibbs * devstat version. If not, exit and print a message informing 2628d2fbde5SJustin T. Gibbs * the user of his mistake. 2638d2fbde5SJustin T. Gibbs */ 2648d2fbde5SJustin T. Gibbs if (checkversion() < 0) 2658d2fbde5SJustin T. Gibbs errx(1, "%s", devstat_errbuf); 2668d2fbde5SJustin T. Gibbs 2678d2fbde5SJustin T. Gibbs /* 2688d2fbde5SJustin T. Gibbs * Figure out how many devices we should display. 2698d2fbde5SJustin T. Gibbs */ 2708d2fbde5SJustin T. Gibbs if (nflag == 0) { 2718d2fbde5SJustin T. Gibbs if (oflag > 0) { 2728d2fbde5SJustin T. Gibbs if ((dflag > 0) && (Cflag == 0) && (Tflag == 0)) 2738d2fbde5SJustin T. Gibbs maxshowdevs = 5; 2748d2fbde5SJustin T. Gibbs else if ((dflag > 0) && (Tflag > 0) && (Cflag == 0)) 2758d2fbde5SJustin T. Gibbs maxshowdevs = 5; 2768d2fbde5SJustin T. Gibbs else 2778d2fbde5SJustin T. Gibbs maxshowdevs = 4; 2788d2fbde5SJustin T. Gibbs } else { 2798d2fbde5SJustin T. Gibbs if ((dflag > 0) && (Cflag == 0)) 2808d2fbde5SJustin T. Gibbs maxshowdevs = 4; 2818d2fbde5SJustin T. Gibbs else 2828d2fbde5SJustin T. Gibbs maxshowdevs = 3; 2838d2fbde5SJustin T. Gibbs } 2848d2fbde5SJustin T. Gibbs } 2858d2fbde5SJustin T. Gibbs 2868d2fbde5SJustin T. Gibbs /* find out how many devices we have */ 2878d2fbde5SJustin T. Gibbs if ((num_devices = getnumdevs()) < 0) 2888d2fbde5SJustin T. Gibbs err(1, "can't get number of devices"); 2898d2fbde5SJustin T. Gibbs 2908d2fbde5SJustin T. Gibbs cur.dinfo = (struct devinfo *)malloc(sizeof(struct devinfo)); 2918d2fbde5SJustin T. Gibbs last.dinfo = (struct devinfo *)malloc(sizeof(struct devinfo)); 2928d2fbde5SJustin T. Gibbs bzero(cur.dinfo, sizeof(struct devinfo)); 2938d2fbde5SJustin T. Gibbs bzero(last.dinfo, sizeof(struct devinfo)); 2948d2fbde5SJustin T. Gibbs 2958d2fbde5SJustin T. Gibbs /* 2968d2fbde5SJustin T. Gibbs * Grab all the devices. We don't look to see if the list has 2978d2fbde5SJustin T. Gibbs * changed here, since it almost certainly has. We only look for 2988d2fbde5SJustin T. Gibbs * errors. 2998d2fbde5SJustin T. Gibbs */ 3008d2fbde5SJustin T. Gibbs if (getdevs(&cur) == -1) 3018d2fbde5SJustin T. Gibbs errx(1, "%s", devstat_errbuf); 3028d2fbde5SJustin T. Gibbs 3038d2fbde5SJustin T. Gibbs num_devices = cur.dinfo->numdevs; 3048d2fbde5SJustin T. Gibbs generation = cur.dinfo->generation; 3058d2fbde5SJustin T. Gibbs 3068d2fbde5SJustin T. Gibbs /* 3078d2fbde5SJustin T. Gibbs * If the user specified any devices on the command line, see if 3088d2fbde5SJustin T. Gibbs * they are in the list of devices we have now. 3098d2fbde5SJustin T. Gibbs */ 3108d2fbde5SJustin T. Gibbs specified_devices = (char **)malloc(sizeof(char *)); 3118d2fbde5SJustin T. Gibbs for (num_devices_specified = 0; *argv; ++argv) { 3128d2fbde5SJustin T. Gibbs if (isdigit(**argv)) 3138d2fbde5SJustin T. Gibbs break; 3148d2fbde5SJustin T. Gibbs num_devices_specified++; 3158d2fbde5SJustin T. Gibbs specified_devices = (char **)realloc(specified_devices, 3168d2fbde5SJustin T. Gibbs sizeof(char *) * 3178d2fbde5SJustin T. Gibbs num_devices_specified); 3188d2fbde5SJustin T. Gibbs specified_devices[num_devices_specified - 1] = *argv; 3198d2fbde5SJustin T. Gibbs 3208d2fbde5SJustin T. Gibbs } 3212fa4aaa0SMatthew Dillon if (nflag == 0 && maxshowdevs < num_devices_specified) 3222fa4aaa0SMatthew Dillon maxshowdevs = num_devices_specified; 3238d2fbde5SJustin T. Gibbs 3248d2fbde5SJustin T. Gibbs dev_select = NULL; 3258d2fbde5SJustin T. Gibbs 3268d2fbde5SJustin T. Gibbs if ((num_devices_specified == 0) && (num_matches == 0)) 3278d2fbde5SJustin T. Gibbs select_mode = DS_SELECT_ADD; 3288d2fbde5SJustin T. Gibbs else 3298d2fbde5SJustin T. Gibbs select_mode = DS_SELECT_ONLY; 3308d2fbde5SJustin T. Gibbs 3318d2fbde5SJustin T. Gibbs /* 3328d2fbde5SJustin T. Gibbs * At this point, selectdevs will almost surely indicate that the 3338d2fbde5SJustin T. Gibbs * device list has changed, so we don't look for return values of 0 3348d2fbde5SJustin T. Gibbs * or 1. If we get back -1, though, there is an error. 3358d2fbde5SJustin T. Gibbs */ 3368d2fbde5SJustin T. Gibbs if (selectdevs(&dev_select, &num_selected, 3378d2fbde5SJustin T. Gibbs &num_selections, &select_generation, 3388d2fbde5SJustin T. Gibbs generation, cur.dinfo->devices, num_devices, 3398d2fbde5SJustin T. Gibbs matches, num_matches, 3408d2fbde5SJustin T. Gibbs specified_devices, num_devices_specified, 3418d2fbde5SJustin T. Gibbs select_mode, maxshowdevs, hflag) == -1) 3428d2fbde5SJustin T. Gibbs errx(1, "%s", devstat_errbuf); 3438d2fbde5SJustin T. Gibbs 3448d2fbde5SJustin T. Gibbs /* 3458d2fbde5SJustin T. Gibbs * Look for the traditional wait time and count arguments. 3468d2fbde5SJustin T. Gibbs */ 3478d2fbde5SJustin T. Gibbs if (*argv) { 3488d2fbde5SJustin T. Gibbs waittime = atoi(*argv); 3498d2fbde5SJustin T. Gibbs 3508d2fbde5SJustin T. Gibbs /* Let the user know he goofed, but keep going anyway */ 3518d2fbde5SJustin T. Gibbs if (wflag != 0) 3528d2fbde5SJustin T. Gibbs warnx("discarding previous wait interval, using" 3538d2fbde5SJustin T. Gibbs " %d instead", waittime); 3548d2fbde5SJustin T. Gibbs wflag++; 3558d2fbde5SJustin T. Gibbs 3568d2fbde5SJustin T. Gibbs if (*++argv) { 3578d2fbde5SJustin T. Gibbs count = atoi(*argv); 3588d2fbde5SJustin T. Gibbs if (cflag != 0) 3598d2fbde5SJustin T. Gibbs warnx("discarding previous count, using %d" 3608d2fbde5SJustin T. Gibbs " instead", count); 3618d2fbde5SJustin T. Gibbs cflag++; 3628d2fbde5SJustin T. Gibbs } else 3638d2fbde5SJustin T. Gibbs count = -1; 3648d2fbde5SJustin T. Gibbs } 3658d2fbde5SJustin T. Gibbs 3668d2fbde5SJustin T. Gibbs /* 3678d2fbde5SJustin T. Gibbs * If the user specified a count, but not an interval, we default 3688d2fbde5SJustin T. Gibbs * to an interval of 1 second. 3698d2fbde5SJustin T. Gibbs */ 3708d2fbde5SJustin T. Gibbs if ((wflag == 0) && (cflag > 0)) 3718d2fbde5SJustin T. Gibbs waittime = 1; 3728d2fbde5SJustin T. Gibbs 3738d2fbde5SJustin T. Gibbs /* 3748d2fbde5SJustin T. Gibbs * If the user specified a wait time, but not a count, we want to 3758d2fbde5SJustin T. Gibbs * go on ad infinitum. This can be redundant if the user uses the 3768d2fbde5SJustin T. Gibbs * traditional method of specifying the wait, since in that case we 3778d2fbde5SJustin T. Gibbs * already set count = -1 above. Oh well. 3788d2fbde5SJustin T. Gibbs */ 3798d2fbde5SJustin T. Gibbs if ((wflag > 0) && (cflag == 0)) 3808d2fbde5SJustin T. Gibbs count = -1; 3818d2fbde5SJustin T. Gibbs 382dea673e9SRodney W. Grimes kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); 3838d2fbde5SJustin T. Gibbs 384dea673e9SRodney W. Grimes if (kd == 0) 385dea673e9SRodney W. Grimes errx(1, "kvm_openfiles: %s", errbuf); 3868d2fbde5SJustin T. Gibbs 387dea673e9SRodney W. Grimes if (kvm_nlist(kd, namelist) == -1) 388dea673e9SRodney W. Grimes errx(1, "kvm_nlist: %s", kvm_geterr(kd)); 389dea673e9SRodney W. Grimes 390dea673e9SRodney W. Grimes (void)nlread(X_HZ, hz); 391dea673e9SRodney W. Grimes (void)nlread(X_STATHZ, stathz); 392dea673e9SRodney W. Grimes if (stathz) 393dea673e9SRodney W. Grimes hz = stathz; 394dea673e9SRodney W. Grimes 395dea673e9SRodney W. Grimes /* 3968d2fbde5SJustin T. Gibbs * If the user stops the program (control-Z) and then resumes it, 3978d2fbde5SJustin T. Gibbs * print out the header again. 398dea673e9SRodney W. Grimes */ 399dea673e9SRodney W. Grimes (void)signal(SIGCONT, phdr); 400dea673e9SRodney W. Grimes 4018d2fbde5SJustin T. Gibbs for (headercount = 1;;) { 4028d2fbde5SJustin T. Gibbs struct devinfo *tmp_dinfo; 4038d2fbde5SJustin T. Gibbs long tmp; 4048d2fbde5SJustin T. Gibbs double etime; 4058d2fbde5SJustin T. Gibbs 4068d2fbde5SJustin T. Gibbs if (!--headercount) { 407dea673e9SRodney W. Grimes phdr(0); 4088d2fbde5SJustin T. Gibbs headercount = 20; 409dea673e9SRodney W. Grimes } 410dea673e9SRodney W. Grimes (void)kvm_read(kd, namelist[X_TK_NIN].n_value, 411dea673e9SRodney W. Grimes &cur.tk_nin, sizeof(cur.tk_nin)); 412dea673e9SRodney W. Grimes (void)kvm_read(kd, namelist[X_TK_NOUT].n_value, 413dea673e9SRodney W. Grimes &cur.tk_nout, sizeof(cur.tk_nout)); 414dea673e9SRodney W. Grimes (void)kvm_read(kd, namelist[X_CP_TIME].n_value, 415dea673e9SRodney W. Grimes cur.cp_time, sizeof(cur.cp_time)); 4168d2fbde5SJustin T. Gibbs 4178d2fbde5SJustin T. Gibbs tmp_dinfo = last.dinfo; 4188d2fbde5SJustin T. Gibbs last.dinfo = cur.dinfo; 4198d2fbde5SJustin T. Gibbs cur.dinfo = tmp_dinfo; 4208d2fbde5SJustin T. Gibbs 4218d2fbde5SJustin T. Gibbs last.busy_time = cur.busy_time; 4228d2fbde5SJustin T. Gibbs 4238d2fbde5SJustin T. Gibbs /* 4248d2fbde5SJustin T. Gibbs * Here what we want to do is refresh our device stats. 4258d2fbde5SJustin T. Gibbs * getdevs() returns 1 when the device list has changed. 4268d2fbde5SJustin T. Gibbs * If the device list has changed, we want to go through 4278d2fbde5SJustin T. Gibbs * the selection process again, in case a device that we 4288d2fbde5SJustin T. Gibbs * were previously displaying has gone away. 4298d2fbde5SJustin T. Gibbs */ 4308d2fbde5SJustin T. Gibbs switch (getdevs(&cur)) { 4318d2fbde5SJustin T. Gibbs case -1: 4328d2fbde5SJustin T. Gibbs errx(1, "%s", devstat_errbuf); 4338d2fbde5SJustin T. Gibbs break; 4348d2fbde5SJustin T. Gibbs case 1: { 4358d2fbde5SJustin T. Gibbs int retval; 4368d2fbde5SJustin T. Gibbs 4378d2fbde5SJustin T. Gibbs num_devices = cur.dinfo->numdevs; 4388d2fbde5SJustin T. Gibbs generation = cur.dinfo->generation; 4398d2fbde5SJustin T. Gibbs retval = selectdevs(&dev_select, &num_selected, 4408d2fbde5SJustin T. Gibbs &num_selections, &select_generation, 4418d2fbde5SJustin T. Gibbs generation, cur.dinfo->devices, 4428d2fbde5SJustin T. Gibbs num_devices, matches, num_matches, 4438d2fbde5SJustin T. Gibbs specified_devices, 4448d2fbde5SJustin T. Gibbs num_devices_specified, 4458d2fbde5SJustin T. Gibbs select_mode, maxshowdevs, hflag); 4468d2fbde5SJustin T. Gibbs switch(retval) { 4478d2fbde5SJustin T. Gibbs case -1: 4488d2fbde5SJustin T. Gibbs errx(1, "%s", devstat_errbuf); 4498d2fbde5SJustin T. Gibbs break; 4508d2fbde5SJustin T. Gibbs case 1: 4518d2fbde5SJustin T. Gibbs phdr(0); 4528d2fbde5SJustin T. Gibbs headercount = 20; 4538d2fbde5SJustin T. Gibbs break; 4548d2fbde5SJustin T. Gibbs default: 4558d2fbde5SJustin T. Gibbs break; 456dea673e9SRodney W. Grimes } 4578d2fbde5SJustin T. Gibbs break; 4588d2fbde5SJustin T. Gibbs } 4598d2fbde5SJustin T. Gibbs default: 4608d2fbde5SJustin T. Gibbs break; 4618d2fbde5SJustin T. Gibbs } 4628d2fbde5SJustin T. Gibbs 4638d2fbde5SJustin T. Gibbs /* 4648d2fbde5SJustin T. Gibbs * We only want to re-select devices if we're in 'top' 4658d2fbde5SJustin T. Gibbs * mode. This is the only mode where the devices selected 4668d2fbde5SJustin T. Gibbs * could actually change. 4678d2fbde5SJustin T. Gibbs */ 4688d2fbde5SJustin T. Gibbs if (hflag > 0) { 4698d2fbde5SJustin T. Gibbs int retval; 4708d2fbde5SJustin T. Gibbs retval = selectdevs(&dev_select, &num_selected, 4718d2fbde5SJustin T. Gibbs &num_selections, &select_generation, 4728d2fbde5SJustin T. Gibbs generation, cur.dinfo->devices, 4738d2fbde5SJustin T. Gibbs num_devices, matches, num_matches, 4748d2fbde5SJustin T. Gibbs specified_devices, 4758d2fbde5SJustin T. Gibbs num_devices_specified, 4768d2fbde5SJustin T. Gibbs select_mode, maxshowdevs, hflag); 4778d2fbde5SJustin T. Gibbs switch(retval) { 4788d2fbde5SJustin T. Gibbs case -1: 4798d2fbde5SJustin T. Gibbs errx(1,"%s", devstat_errbuf); 4808d2fbde5SJustin T. Gibbs break; 4818d2fbde5SJustin T. Gibbs case 1: 4828d2fbde5SJustin T. Gibbs phdr(0); 4838d2fbde5SJustin T. Gibbs headercount = 20; 4848d2fbde5SJustin T. Gibbs break; 4858d2fbde5SJustin T. Gibbs default: 4868d2fbde5SJustin T. Gibbs break; 4878d2fbde5SJustin T. Gibbs } 4888d2fbde5SJustin T. Gibbs } 4898d2fbde5SJustin T. Gibbs 490dea673e9SRodney W. Grimes tmp = cur.tk_nin; 491dea673e9SRodney W. Grimes cur.tk_nin -= last.tk_nin; 492dea673e9SRodney W. Grimes last.tk_nin = tmp; 493dea673e9SRodney W. Grimes tmp = cur.tk_nout; 494dea673e9SRodney W. Grimes cur.tk_nout -= last.tk_nout; 495dea673e9SRodney W. Grimes last.tk_nout = tmp; 4968d2fbde5SJustin T. Gibbs 4978d2fbde5SJustin T. Gibbs etime = 0.0; 4988d2fbde5SJustin T. Gibbs 4998d2fbde5SJustin T. Gibbs #define X(fld) tmp = cur.fld[i]; cur.fld[i] -= last.fld[i]; last.fld[i] = tmp 5008d2fbde5SJustin T. Gibbs 501dea673e9SRodney W. Grimes for (i = 0; i < CPUSTATES; i++) { 502dea673e9SRodney W. Grimes X(cp_time); 503dea673e9SRodney W. Grimes etime += cur.cp_time[i]; 504dea673e9SRodney W. Grimes } 505dea673e9SRodney W. Grimes if (etime == 0.0) 506dea673e9SRodney W. Grimes etime = 1.0; 507dea673e9SRodney W. Grimes etime /= (float)hz; 5088d2fbde5SJustin T. Gibbs if ((dflag == 0) || (Tflag > 0)) 5098d2fbde5SJustin T. Gibbs printf("%4.0f%5.0f", cur.tk_nin / etime, 5108d2fbde5SJustin T. Gibbs cur.tk_nout/etime); 5118d2fbde5SJustin T. Gibbs devstats(hflag); 5128d2fbde5SJustin T. Gibbs if ((dflag == 0) || (Cflag > 0)) 513dea673e9SRodney W. Grimes cpustats(); 5148d2fbde5SJustin T. Gibbs printf("\n"); 5158d2fbde5SJustin T. Gibbs fflush(stdout); 516dea673e9SRodney W. Grimes 5178d2fbde5SJustin T. Gibbs if (count >= 0 && --count <= 0) 518dea673e9SRodney W. Grimes break; 5198d2fbde5SJustin T. Gibbs 5208d2fbde5SJustin T. Gibbs sleep(waittime); 521dea673e9SRodney W. Grimes } 5228d2fbde5SJustin T. Gibbs 523dea673e9SRodney W. Grimes exit(0); 524dea673e9SRodney W. Grimes } 525dea673e9SRodney W. Grimes 5268d2fbde5SJustin T. Gibbs static void 5278d2fbde5SJustin T. Gibbs phdr(int signo) 528dea673e9SRodney W. Grimes { 529dea673e9SRodney W. Grimes register int i; 5308d2fbde5SJustin T. Gibbs int printed; 531dea673e9SRodney W. Grimes 5328d2fbde5SJustin T. Gibbs if ((dflag == 0) || (Tflag > 0)) 533dea673e9SRodney W. Grimes (void)printf(" tty"); 5348d2fbde5SJustin T. Gibbs for (i = 0, printed=0;(i < num_devices) && (printed < maxshowdevs);i++){ 5358d2fbde5SJustin T. Gibbs int di; 5368d2fbde5SJustin T. Gibbs if ((dev_select[i].selected != 0) 5378d2fbde5SJustin T. Gibbs && (dev_select[i].selected <= maxshowdevs)) { 5388d2fbde5SJustin T. Gibbs di = dev_select[i].position; 5398d2fbde5SJustin T. Gibbs if (oflag > 0) 5408d2fbde5SJustin T. Gibbs (void)printf("%12.6s%d ", 5418d2fbde5SJustin T. Gibbs cur.dinfo->devices[di].device_name, 5428d2fbde5SJustin T. Gibbs cur.dinfo->devices[di].unit_number); 5438d2fbde5SJustin T. Gibbs else 5448d2fbde5SJustin T. Gibbs printf("%15.6s%d ", 5458d2fbde5SJustin T. Gibbs cur.dinfo->devices[di].device_name, 5468d2fbde5SJustin T. Gibbs cur.dinfo->devices[di].unit_number); 5478d2fbde5SJustin T. Gibbs printed++; 5488d2fbde5SJustin T. Gibbs } 5498d2fbde5SJustin T. Gibbs } 5508d2fbde5SJustin T. Gibbs if ((dflag == 0) || (Cflag > 0)) 5518d2fbde5SJustin T. Gibbs (void)printf(" cpu\n"); 5528d2fbde5SJustin T. Gibbs else 5538d2fbde5SJustin T. Gibbs (void)printf("\n"); 5548d2fbde5SJustin T. Gibbs 5558d2fbde5SJustin T. Gibbs if ((dflag == 0) || (Tflag > 0)) 5568d2fbde5SJustin T. Gibbs (void)printf(" tin tout"); 5578d2fbde5SJustin T. Gibbs 5588d2fbde5SJustin T. Gibbs for (i=0, printed = 0;(i < num_devices) && (printed < maxshowdevs);i++){ 5598d2fbde5SJustin T. Gibbs if ((dev_select[i].selected != 0) 5608d2fbde5SJustin T. Gibbs && (dev_select[i].selected <= maxshowdevs)) { 5612fa4aaa0SMatthew Dillon if (oflag > 0) { 5628d2fbde5SJustin T. Gibbs if (Iflag == 0) 563dea673e9SRodney W. Grimes (void)printf(" sps tps msps "); 5648d2fbde5SJustin T. Gibbs else 5658d2fbde5SJustin T. Gibbs (void)printf(" blk xfr msps "); 5662fa4aaa0SMatthew Dillon } else { 5678d2fbde5SJustin T. Gibbs if (Iflag == 0) 5688d2fbde5SJustin T. Gibbs printf(" KB/t tps MB/s "); 5698d2fbde5SJustin T. Gibbs else 5708d2fbde5SJustin T. Gibbs printf(" KB/t xfrs MB "); 5712fa4aaa0SMatthew Dillon } 5728d2fbde5SJustin T. Gibbs printed++; 5738d2fbde5SJustin T. Gibbs } 5748d2fbde5SJustin T. Gibbs } 5758d2fbde5SJustin T. Gibbs if ((dflag == 0) || (Cflag > 0)) 576936d754aSAndrey A. Chernov (void)printf(" us ni sy in id\n"); 5778d2fbde5SJustin T. Gibbs else 5788d2fbde5SJustin T. Gibbs printf("\n"); 5798d2fbde5SJustin T. Gibbs 580dea673e9SRodney W. Grimes } 581dea673e9SRodney W. Grimes 5828d2fbde5SJustin T. Gibbs static void 5838d2fbde5SJustin T. Gibbs devstats(int perf_select) 584dea673e9SRodney W. Grimes { 585dea673e9SRodney W. Grimes register int dn; 5868d2fbde5SJustin T. Gibbs long double transfers_per_second; 5878d2fbde5SJustin T. Gibbs long double kb_per_transfer, mb_per_second; 5888d2fbde5SJustin T. Gibbs u_int64_t total_bytes, total_transfers, total_blocks; 5898d2fbde5SJustin T. Gibbs long double busy_seconds; 5908d2fbde5SJustin T. Gibbs long double total_mb; 5918d2fbde5SJustin T. Gibbs long double blocks_per_second, ms_per_transaction; 592dea673e9SRodney W. Grimes 5938d2fbde5SJustin T. Gibbs /* 5948d2fbde5SJustin T. Gibbs * Calculate elapsed time up front, since it's the same for all 5958d2fbde5SJustin T. Gibbs * devices. 5968d2fbde5SJustin T. Gibbs */ 5978d2fbde5SJustin T. Gibbs busy_seconds = compute_etime(cur.busy_time, last.busy_time); 5988d2fbde5SJustin T. Gibbs 5998d2fbde5SJustin T. Gibbs for (dn = 0; dn < num_devices; dn++) { 6008d2fbde5SJustin T. Gibbs int di; 6018d2fbde5SJustin T. Gibbs 6028d2fbde5SJustin T. Gibbs if (((perf_select == 0) && (dev_select[dn].selected == 0)) 6038d2fbde5SJustin T. Gibbs || (dev_select[dn].selected > maxshowdevs)) 604dea673e9SRodney W. Grimes continue; 605dea673e9SRodney W. Grimes 6068d2fbde5SJustin T. Gibbs di = dev_select[dn].position; 607dea673e9SRodney W. Grimes 6088d2fbde5SJustin T. Gibbs if (compute_stats(&cur.dinfo->devices[di], 6098d2fbde5SJustin T. Gibbs &last.dinfo->devices[di], busy_seconds, 6108d2fbde5SJustin T. Gibbs &total_bytes, &total_transfers, 6118d2fbde5SJustin T. Gibbs &total_blocks, &kb_per_transfer, 6128d2fbde5SJustin T. Gibbs &transfers_per_second, &mb_per_second, 6138d2fbde5SJustin T. Gibbs &blocks_per_second, &ms_per_transaction)!= 0) 6148d2fbde5SJustin T. Gibbs errx(1, "%s", devstat_errbuf); 6158d2fbde5SJustin T. Gibbs 6168d2fbde5SJustin T. Gibbs if (perf_select != 0) { 6178d2fbde5SJustin T. Gibbs dev_select[dn].bytes = total_bytes; 6188d2fbde5SJustin T. Gibbs if ((dev_select[dn].selected == 0) 6198d2fbde5SJustin T. Gibbs || (dev_select[dn].selected > maxshowdevs)) 6208d2fbde5SJustin T. Gibbs continue; 6218d2fbde5SJustin T. Gibbs } 6228d2fbde5SJustin T. Gibbs 6232fa4aaa0SMatthew Dillon if (Kflag) { 6242fa4aaa0SMatthew Dillon int block_size = cur.dinfo->devices[di].block_size; 625e4d7fe02SKenneth D. Merry total_blocks = total_blocks * (block_size ? 626e4d7fe02SKenneth D. Merry block_size : 512) / 1024; 6272fa4aaa0SMatthew Dillon } 6282fa4aaa0SMatthew Dillon 6298d2fbde5SJustin T. Gibbs if (oflag > 0) { 6302fa4aaa0SMatthew Dillon int msdig = (ms_per_transaction < 100.0) ? 1 : 0; 6318d2fbde5SJustin T. Gibbs 6328d2fbde5SJustin T. Gibbs if (Iflag == 0) 6332fa4aaa0SMatthew Dillon printf("%4.0Lf%4.0Lf%5.*Lf ", 6348d2fbde5SJustin T. Gibbs blocks_per_second, 6358d2fbde5SJustin T. Gibbs transfers_per_second, 6362fa4aaa0SMatthew Dillon msdig, 6378d2fbde5SJustin T. Gibbs ms_per_transaction); 638dea673e9SRodney W. Grimes else 6392fa4aaa0SMatthew Dillon printf("%4.1qu%4.1qu%5.*Lf ", 6408d2fbde5SJustin T. Gibbs total_blocks, 6418d2fbde5SJustin T. Gibbs total_transfers, 6422fa4aaa0SMatthew Dillon msdig, 6438d2fbde5SJustin T. Gibbs ms_per_transaction); 6448d2fbde5SJustin T. Gibbs } else { 6458d2fbde5SJustin T. Gibbs if (Iflag == 0) 6468d2fbde5SJustin T. Gibbs printf(" %5.2Lf %3.0Lf %5.2Lf ", 6478d2fbde5SJustin T. Gibbs kb_per_transfer, 6488d2fbde5SJustin T. Gibbs transfers_per_second, 6498d2fbde5SJustin T. Gibbs mb_per_second); 6508d2fbde5SJustin T. Gibbs else { 6518d2fbde5SJustin T. Gibbs total_mb = total_bytes; 6528d2fbde5SJustin T. Gibbs total_mb /= 1024 * 1024; 6538d2fbde5SJustin T. Gibbs 6548d2fbde5SJustin T. Gibbs printf(" %5.2Lf %3.1qu %5.2Lf ", 6558d2fbde5SJustin T. Gibbs kb_per_transfer, 6568d2fbde5SJustin T. Gibbs total_transfers, 6578d2fbde5SJustin T. Gibbs total_mb); 6588d2fbde5SJustin T. Gibbs } 6598d2fbde5SJustin T. Gibbs } 660dea673e9SRodney W. Grimes } 661dea673e9SRodney W. Grimes } 662dea673e9SRodney W. Grimes 6638d2fbde5SJustin T. Gibbs static void 6648d2fbde5SJustin T. Gibbs cpustats(void) 665dea673e9SRodney W. Grimes { 666dea673e9SRodney W. Grimes register int state; 667dea673e9SRodney W. Grimes double time; 668dea673e9SRodney W. Grimes 6698d2fbde5SJustin T. Gibbs time = 0.0; 6708d2fbde5SJustin T. Gibbs 671dea673e9SRodney W. Grimes for (state = 0; state < CPUSTATES; ++state) 672dea673e9SRodney W. Grimes time += cur.cp_time[state]; 673dea673e9SRodney W. Grimes for (state = 0; state < CPUSTATES; ++state) 6748d2fbde5SJustin T. Gibbs printf("%3.0f", 675dea673e9SRodney W. Grimes 100. * cur.cp_time[state] / (time ? time : 1)); 676dea673e9SRodney W. Grimes } 677