1205408Srdivacky/*- 2205408Srdivacky * Copyright (c) 1980, 1992, 1993 3205408Srdivacky * The Regents of the University of California. All rights reserved. 4205408Srdivacky * 5205408Srdivacky * Redistribution and use in source and binary forms, with or without 6205408Srdivacky * modification, are permitted provided that the following conditions 7205408Srdivacky * are met: 8205408Srdivacky * 1. Redistributions of source code must retain the above copyright 9205408Srdivacky * notice, this list of conditions and the following disclaimer. 10205408Srdivacky * 2. Redistributions in binary form must reproduce the above copyright 11205408Srdivacky * notice, this list of conditions and the following disclaimer in the 12205408Srdivacky * documentation and/or other materials provided with the distribution. 13205408Srdivacky * 4. Neither the name of the University nor the names of its contributors 14205408Srdivacky * may be used to endorse or promote products derived from this software 15205408Srdivacky * without specific prior written permission. 16205408Srdivacky * 17249423Sdim * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18218893Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19205408Srdivacky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20205408Srdivacky * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21205408Srdivacky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22205408Srdivacky * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23205408Srdivacky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24218893Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25218893Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26218893Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27226633Sdim * SUCH DAMAGE. 28243830Sdim */ 29243830Sdim 30218893Sdim#if 0 31218893Sdim#ifndef lint 32243830Sdimstatic char sccsid[] = "@(#)pigs.c 8.2 (Berkeley) 9/23/93"; 33218893Sdim#endif /* not lint */ 34218893Sdim#endif 35218893Sdim 36218893Sdim#include <sys/cdefs.h> 37218893Sdim__FBSDID("$FreeBSD$"); 38226633Sdim 39218893Sdim/* 40218893Sdim * Pigs display from Bill Reeves at Lucasfilm 41249423Sdim */ 42234353Sdim 43249423Sdim#include <sys/param.h> 44205408Srdivacky#include <sys/proc.h> 45205408Srdivacky#include <sys/sysctl.h> 46226633Sdim#include <sys/time.h> 47239462Sdim#include <sys/user.h> 48226633Sdim 49226633Sdim#include <curses.h> 50226633Sdim#include <math.h> 51234353Sdim#include <pwd.h> 52234353Sdim#include <stdlib.h> 53234353Sdim 54234353Sdim#include "systat.h" 55234353Sdim#include "extern.h" 56234353Sdim 57234353Sdimint compar(const void *, const void *); 58243830Sdim 59234353Sdimstatic int nproc; 60234353Sdimstatic struct p_times { 61234353Sdim float pt_pctcpu; 62234353Sdim struct kinfo_proc *pt_kp; 63234353Sdim} *pt; 64234353Sdim 65234353Sdimstatic int fscale; 66234353Sdimstatic double lccpu; 67234353Sdim 68234353SdimWINDOW * 69234353Sdimopenpigs(void) 70234353Sdim{ 71234353Sdim return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0)); 72234353Sdim} 73234353Sdim 74234353Sdimvoid 75234353Sdimclosepigs(WINDOW *w) 76234353Sdim{ 77234353Sdim if (w == NULL) 78234353Sdim return; 79234353Sdim wclear(w); 80234353Sdim wrefresh(w); 81234353Sdim delwin(w); 82234353Sdim} 83234353Sdim 84234353Sdimvoid 85234353Sdimshowpigs(void) 86234353Sdim{ 87239462Sdim int i, j, y, k; 88234353Sdim const char *uname, *pname; 89234353Sdim char pidname[30]; 90234353Sdim 91234353Sdim if (pt == NULL) 92234353Sdim return; 93243830Sdim 94243830Sdim qsort(pt, nproc, sizeof (struct p_times), compar); 95249423Sdim y = 1; 96249423Sdim i = nproc; 97249423Sdim if (i > wnd->_maxy-1) 98249423Sdim i = wnd->_maxy-1; 99234353Sdim for (k = 0; i > 0 && pt[k].pt_pctcpu > 0.01; i--, y++, k++) { 100243830Sdim uname = user_from_uid(pt[k].pt_kp->ki_uid, 0); 101234353Sdim pname = pt[k].pt_kp->ki_comm; 102234353Sdim wmove(wnd, y, 0); 103234353Sdim wclrtoeol(wnd); 104234353Sdim mvwaddstr(wnd, y, 0, uname); 105234353Sdim snprintf(pidname, sizeof(pidname), "%10.10s", pname); 106249423Sdim mvwaddstr(wnd, y, 9, pidname); 107249423Sdim wmove(wnd, y, 20); 108234353Sdim for (j = pt[k].pt_pctcpu * 50 + 0.5; j > 0; j--) 109234353Sdim waddch(wnd, 'X'); 110234353Sdim } 111234353Sdim wmove(wnd, y, 0); wclrtobot(wnd); 112234353Sdim} 113234353Sdim 114234353Sdimint 115234353Sdiminitpigs(void) 116234353Sdim{ 117234353Sdim fixpt_t ccpu; 118249423Sdim size_t len; 119249423Sdim int err; 120249423Sdim 121249423Sdim len = sizeof(ccpu); 122243830Sdim err = sysctlbyname("kern.ccpu", &ccpu, &len, NULL, 0); 123234353Sdim if (err || len != sizeof(ccpu)) { 124234353Sdim perror("kern.ccpu"); 125234353Sdim return (0); 126234353Sdim } 127234353Sdim 128243830Sdim len = sizeof(fscale); 129234353Sdim err = sysctlbyname("kern.fscale", &fscale, &len, NULL, 0); 130234353Sdim if (err || len != sizeof(fscale)) { 131226633Sdim perror("kern.fscale"); 132234353Sdim return (0); 133226633Sdim } 134226633Sdim 135234353Sdim lccpu = log((double) ccpu / fscale); 136226633Sdim 137226633Sdim return(1); 138234353Sdim} 139234353Sdim 140226633Sdimvoid 141226633Sdimfetchpigs(void) 142234353Sdim{ 143226633Sdim int i; 144226633Sdim float ftime; 145234353Sdim float *pctp; 146234353Sdim struct kinfo_proc *kpp; 147226633Sdim static int lastnproc = 0; 148234353Sdim 149226633Sdim if ((kpp = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nproc)) == NULL) { 150226633Sdim error("%s", kvm_geterr(kd)); 151234353Sdim if (pt) 152234353Sdim free(pt); 153234353Sdim return; 154226633Sdim } 155234353Sdim if (nproc > lastnproc) { 156205408Srdivacky free(pt); 157205408Srdivacky if ((pt = 158226633Sdim malloc(nproc * sizeof(struct p_times))) == NULL) { 159226633Sdim error("Out of memory"); 160226633Sdim die(0); 161226633Sdim } 162226633Sdim } 163226633Sdim lastnproc = nproc; 164226633Sdim /* 165226633Sdim * calculate %cpu for each proc 166226633Sdim */ 167226633Sdim for (i = 0; i < nproc; i++) { 168205408Srdivacky pt[i].pt_kp = &kpp[i]; 169205408Srdivacky pctp = &pt[i].pt_pctcpu; 170226633Sdim ftime = kpp[i].ki_swtime; 171226633Sdim if (ftime == 0 || (kpp[i].ki_flag & P_INMEM) == 0) 172226633Sdim *pctp = 0; 173226633Sdim else 174226633Sdim *pctp = ((double) kpp[i].ki_pctcpu / 175226633Sdim fscale) / (1.0 - exp(ftime * lccpu)); 176226633Sdim } 177226633Sdim} 178226633Sdim 179226633Sdimvoid 180226633Sdimlabelpigs(void) 181226633Sdim{ 182226633Sdim wmove(wnd, 0, 0); 183226633Sdim wclrtoeol(wnd); 184226633Sdim mvwaddstr(wnd, 0, 20, 185226633Sdim "/0% /10 /20 /30 /40 /50 /60 /70 /80 /90 /100"); 186226633Sdim} 187226633Sdim 188226633Sdimint 189226633Sdimcompar(const void *a, const void *b) 190226633Sdim{ 191226633Sdim return (((const struct p_times *) a)->pt_pctcpu > 192226633Sdim ((const struct p_times *) b)->pt_pctcpu)? -1: 1; 193226633Sdim} 194226633Sdim