19b50d902SRodney W. Grimes /*- 29b50d902SRodney W. Grimes * Copyright (c) 1980, 1992, 1993 39b50d902SRodney W. Grimes * The Regents of the University of California. All rights reserved. 49b50d902SRodney W. Grimes * 59b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 69b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions 79b50d902SRodney W. Grimes * are met: 89b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 99b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 109b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 119b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 129b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution. 139b50d902SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 149b50d902SRodney W. Grimes * must display the following acknowledgement: 159b50d902SRodney W. Grimes * This product includes software developed by the University of 169b50d902SRodney W. Grimes * California, Berkeley and its contributors. 179b50d902SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 189b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 199b50d902SRodney W. Grimes * without specific prior written permission. 209b50d902SRodney W. Grimes * 219b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 229b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 239b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 249b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 259b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 269b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 279b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 289b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 299b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 309b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 319b50d902SRodney W. Grimes * SUCH DAMAGE. 329b50d902SRodney W. Grimes */ 339b50d902SRodney W. Grimes 349ff712b0SMark Murray #include <sys/cdefs.h> 359ff712b0SMark Murray 369ff712b0SMark Murray __FBSDID("$FreeBSD$"); 379ff712b0SMark Murray 389ff712b0SMark Murray #ifdef lint 399ff712b0SMark Murray static const char sccsid[] = "@(#)pigs.c 8.2 (Berkeley) 9/23/93"; 409ff712b0SMark Murray #endif 419b50d902SRodney W. Grimes 429b50d902SRodney W. Grimes /* 439b50d902SRodney W. Grimes * Pigs display from Bill Reeves at Lucasfilm 449b50d902SRodney W. Grimes */ 459b50d902SRodney W. Grimes 469b50d902SRodney W. Grimes #include <sys/param.h> 479b50d902SRodney W. Grimes #include <sys/dkstat.h> 489b50d902SRodney W. Grimes #include <sys/time.h> 4952a28d70SPoul-Henning Kamp #include <sys/user.h> 509b50d902SRodney W. Grimes #include <sys/sysctl.h> 519b50d902SRodney W. Grimes 529b50d902SRodney W. Grimes #include <curses.h> 539b50d902SRodney W. Grimes #include <math.h> 549b50d902SRodney W. Grimes #include <nlist.h> 559b50d902SRodney W. Grimes #include <pwd.h> 569b50d902SRodney W. Grimes #include <stdlib.h> 579b50d902SRodney W. Grimes 589b50d902SRodney W. Grimes #include "extern.h" 599b50d902SRodney W. Grimes #include "systat.h" 609b50d902SRodney W. Grimes 619b50d902SRodney W. Grimes int compar __P((const void *, const void *)); 629b50d902SRodney W. Grimes 639b50d902SRodney W. Grimes static int nproc; 649b50d902SRodney W. Grimes static struct p_times { 659b50d902SRodney W. Grimes float pt_pctcpu; 669b50d902SRodney W. Grimes struct kinfo_proc *pt_kp; 679b50d902SRodney W. Grimes } *pt; 689b50d902SRodney W. Grimes 699b50d902SRodney W. Grimes static long stime[CPUSTATES]; 7036acf3d9SAndrew Gallatin static int fscale; 719b50d902SRodney W. Grimes static double lccpu; 729b50d902SRodney W. Grimes 739b50d902SRodney W. Grimes WINDOW * 749b50d902SRodney W. Grimes openpigs() 759b50d902SRodney W. Grimes { 769b50d902SRodney W. Grimes return (subwin(stdscr, LINES-5-1, 0, 5, 0)); 779b50d902SRodney W. Grimes } 789b50d902SRodney W. Grimes 799b50d902SRodney W. Grimes void 809b50d902SRodney W. Grimes closepigs(w) 819b50d902SRodney W. Grimes WINDOW *w; 829b50d902SRodney W. Grimes { 839b50d902SRodney W. Grimes if (w == NULL) 849b50d902SRodney W. Grimes return; 859b50d902SRodney W. Grimes wclear(w); 869b50d902SRodney W. Grimes wrefresh(w); 879b50d902SRodney W. Grimes delwin(w); 889b50d902SRodney W. Grimes } 899b50d902SRodney W. Grimes 909b50d902SRodney W. Grimes 919b50d902SRodney W. Grimes void 929b50d902SRodney W. Grimes showpigs() 939b50d902SRodney W. Grimes { 949b50d902SRodney W. Grimes register int i, j, y, k; 959b50d902SRodney W. Grimes float total; 969b50d902SRodney W. Grimes int factor; 979ff712b0SMark Murray const char *uname, *pname; 989ff712b0SMark Murray char pidname[30]; 999b50d902SRodney W. Grimes 1009b50d902SRodney W. Grimes if (pt == NULL) 1019b50d902SRodney W. Grimes return; 1029b50d902SRodney W. Grimes /* Accumulate the percent of cpu per user. */ 1039b50d902SRodney W. Grimes total = 0.0; 1049b50d902SRodney W. Grimes for (i = 0; i <= nproc; i++) { 1059b50d902SRodney W. Grimes /* Accumulate the percentage. */ 1069b50d902SRodney W. Grimes total += pt[i].pt_pctcpu; 1079b50d902SRodney W. Grimes } 1089b50d902SRodney W. Grimes 1099b50d902SRodney W. Grimes if (total < 1.0) 1109b50d902SRodney W. Grimes total = 1.0; 1119b50d902SRodney W. Grimes factor = 50.0/total; 1129b50d902SRodney W. Grimes 1139b50d902SRodney W. Grimes qsort(pt, nproc + 1, sizeof (struct p_times), compar); 1149b50d902SRodney W. Grimes y = 1; 1159b50d902SRodney W. Grimes i = nproc + 1; 1163879bee4SPeter Wemm if (i > wnd->_maxy-1) 1173879bee4SPeter Wemm i = wnd->_maxy-1; 1189b50d902SRodney W. Grimes for (k = 0; i > 0 && pt[k].pt_pctcpu > 0.01; i--, y++, k++) { 1199b50d902SRodney W. Grimes if (pt[k].pt_kp == NULL) { 1209b50d902SRodney W. Grimes uname = ""; 1219b50d902SRodney W. Grimes pname = "<idle>"; 1229b50d902SRodney W. Grimes } 1239b50d902SRodney W. Grimes else { 1241f7d2501SKirk McKusick uname = (char *) 1251f7d2501SKirk McKusick user_from_uid(pt[k].pt_kp->ki_uid, 0); 1261f7d2501SKirk McKusick pname = pt[k].pt_kp->ki_comm; 1279b50d902SRodney W. Grimes } 1289b50d902SRodney W. Grimes wmove(wnd, y, 0); 1299b50d902SRodney W. Grimes wclrtoeol(wnd); 1309b50d902SRodney W. Grimes mvwaddstr(wnd, y, 0, uname); 131448b84a0SWarner Losh snprintf(pidname, sizeof(pidname), "%10.10s", pname); 1329b50d902SRodney W. Grimes mvwaddstr(wnd, y, 9, pidname); 1339b50d902SRodney W. Grimes wmove(wnd, y, 20); 1349b50d902SRodney W. Grimes for (j = pt[k].pt_pctcpu*factor + 0.5; j > 0; j--) 1359b50d902SRodney W. Grimes waddch(wnd, 'X'); 1369b50d902SRodney W. Grimes } 1379b50d902SRodney W. Grimes wmove(wnd, y, 0); wclrtobot(wnd); 1389b50d902SRodney W. Grimes } 1399b50d902SRodney W. Grimes 1409b50d902SRodney W. Grimes int 1419b50d902SRodney W. Grimes initpigs() 1429b50d902SRodney W. Grimes { 1439b50d902SRodney W. Grimes fixpt_t ccpu; 14400df2277SRobert Watson size_t len; 14500df2277SRobert Watson int err; 1469b50d902SRodney W. Grimes 14700df2277SRobert Watson len = sizeof(stime); 14800df2277SRobert Watson err = sysctlbyname("kern.cp_time", &stime, &len, NULL, 0); 14900df2277SRobert Watson if (err || len != sizeof(stime)) { 15000df2277SRobert Watson perror("kern.cp_time"); 1519b50d902SRodney W. Grimes return (0); 1529b50d902SRodney W. Grimes } 15300df2277SRobert Watson 15400df2277SRobert Watson len = sizeof(ccpu); 15500df2277SRobert Watson err = sysctlbyname("kern.ccpu", &ccpu, &len, NULL, 0); 15600df2277SRobert Watson if (err || len != sizeof(ccpu)) { 15700df2277SRobert Watson perror("kern.ccpu"); 1589b50d902SRodney W. Grimes return (0); 1599b50d902SRodney W. Grimes } 16000df2277SRobert Watson 16100df2277SRobert Watson len = sizeof(fscale); 16200df2277SRobert Watson err = sysctlbyname("kern.fscale", &fscale, &len, NULL, 0); 16300df2277SRobert Watson if (err || len != sizeof(fscale)) { 16400df2277SRobert Watson perror("kern.fscale"); 16500df2277SRobert Watson return (0); 1669b50d902SRodney W. Grimes } 16700df2277SRobert Watson 1689b50d902SRodney W. Grimes lccpu = log((double) ccpu / fscale); 1699b50d902SRodney W. Grimes 1709b50d902SRodney W. Grimes return(1); 1719b50d902SRodney W. Grimes } 1729b50d902SRodney W. Grimes 1739b50d902SRodney W. Grimes void 1749b50d902SRodney W. Grimes fetchpigs() 1759b50d902SRodney W. Grimes { 1769ff712b0SMark Murray int i; 1779ff712b0SMark Murray float ftime; 1789ff712b0SMark Murray float *pctp; 1799b50d902SRodney W. Grimes struct kinfo_proc *kpp; 1809ff712b0SMark Murray long c_time[CPUSTATES]; 1819b50d902SRodney W. Grimes double t; 1829b50d902SRodney W. Grimes static int lastnproc = 0; 18300df2277SRobert Watson size_t len; 18400df2277SRobert Watson int err; 1859b50d902SRodney W. Grimes 1869b50d902SRodney W. Grimes if ((kpp = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nproc)) == NULL) { 1879b50d902SRodney W. Grimes error("%s", kvm_geterr(kd)); 1889b50d902SRodney W. Grimes if (pt) 1899b50d902SRodney W. Grimes free(pt); 1909b50d902SRodney W. Grimes return; 1919b50d902SRodney W. Grimes } 1929b50d902SRodney W. Grimes if (nproc > lastnproc) { 1939b50d902SRodney W. Grimes free(pt); 1949b50d902SRodney W. Grimes if ((pt = 1959b50d902SRodney W. Grimes malloc((nproc + 1) * sizeof(struct p_times))) == NULL) { 1969b50d902SRodney W. Grimes error("Out of memory"); 1979b50d902SRodney W. Grimes die(0); 1989b50d902SRodney W. Grimes } 1999b50d902SRodney W. Grimes } 2009b50d902SRodney W. Grimes lastnproc = nproc; 2019b50d902SRodney W. Grimes /* 2029b50d902SRodney W. Grimes * calculate %cpu for each proc 2039b50d902SRodney W. Grimes */ 2049b50d902SRodney W. Grimes for (i = 0; i < nproc; i++) { 2059b50d902SRodney W. Grimes pt[i].pt_kp = &kpp[i]; 2069b50d902SRodney W. Grimes pctp = &pt[i].pt_pctcpu; 2079ff712b0SMark Murray ftime = kpp[i].ki_swtime; 2089ff712b0SMark Murray if (ftime == 0 || (kpp[i].ki_sflag & PS_INMEM) == 0) 2099b50d902SRodney W. Grimes *pctp = 0; 2109b50d902SRodney W. Grimes else 2111f7d2501SKirk McKusick *pctp = ((double) kpp[i].ki_pctcpu / 2129ff712b0SMark Murray fscale) / (1.0 - exp(ftime * lccpu)); 2139b50d902SRodney W. Grimes } 2149b50d902SRodney W. Grimes /* 2159b50d902SRodney W. Grimes * and for the imaginary "idle" process 2169b50d902SRodney W. Grimes */ 2179ff712b0SMark Murray len = sizeof(c_time); 2189ff712b0SMark Murray err = sysctlbyname("kern.cp_time", &c_time, &len, NULL, 0); 2199ff712b0SMark Murray if (err || len != sizeof(c_time)) { 22000df2277SRobert Watson perror("kern.cp_time"); 22100df2277SRobert Watson return; 22200df2277SRobert Watson } 2239b50d902SRodney W. Grimes t = 0; 2249b50d902SRodney W. Grimes for (i = 0; i < CPUSTATES; i++) 2259ff712b0SMark Murray t += c_time[i] - stime[i]; 2269b50d902SRodney W. Grimes if (t == 0.0) 2279b50d902SRodney W. Grimes t = 1.0; 2289b50d902SRodney W. Grimes pt[nproc].pt_kp = NULL; 2299ff712b0SMark Murray pt[nproc].pt_pctcpu = (c_time[CP_IDLE] - stime[CP_IDLE]) / t; 2309b50d902SRodney W. Grimes for (i = 0; i < CPUSTATES; i++) 2319ff712b0SMark Murray stime[i] = c_time[i]; 2329b50d902SRodney W. Grimes } 2339b50d902SRodney W. Grimes 2349b50d902SRodney W. Grimes void 2359b50d902SRodney W. Grimes labelpigs() 2369b50d902SRodney W. Grimes { 2379b50d902SRodney W. Grimes wmove(wnd, 0, 0); 2389b50d902SRodney W. Grimes wclrtoeol(wnd); 2399b50d902SRodney W. Grimes mvwaddstr(wnd, 0, 20, 2409b50d902SRodney W. Grimes "/0 /10 /20 /30 /40 /50 /60 /70 /80 /90 /100"); 2419b50d902SRodney W. Grimes } 2429b50d902SRodney W. Grimes 2439b50d902SRodney W. Grimes int 2449b50d902SRodney W. Grimes compar(a, b) 2459b50d902SRodney W. Grimes const void *a, *b; 2469b50d902SRodney W. Grimes { 2479ff712b0SMark Murray return (((const struct p_times *) a)->pt_pctcpu > 2489ff712b0SMark Murray ((const struct p_times *) b)->pt_pctcpu)? -1: 1; 2499b50d902SRodney W. Grimes } 250