vmstat.c revision 12805
11590Srgrimes/*- 21590Srgrimes * Copyright (c) 1983, 1989, 1992, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 3. All advertising materials mentioning features or use of this software 141590Srgrimes * must display the following acknowledgement: 151590Srgrimes * This product includes software developed by the University of 161590Srgrimes * California, Berkeley and its contributors. 171590Srgrimes * 4. Neither the name of the University nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 331590Srgrimes 341590Srgrimes#ifndef lint 351590Srgrimesstatic char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 1/12/94"; 361590Srgrimes#endif /* not lint */ 371590Srgrimes 381590Srgrimes/* 391590Srgrimes * Cursed vmstat -- from Robert Elz. 401590Srgrimes */ 411590Srgrimes 421590Srgrimes#include <sys/param.h> 431590Srgrimes#include <sys/dkstat.h> 441590Srgrimes#include <sys/buf.h> 451590Srgrimes#include <sys/stat.h> 461590Srgrimes#include <sys/time.h> 471590Srgrimes#include <sys/user.h> 481590Srgrimes#include <sys/proc.h> 491590Srgrimes#include <sys/namei.h> 501590Srgrimes#include <sys/sysctl.h> 5112805Speter#include <sys/vmmeter.h> 521590Srgrimes#include <vm/vm.h> 531590Srgrimes 541590Srgrimes#include <signal.h> 551590Srgrimes#include <nlist.h> 561590Srgrimes#include <ctype.h> 571590Srgrimes#include <utmp.h> 581590Srgrimes#include <paths.h> 591590Srgrimes#include <string.h> 601590Srgrimes#include <stdlib.h> 611590Srgrimes#include <unistd.h> 621590Srgrimes#include "systat.h" 631590Srgrimes#include "extern.h" 641590Srgrimes 651590Srgrimesstatic struct Info { 661590Srgrimes long time[CPUSTATES]; 671590Srgrimes struct vmmeter Cnt; 681590Srgrimes struct vmtotal Total; 691590Srgrimes long *dk_time; 701590Srgrimes long *dk_wds; 711590Srgrimes long *dk_seek; 721590Srgrimes long *dk_xfer; 731590Srgrimes int dk_busy; 741590Srgrimes struct nchstats nchstats; 751590Srgrimes long nchcount; 761590Srgrimes long *intrcnt; 776988Sdg int bufspace; 781590Srgrimes} s, s1, s2, z; 791590Srgrimes 801590Srgrimes#define cnt s.Cnt 811590Srgrimes#define oldcnt s1.Cnt 821590Srgrimes#define total s.Total 831590Srgrimes#define nchtotal s.nchstats 841590Srgrimes#define oldnchtotal s1.nchstats 851590Srgrimes 861590Srgrimesstatic enum state { BOOT, TIME, RUN } state = TIME; 871590Srgrimes 881590Srgrimesstatic void allocinfo __P((struct Info *)); 891590Srgrimesstatic void copyinfo __P((struct Info *, struct Info *)); 901590Srgrimesstatic float cputime __P((int)); 911590Srgrimesstatic void dinfo __P((int, int)); 921590Srgrimesstatic void getinfo __P((struct Info *, enum state)); 931590Srgrimesstatic void putint __P((int, int, int, int)); 941590Srgrimesstatic void putfloat __P((double, int, int, int, int, int)); 951590Srgrimesstatic int ucount __P((void)); 961590Srgrimes 971590Srgrimesstatic int ut; 981590Srgrimesstatic char buf[26]; 991590Srgrimesstatic time_t t; 1001590Srgrimesstatic double etime; 1011590Srgrimesstatic int nintr; 1021590Srgrimesstatic long *intrloc; 1031590Srgrimesstatic char **intrname; 1041590Srgrimesstatic int nextintsrow; 1051590Srgrimes 1061590Srgrimesstruct utmp utmp; 1071590Srgrimes 1081590Srgrimes 1091590SrgrimesWINDOW * 1101590Srgrimesopenkre() 1111590Srgrimes{ 1121590Srgrimes 1131590Srgrimes ut = open(_PATH_UTMP, O_RDONLY); 1141590Srgrimes if (ut < 0) 1151590Srgrimes error("No utmp"); 1161590Srgrimes return (stdscr); 1171590Srgrimes} 1181590Srgrimes 1191590Srgrimesvoid 1201590Srgrimesclosekre(w) 1211590Srgrimes WINDOW *w; 1221590Srgrimes{ 1231590Srgrimes 1241590Srgrimes (void) close(ut); 1251590Srgrimes if (w == NULL) 1261590Srgrimes return; 1271590Srgrimes wclear(w); 1281590Srgrimes wrefresh(w); 1291590Srgrimes} 1301590Srgrimes 1311590Srgrimes 1321590Srgrimesstatic struct nlist namelist[] = { 1331590Srgrimes#define X_CPTIME 0 1341590Srgrimes { "_cp_time" }, 1351590Srgrimes#define X_CNT 1 1361590Srgrimes { "_cnt" }, 1379501Sbde#define X_BUFFERSPACE 2 1389501Sbde { "_bufspace" }, 1391590Srgrimes#define X_DK_BUSY 3 1401590Srgrimes { "_dk_busy" }, 1411590Srgrimes#define X_DK_TIME 4 1421590Srgrimes { "_dk_time" }, 1431590Srgrimes#define X_DK_XFER 5 1441590Srgrimes { "_dk_xfer" }, 1451590Srgrimes#define X_DK_WDS 6 1461590Srgrimes { "_dk_wds" }, 1471590Srgrimes#define X_DK_SEEK 7 1481590Srgrimes { "_dk_seek" }, 1491590Srgrimes#define X_NCHSTATS 8 1501590Srgrimes { "_nchstats" }, 1511590Srgrimes#define X_INTRNAMES 9 1521590Srgrimes { "_intrnames" }, 1531590Srgrimes#define X_EINTRNAMES 10 1541590Srgrimes { "_eintrnames" }, 1551590Srgrimes#define X_INTRCNT 11 1561590Srgrimes { "_intrcnt" }, 1571590Srgrimes#define X_EINTRCNT 12 1581590Srgrimes { "_eintrcnt" }, 1591590Srgrimes { "" }, 1601590Srgrimes}; 1611590Srgrimes 1621590Srgrimes/* 1631590Srgrimes * These constants define where the major pieces are laid out 1641590Srgrimes */ 1651590Srgrimes#define STATROW 0 /* uses 1 row and 68 cols */ 1661590Srgrimes#define STATCOL 2 1671590Srgrimes#define MEMROW 2 /* uses 4 rows and 31 cols */ 1681590Srgrimes#define MEMCOL 0 1691590Srgrimes#define PAGEROW 2 /* uses 4 rows and 26 cols */ 1701590Srgrimes#define PAGECOL 36 1711590Srgrimes#define INTSROW 2 /* uses all rows to bottom and 17 cols */ 1727455Sdg#define INTSCOL 61 1731590Srgrimes#define PROCSROW 7 /* uses 2 rows and 20 cols */ 1741590Srgrimes#define PROCSCOL 0 1751590Srgrimes#define GENSTATROW 7 /* uses 2 rows and 30 cols */ 1761590Srgrimes#define GENSTATCOL 20 1774808Sdg#define VMSTATROW 6 /* uses 17 rows and 12 cols */ 1781590Srgrimes#define VMSTATCOL 48 1791590Srgrimes#define GRAPHROW 10 /* uses 3 rows and 51 cols */ 1801590Srgrimes#define GRAPHCOL 0 1811590Srgrimes#define NAMEIROW 14 /* uses 3 rows and 38 cols */ 1821590Srgrimes#define NAMEICOL 0 1831590Srgrimes#define DISKROW 18 /* uses 5 rows and 50 cols (for 9 drives) */ 1841590Srgrimes#define DISKCOL 0 1851590Srgrimes 1861590Srgrimes#define DRIVESPACE 9 /* max # for space */ 1871590Srgrimes 1881590Srgrimes#if DK_NDRIVE > DRIVESPACE 1891590Srgrimes#define MAXDRIVES DRIVESPACE /* max # to display */ 1901590Srgrimes#else 1911590Srgrimes#define MAXDRIVES DK_NDRIVE /* max # to display */ 1921590Srgrimes#endif 1931590Srgrimes 1941590Srgrimesint 1951590Srgrimesinitkre() 1961590Srgrimes{ 1971590Srgrimes char *intrnamebuf, *cp; 1981590Srgrimes int i; 1991590Srgrimes static int once = 0; 2001590Srgrimes 2011590Srgrimes if (namelist[0].n_type == 0) { 2021590Srgrimes if (kvm_nlist(kd, namelist)) { 2031590Srgrimes nlisterr(namelist); 2041590Srgrimes return(0); 2051590Srgrimes } 2061590Srgrimes if (namelist[0].n_type == 0) { 2071590Srgrimes error("No namelist"); 2081590Srgrimes return(0); 2091590Srgrimes } 2101590Srgrimes } 2111590Srgrimes if (! dkinit()) 2121590Srgrimes return(0); 2131590Srgrimes if (dk_ndrive && !once) { 2141590Srgrimes#define allocate(e, t) \ 2151590Srgrimes s./**/e = (t *)calloc(dk_ndrive, sizeof (t)); \ 2161590Srgrimes s1./**/e = (t *)calloc(dk_ndrive, sizeof (t)); \ 2171590Srgrimes s2./**/e = (t *)calloc(dk_ndrive, sizeof (t)); \ 2181590Srgrimes z./**/e = (t *)calloc(dk_ndrive, sizeof (t)); 2191590Srgrimes allocate(dk_time, long); 2201590Srgrimes allocate(dk_wds, long); 2211590Srgrimes allocate(dk_seek, long); 2221590Srgrimes allocate(dk_xfer, long); 2231590Srgrimes once = 1; 2241590Srgrimes#undef allocate 2251590Srgrimes } 2261590Srgrimes if (nintr == 0) { 2271590Srgrimes nintr = (namelist[X_EINTRCNT].n_value - 2281590Srgrimes namelist[X_INTRCNT].n_value) / sizeof (long); 2291590Srgrimes intrloc = calloc(nintr, sizeof (long)); 2301590Srgrimes intrname = calloc(nintr, sizeof (long)); 2311590Srgrimes intrnamebuf = malloc(namelist[X_EINTRNAMES].n_value - 2321590Srgrimes namelist[X_INTRNAMES].n_value); 2331590Srgrimes if (intrnamebuf == 0 || intrname == 0 || intrloc == 0) { 2341590Srgrimes error("Out of memory\n"); 2351590Srgrimes if (intrnamebuf) 2361590Srgrimes free(intrnamebuf); 2371590Srgrimes if (intrname) 2381590Srgrimes free(intrname); 2391590Srgrimes if (intrloc) 2401590Srgrimes free(intrloc); 2411590Srgrimes nintr = 0; 2421590Srgrimes return(0); 2431590Srgrimes } 2441590Srgrimes NREAD(X_INTRNAMES, intrnamebuf, NVAL(X_EINTRNAMES) - 2451590Srgrimes NVAL(X_INTRNAMES)); 2461590Srgrimes for (cp = intrnamebuf, i = 0; i < nintr; i++) { 2471590Srgrimes intrname[i] = cp; 2481590Srgrimes cp += strlen(cp) + 1; 2491590Srgrimes } 2501590Srgrimes nextintsrow = INTSROW + 2; 2511590Srgrimes allocinfo(&s); 2521590Srgrimes allocinfo(&s1); 2531590Srgrimes allocinfo(&s2); 2541590Srgrimes allocinfo(&z); 2551590Srgrimes } 2561590Srgrimes getinfo(&s2, RUN); 2571590Srgrimes copyinfo(&s2, &s1); 2581590Srgrimes return(1); 2591590Srgrimes} 2601590Srgrimes 2611590Srgrimesvoid 2621590Srgrimesfetchkre() 2631590Srgrimes{ 2641590Srgrimes time_t now; 2651590Srgrimes 2661590Srgrimes time(&now); 2671590Srgrimes strcpy(buf, ctime(&now)); 2681590Srgrimes buf[16] = '\0'; 2691590Srgrimes getinfo(&s, state); 2701590Srgrimes} 2711590Srgrimes 2721590Srgrimesvoid 2731590Srgrimeslabelkre() 2741590Srgrimes{ 2751590Srgrimes register int i, j; 2761590Srgrimes 2771590Srgrimes clear(); 2781590Srgrimes mvprintw(STATROW, STATCOL + 4, "users Load"); 2791590Srgrimes mvprintw(MEMROW, MEMCOL, "Mem:KB REAL VIRTUAL"); 2801590Srgrimes mvprintw(MEMROW + 1, MEMCOL, " Tot Share Tot Share"); 2811590Srgrimes mvprintw(MEMROW + 2, MEMCOL, "Act"); 2821590Srgrimes mvprintw(MEMROW + 3, MEMCOL, "All"); 2831590Srgrimes 2841590Srgrimes mvprintw(MEMROW + 1, MEMCOL + 31, "Free"); 2851590Srgrimes 2863614Sdg mvprintw(PAGEROW, PAGECOL, " VN PAGER SWAP PAGER "); 2873614Sdg mvprintw(PAGEROW + 1, PAGECOL, " in out in out "); 2881590Srgrimes mvprintw(PAGEROW + 2, PAGECOL, "count"); 2891590Srgrimes mvprintw(PAGEROW + 3, PAGECOL, "pages"); 2901590Srgrimes 2911590Srgrimes mvprintw(INTSROW, INTSCOL + 3, " Interrupts"); 2921590Srgrimes mvprintw(INTSROW + 1, INTSCOL + 9, "total"); 2931590Srgrimes 2941590Srgrimes mvprintw(VMSTATROW + 0, VMSTATCOL + 10, "cow"); 2957348Sdg mvprintw(VMSTATROW + 1, VMSTATCOL + 10, "zfod"); 2967351Sdg mvprintw(VMSTATROW + 2, VMSTATCOL + 10, "wire"); 2977351Sdg mvprintw(VMSTATROW + 3, VMSTATCOL + 10, "act"); 2987351Sdg mvprintw(VMSTATROW + 4, VMSTATCOL + 10, "inact"); 2997351Sdg mvprintw(VMSTATROW + 5, VMSTATCOL + 10, "cache"); 3007351Sdg mvprintw(VMSTATROW + 6, VMSTATCOL + 10, "free"); 3017351Sdg mvprintw(VMSTATROW + 7, VMSTATCOL + 10, "daefr"); 3027351Sdg mvprintw(VMSTATROW + 8, VMSTATCOL + 10, "prcfr"); 3037351Sdg mvprintw(VMSTATROW + 9, VMSTATCOL + 10, "react"); 3047351Sdg mvprintw(VMSTATROW + 10, VMSTATCOL + 10, "pdwake"); 3057351Sdg mvprintw(VMSTATROW + 11, VMSTATCOL + 10, "pdpgs"); 3067351Sdg mvprintw(VMSTATROW + 12, VMSTATCOL + 10, "intrn"); 3077351Sdg mvprintw(VMSTATROW + 13, VMSTATCOL + 10, "buf"); 3081590Srgrimes 3091590Srgrimes mvprintw(GENSTATROW, GENSTATCOL, " Csw Trp Sys Int Sof Flt"); 3101590Srgrimes 3111590Srgrimes mvprintw(GRAPHROW, GRAPHCOL, 3124930Sbde " . %%Sys . %%Intr . %%User . %%Nice . %%Idle"); 3131590Srgrimes mvprintw(PROCSROW, PROCSCOL, "Proc:r p d s w"); 3141590Srgrimes mvprintw(GRAPHROW + 1, GRAPHCOL, 3151590Srgrimes "| | | | | | | | | | |"); 3161590Srgrimes 3177012Sphk mvprintw(NAMEIROW, NAMEICOL, "Namei Name-cache Proc-cache"); 3181590Srgrimes mvprintw(NAMEIROW + 1, NAMEICOL, 3191590Srgrimes " Calls hits %% hits %%"); 3201590Srgrimes mvprintw(DISKROW, DISKCOL, "Discs"); 3211590Srgrimes mvprintw(DISKROW + 1, DISKCOL, "seeks"); 3221590Srgrimes mvprintw(DISKROW + 2, DISKCOL, "xfers"); 3231590Srgrimes mvprintw(DISKROW + 3, DISKCOL, " blks"); 3241590Srgrimes mvprintw(DISKROW + 4, DISKCOL, " msps"); 3251590Srgrimes j = 0; 3261590Srgrimes for (i = 0; i < dk_ndrive && j < MAXDRIVES; i++) 3271590Srgrimes if (dk_select[i]) { 3281590Srgrimes mvprintw(DISKROW, DISKCOL + 5 + 5 * j, 3291590Srgrimes " %3.3s", dr_name[j]); 3301590Srgrimes j++; 3311590Srgrimes } 3321590Srgrimes for (i = 0; i < nintr; i++) { 3331590Srgrimes if (intrloc[i] == 0) 3341590Srgrimes continue; 3357455Sdg mvprintw(intrloc[i], INTSCOL + 9, "%-10.10s", intrname[i]); 3361590Srgrimes } 3371590Srgrimes} 3381590Srgrimes 3391590Srgrimes#define X(fld) {t=s.fld[i]; s.fld[i]-=s1.fld[i]; if(state==TIME) s1.fld[i]=t;} 3401590Srgrimes#define Y(fld) {t = s.fld; s.fld -= s1.fld; if(state == TIME) s1.fld = t;} 3411590Srgrimes#define Z(fld) {t = s.nchstats.fld; s.nchstats.fld -= s1.nchstats.fld; \ 3421590Srgrimes if(state == TIME) s1.nchstats.fld = t;} 3431590Srgrimes#define PUTRATE(fld, l, c, w) \ 3441590Srgrimes Y(fld); \ 3451590Srgrimes putint((int)((float)s.fld/etime + 0.5), l, c, w) 3461590Srgrimes#define MAXFAIL 5 3471590Srgrimes 3484930Sbdestatic char cpuchar[CPUSTATES] = { '=' , '+', '>', '-', ' ' }; 3494930Sbdestatic char cpuorder[CPUSTATES] = { CP_SYS, CP_INTR, CP_USER, CP_NICE, 3504930Sbde CP_IDLE }; 3511590Srgrimes 3521590Srgrimesvoid 3531590Srgrimesshowkre() 3541590Srgrimes{ 3551590Srgrimes float f1, f2; 3561590Srgrimes int psiz, inttotal; 3571590Srgrimes int i, l, c; 3581590Srgrimes static int failcnt = 0; 3591590Srgrimes 3601590Srgrimes for (i = 0; i < dk_ndrive; i++) { 3611590Srgrimes X(dk_xfer); X(dk_seek); X(dk_wds); X(dk_time); 3621590Srgrimes } 3631590Srgrimes etime = 0; 3641590Srgrimes for(i = 0; i < CPUSTATES; i++) { 3651590Srgrimes X(time); 3661590Srgrimes etime += s.time[i]; 3671590Srgrimes } 3681590Srgrimes if (etime < 5.0) { /* < 5 ticks - ignore this trash */ 3691590Srgrimes if (failcnt++ >= MAXFAIL) { 3701590Srgrimes clear(); 3711590Srgrimes mvprintw(2, 10, "The alternate system clock has died!"); 3721590Srgrimes mvprintw(3, 10, "Reverting to ``pigs'' display."); 3731590Srgrimes move(CMDLINE, 0); 3741590Srgrimes refresh(); 3751590Srgrimes failcnt = 0; 3761590Srgrimes sleep(5); 3771590Srgrimes command("pigs"); 3781590Srgrimes } 3791590Srgrimes return; 3801590Srgrimes } 3811590Srgrimes failcnt = 0; 3821590Srgrimes etime /= hertz; 3831590Srgrimes inttotal = 0; 3841590Srgrimes for (i = 0; i < nintr; i++) { 3851590Srgrimes if (s.intrcnt[i] == 0) 3861590Srgrimes continue; 3871590Srgrimes if (intrloc[i] == 0) { 3881590Srgrimes if (nextintsrow == LINES) 3891590Srgrimes continue; 3901590Srgrimes intrloc[i] = nextintsrow++; 3917455Sdg mvprintw(intrloc[i], INTSCOL + 9, "%-10.10s", 3921590Srgrimes intrname[i]); 3931590Srgrimes } 3941590Srgrimes X(intrcnt); 3951590Srgrimes l = (int)((float)s.intrcnt[i]/etime + 0.5); 3961590Srgrimes inttotal += l; 3977455Sdg putint(l, intrloc[i], INTSCOL + 2, 6); 3981590Srgrimes } 3997455Sdg putint(inttotal, INTSROW + 1, INTSCOL + 2, 6); 4001590Srgrimes Z(ncs_goodhits); Z(ncs_badhits); Z(ncs_miss); 4017138Sphk Z(ncs_long); Z(ncs_pass2); Z(ncs_2passes); Z(ncs_neghits); 4021590Srgrimes s.nchcount = nchtotal.ncs_goodhits + nchtotal.ncs_badhits + 4037012Sphk nchtotal.ncs_miss + nchtotal.ncs_long + nchtotal.ncs_neghits; 4041590Srgrimes if (state == TIME) 4051590Srgrimes s1.nchcount = s.nchcount; 4061590Srgrimes 4071590Srgrimes psiz = 0; 4081590Srgrimes f2 = 0.0; 4094930Sbde for (c = 0; c < CPUSTATES; c++) { 4101590Srgrimes i = cpuorder[c]; 4111590Srgrimes f1 = cputime(i); 4121590Srgrimes f2 += f1; 4131590Srgrimes l = (int) ((f2 + 1.0) / 2.0) - psiz; 4144930Sbde if (f1 > 99.9) 4154930Sbde f1 = 99.9; /* no room to display 100.0 */ 4164930Sbde putfloat(f1, GRAPHROW, GRAPHCOL + 10 * c, 4, 1, 0); 4171590Srgrimes move(GRAPHROW + 2, psiz); 4181590Srgrimes psiz += l; 4191590Srgrimes while (l-- > 0) 4201590Srgrimes addch(cpuchar[c]); 4211590Srgrimes } 4221590Srgrimes 4231590Srgrimes putint(ucount(), STATROW, STATCOL, 3); 4241590Srgrimes putfloat(avenrun[0], STATROW, STATCOL + 17, 6, 2, 0); 4251590Srgrimes putfloat(avenrun[1], STATROW, STATCOL + 23, 6, 2, 0); 4261590Srgrimes putfloat(avenrun[2], STATROW, STATCOL + 29, 6, 2, 0); 4271590Srgrimes mvaddstr(STATROW, STATCOL + 53, buf); 4281590Srgrimes#define pgtokb(pg) ((pg) * cnt.v_page_size / 1024) 4291590Srgrimes putint(pgtokb(total.t_arm), MEMROW + 2, MEMCOL + 3, 6); 4301590Srgrimes putint(pgtokb(total.t_armshr), MEMROW + 2, MEMCOL + 9, 6); 4311590Srgrimes putint(pgtokb(total.t_avm), MEMROW + 2, MEMCOL + 15, 7); 4321590Srgrimes putint(pgtokb(total.t_avmshr), MEMROW + 2, MEMCOL + 22, 7); 4331590Srgrimes putint(pgtokb(total.t_rm), MEMROW + 3, MEMCOL + 3, 6); 4341590Srgrimes putint(pgtokb(total.t_rmshr), MEMROW + 3, MEMCOL + 9, 6); 4351590Srgrimes putint(pgtokb(total.t_vm), MEMROW + 3, MEMCOL + 15, 7); 4361590Srgrimes putint(pgtokb(total.t_vmshr), MEMROW + 3, MEMCOL + 22, 7); 4371590Srgrimes putint(pgtokb(total.t_free), MEMROW + 2, MEMCOL + 29, 6); 4381590Srgrimes putint(total.t_rq - 1, PROCSROW + 1, PROCSCOL + 3, 3); 4391590Srgrimes putint(total.t_pw, PROCSROW + 1, PROCSCOL + 6, 3); 4401590Srgrimes putint(total.t_dw, PROCSROW + 1, PROCSCOL + 9, 3); 4411590Srgrimes putint(total.t_sl, PROCSROW + 1, PROCSCOL + 12, 3); 4421590Srgrimes putint(total.t_sw, PROCSROW + 1, PROCSCOL + 15, 3); 4431590Srgrimes PUTRATE(Cnt.v_cow_faults, VMSTATROW + 0, VMSTATCOL + 3, 6); 4447348Sdg PUTRATE(Cnt.v_zfod, VMSTATROW + 1, VMSTATCOL + 4, 5); 4457351Sdg putint(pgtokb(cnt.v_wire_count), VMSTATROW + 2, VMSTATCOL, 9); 4467351Sdg putint(pgtokb(cnt.v_active_count), VMSTATROW + 3, VMSTATCOL, 9); 4477351Sdg putint(pgtokb(cnt.v_inactive_count), VMSTATROW + 4, VMSTATCOL, 9); 4487351Sdg putint(pgtokb(cnt.v_cache_count), VMSTATROW + 5, VMSTATCOL, 9); 4497351Sdg putint(pgtokb(cnt.v_free_count), VMSTATROW + 6, VMSTATCOL, 9); 4507351Sdg PUTRATE(Cnt.v_dfree, VMSTATROW + 7, VMSTATCOL, 9); 4517351Sdg PUTRATE(Cnt.v_pfree, VMSTATROW + 8, VMSTATCOL, 9); 4527351Sdg PUTRATE(Cnt.v_reactivated, VMSTATROW + 9, VMSTATCOL, 9); 4537351Sdg PUTRATE(Cnt.v_pdwakeups, VMSTATROW + 10, VMSTATCOL, 9); 4547351Sdg PUTRATE(Cnt.v_pdpages, VMSTATROW + 11, VMSTATCOL, 9); 4557351Sdg PUTRATE(Cnt.v_intrans, VMSTATROW + 12, VMSTATCOL, 9); 4567351Sdg putint(s.bufspace/1024, VMSTATROW + 13, VMSTATCOL, 9); 4573614Sdg PUTRATE(Cnt.v_vnodein, PAGEROW + 2, PAGECOL + 5, 5); 4583614Sdg PUTRATE(Cnt.v_vnodeout, PAGEROW + 2, PAGECOL + 10, 5); 4593614Sdg PUTRATE(Cnt.v_swapin, PAGEROW + 2, PAGECOL + 17, 5); 4603614Sdg PUTRATE(Cnt.v_swapout, PAGEROW + 2, PAGECOL + 22, 5); 4613614Sdg PUTRATE(Cnt.v_vnodepgsin, PAGEROW + 3, PAGECOL + 5, 5); 4623614Sdg PUTRATE(Cnt.v_vnodepgsout, PAGEROW + 3, PAGECOL + 10, 5); 4633614Sdg PUTRATE(Cnt.v_swappgsin, PAGEROW + 3, PAGECOL + 17, 5); 4643614Sdg PUTRATE(Cnt.v_swappgsout, PAGEROW + 3, PAGECOL + 22, 5); 4651590Srgrimes PUTRATE(Cnt.v_swtch, GENSTATROW + 1, GENSTATCOL, 5); 4661590Srgrimes PUTRATE(Cnt.v_trap, GENSTATROW + 1, GENSTATCOL + 5, 5); 4671590Srgrimes PUTRATE(Cnt.v_syscall, GENSTATROW + 1, GENSTATCOL + 10, 5); 4681590Srgrimes PUTRATE(Cnt.v_intr, GENSTATROW + 1, GENSTATCOL + 15, 5); 4691590Srgrimes PUTRATE(Cnt.v_soft, GENSTATROW + 1, GENSTATCOL + 20, 5); 4703614Sdg PUTRATE(Cnt.v_vm_faults, GENSTATROW + 1, GENSTATCOL + 25, 5); 4711590Srgrimes mvprintw(DISKROW, DISKCOL + 5, " "); 4721590Srgrimes for (i = 0, c = 0; i < dk_ndrive && c < MAXDRIVES; i++) 4731590Srgrimes if (dk_select[i]) { 4741590Srgrimes mvprintw(DISKROW, DISKCOL + 5 + 5 * c, 4751590Srgrimes " %3.3s", dr_name[i]); 4761590Srgrimes dinfo(i, ++c); 4771590Srgrimes } 4781590Srgrimes putint(s.nchcount, NAMEIROW + 2, NAMEICOL, 9); 4797012Sphk putint((nchtotal.ncs_goodhits + nchtotal.ncs_neghits), 4807012Sphk NAMEIROW + 2, NAMEICOL + 9, 9); 4811590Srgrimes#define nz(x) ((x) ? (x) : 1) 4828874Srgrimes putfloat((nchtotal.ncs_goodhits+nchtotal.ncs_neghits) * 4837012Sphk 100.0 / nz(s.nchcount), 4841590Srgrimes NAMEIROW + 2, NAMEICOL + 19, 4, 0, 1); 4851590Srgrimes putint(nchtotal.ncs_pass2, NAMEIROW + 2, NAMEICOL + 23, 9); 4861590Srgrimes putfloat(nchtotal.ncs_pass2 * 100.0 / nz(s.nchcount), 4871590Srgrimes NAMEIROW + 2, NAMEICOL + 34, 4, 0, 1); 4881590Srgrimes#undef nz 4891590Srgrimes} 4901590Srgrimes 4911590Srgrimesint 4921590Srgrimescmdkre(cmd, args) 4931590Srgrimes char *cmd, *args; 4941590Srgrimes{ 4951590Srgrimes 4961590Srgrimes if (prefix(cmd, "run")) { 4971590Srgrimes copyinfo(&s2, &s1); 4981590Srgrimes state = RUN; 4991590Srgrimes return (1); 5001590Srgrimes } 5011590Srgrimes if (prefix(cmd, "boot")) { 5021590Srgrimes state = BOOT; 5031590Srgrimes copyinfo(&z, &s1); 5041590Srgrimes return (1); 5051590Srgrimes } 5061590Srgrimes if (prefix(cmd, "time")) { 5071590Srgrimes state = TIME; 5081590Srgrimes return (1); 5091590Srgrimes } 5101590Srgrimes if (prefix(cmd, "zero")) { 5111590Srgrimes if (state == RUN) 5121590Srgrimes getinfo(&s1, RUN); 5131590Srgrimes return (1); 5141590Srgrimes } 5151590Srgrimes return (dkcmd(cmd, args)); 5161590Srgrimes} 5171590Srgrimes 5181590Srgrimes/* calculate number of users on the system */ 5191590Srgrimesstatic int 5201590Srgrimesucount() 5211590Srgrimes{ 5221590Srgrimes register int nusers = 0; 5231590Srgrimes 5241590Srgrimes if (ut < 0) 5251590Srgrimes return (0); 5261590Srgrimes while (read(ut, &utmp, sizeof(utmp))) 5271590Srgrimes if (utmp.ut_name[0] != '\0') 5281590Srgrimes nusers++; 5291590Srgrimes 5301590Srgrimes lseek(ut, 0L, L_SET); 5311590Srgrimes return (nusers); 5321590Srgrimes} 5331590Srgrimes 5341590Srgrimesstatic float 5351590Srgrimescputime(indx) 5361590Srgrimes int indx; 5371590Srgrimes{ 5381590Srgrimes double t; 5391590Srgrimes register int i; 5401590Srgrimes 5411590Srgrimes t = 0; 5421590Srgrimes for (i = 0; i < CPUSTATES; i++) 5431590Srgrimes t += s.time[i]; 5441590Srgrimes if (t == 0.0) 5451590Srgrimes t = 1.0; 5461590Srgrimes return (s.time[indx] * 100.0 / t); 5471590Srgrimes} 5481590Srgrimes 5491590Srgrimesstatic void 5501590Srgrimesputint(n, l, c, w) 5511590Srgrimes int n, l, c, w; 5521590Srgrimes{ 5531590Srgrimes char b[128]; 5541590Srgrimes 5551590Srgrimes move(l, c); 5561590Srgrimes if (n == 0) { 5571590Srgrimes while (w-- > 0) 5581590Srgrimes addch(' '); 5591590Srgrimes return; 5601590Srgrimes } 5611590Srgrimes sprintf(b, "%*d", w, n); 5621590Srgrimes if (strlen(b) > w) { 5631590Srgrimes while (w-- > 0) 5641590Srgrimes addch('*'); 5651590Srgrimes return; 5661590Srgrimes } 5671590Srgrimes addstr(b); 5681590Srgrimes} 5691590Srgrimes 5701590Srgrimesstatic void 5711590Srgrimesputfloat(f, l, c, w, d, nz) 5721590Srgrimes double f; 5731590Srgrimes int l, c, w, d, nz; 5741590Srgrimes{ 5751590Srgrimes char b[128]; 5761590Srgrimes 5771590Srgrimes move(l, c); 5781590Srgrimes if (nz && f == 0.0) { 5791590Srgrimes while (--w >= 0) 5801590Srgrimes addch(' '); 5811590Srgrimes return; 5821590Srgrimes } 5831590Srgrimes sprintf(b, "%*.*f", w, d, f); 5841590Srgrimes if (strlen(b) > w) { 5851590Srgrimes while (--w >= 0) 5861590Srgrimes addch('*'); 5871590Srgrimes return; 5881590Srgrimes } 5891590Srgrimes addstr(b); 5901590Srgrimes} 5911590Srgrimes 5921590Srgrimesstatic void 5931590Srgrimesgetinfo(s, st) 5941590Srgrimes struct Info *s; 5951590Srgrimes enum state st; 5961590Srgrimes{ 5971590Srgrimes int mib[2], size; 5981590Srgrimes extern int errno; 5991590Srgrimes 6001590Srgrimes NREAD(X_CPTIME, s->time, sizeof s->time); 6011590Srgrimes NREAD(X_CNT, &s->Cnt, sizeof s->Cnt); 6026988Sdg NREAD(X_BUFFERSPACE, &s->bufspace, LONG); 6031590Srgrimes NREAD(X_DK_BUSY, &s->dk_busy, LONG); 6041590Srgrimes NREAD(X_DK_TIME, s->dk_time, dk_ndrive * LONG); 6051590Srgrimes NREAD(X_DK_XFER, s->dk_xfer, dk_ndrive * LONG); 6061590Srgrimes NREAD(X_DK_WDS, s->dk_wds, dk_ndrive * LONG); 6071590Srgrimes NREAD(X_DK_SEEK, s->dk_seek, dk_ndrive * LONG); 6081590Srgrimes NREAD(X_NCHSTATS, &s->nchstats, sizeof s->nchstats); 6091590Srgrimes NREAD(X_INTRCNT, s->intrcnt, nintr * LONG); 6101590Srgrimes size = sizeof(s->Total); 6111590Srgrimes mib[0] = CTL_VM; 6121590Srgrimes mib[1] = VM_METER; 6131590Srgrimes if (sysctl(mib, 2, &s->Total, &size, NULL, 0) < 0) { 6141590Srgrimes error("Can't get kernel info: %s\n", strerror(errno)); 6151590Srgrimes bzero(&s->Total, sizeof(s->Total)); 6161590Srgrimes } 6171590Srgrimes} 6181590Srgrimes 6191590Srgrimesstatic void 6201590Srgrimesallocinfo(s) 6211590Srgrimes struct Info *s; 6221590Srgrimes{ 6231590Srgrimes 6241590Srgrimes s->intrcnt = (long *) malloc(nintr * sizeof(long)); 6251590Srgrimes if (s->intrcnt == NULL) { 6261590Srgrimes fprintf(stderr, "systat: out of memory\n"); 6271590Srgrimes exit(2); 6281590Srgrimes } 6291590Srgrimes} 6301590Srgrimes 6311590Srgrimesstatic void 6321590Srgrimescopyinfo(from, to) 6331590Srgrimes register struct Info *from, *to; 6341590Srgrimes{ 6351590Srgrimes long *time, *wds, *seek, *xfer; 6361590Srgrimes long *intrcnt; 6371590Srgrimes 6381590Srgrimes /* 6391590Srgrimes * time, wds, seek, and xfer are malloc'd so we have to 6408874Srgrimes * save the pointers before the structure copy and then 6411590Srgrimes * copy by hand. 6421590Srgrimes */ 6431590Srgrimes time = to->dk_time; wds = to->dk_wds; seek = to->dk_seek; 6441590Srgrimes xfer = to->dk_xfer; intrcnt = to->intrcnt; 6451590Srgrimes *to = *from; 6461590Srgrimes bcopy(from->dk_time, to->dk_time = time, dk_ndrive * sizeof (long)); 6471590Srgrimes bcopy(from->dk_wds, to->dk_wds = wds, dk_ndrive * sizeof (long)); 6481590Srgrimes bcopy(from->dk_seek, to->dk_seek = seek, dk_ndrive * sizeof (long)); 6491590Srgrimes bcopy(from->dk_xfer, to->dk_xfer = xfer, dk_ndrive * sizeof (long)); 6501590Srgrimes bcopy(from->intrcnt, to->intrcnt = intrcnt, nintr * sizeof (int)); 6511590Srgrimes} 6521590Srgrimes 6531590Srgrimesstatic void 6541590Srgrimesdinfo(dn, c) 6551590Srgrimes int dn, c; 6561590Srgrimes{ 6571590Srgrimes double words, atime, itime, xtime; 6581590Srgrimes 6591590Srgrimes c = DISKCOL + c * 5; 6601590Srgrimes atime = s.dk_time[dn]; 6611590Srgrimes atime /= hertz; 6621590Srgrimes words = s.dk_wds[dn]*32.0; /* number of words transferred */ 6631590Srgrimes xtime = dk_mspw[dn]*words; /* transfer time */ 6641590Srgrimes itime = atime - xtime; /* time not transferring */ 6651590Srgrimes if (xtime < 0) 6661590Srgrimes itime += xtime, xtime = 0; 6671590Srgrimes if (itime < 0) 6681590Srgrimes xtime += itime, itime = 0; 6691590Srgrimes putint((int)((float)s.dk_seek[dn]/etime+0.5), DISKROW + 1, c, 5); 6701590Srgrimes putint((int)((float)s.dk_xfer[dn]/etime+0.5), DISKROW + 2, c, 5); 6711590Srgrimes putint((int)(words/etime/512.0 + 0.5), DISKROW + 3, c, 5); 6721590Srgrimes if (s.dk_seek[dn]) 6731590Srgrimes putfloat(itime*1000.0/s.dk_seek[dn], DISKROW + 4, c, 5, 1, 1); 6741590Srgrimes else 6751590Srgrimes putint(0, DISKROW + 4, c, 5); 6761590Srgrimes} 677