vmstat.c revision 97970
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 3487715Smarkm#include <sys/cdefs.h> 3587715Smarkm 3687715Smarkm__FBSDID("$FreeBSD: head/usr.bin/systat/vmstat.c 97970 2002-06-06 23:01:50Z des $"); 3787715Smarkm 3887715Smarkm#ifdef lint 3987715Smarkmstatic const char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 1/12/94"; 4028149Scharnier#endif 411590Srgrimes 421590Srgrimes/* 431590Srgrimes * Cursed vmstat -- from Robert Elz. 441590Srgrimes */ 451590Srgrimes 461590Srgrimes#include <sys/param.h> 471590Srgrimes#include <sys/stat.h> 481590Srgrimes#include <sys/time.h> 491590Srgrimes#include <sys/proc.h> 5012811Sbde#include <sys/uio.h> 511590Srgrimes#include <sys/namei.h> 521590Srgrimes#include <sys/sysctl.h> 5339230Sgibbs#include <sys/dkstat.h> 5412805Speter#include <sys/vmmeter.h> 551590Srgrimes 5612811Sbde#include <vm/vm_param.h> 5712811Sbde 5828149Scharnier#include <ctype.h> 5928149Scharnier#include <err.h> 6059217Simp#include <errno.h> 6174595Sache#include <langinfo.h> 621590Srgrimes#include <nlist.h> 631590Srgrimes#include <paths.h> 6428149Scharnier#include <signal.h> 6528149Scharnier#include <stdlib.h> 661590Srgrimes#include <string.h> 6714953Sache#include <time.h> 681590Srgrimes#include <unistd.h> 6928149Scharnier#include <utmp.h> 7039230Sgibbs#include <devstat.h> 711590Srgrimes#include "systat.h" 721590Srgrimes#include "extern.h" 7340060Sobrien#include "devs.h" 741590Srgrimes 751590Srgrimesstatic struct Info { 761590Srgrimes long time[CPUSTATES]; 7774671Stmm u_int v_swtch; /* context switches */ 7874671Stmm u_int v_trap; /* calls to trap */ 7974671Stmm u_int v_syscall; /* calls to syscall() */ 8074671Stmm u_int v_intr; /* device interrupts */ 8174671Stmm u_int v_soft; /* software interrupts */ 8274671Stmm /* 8374671Stmm * Virtual memory activity. 8474671Stmm */ 8574671Stmm u_int v_vm_faults; /* number of address memory faults */ 8674671Stmm u_int v_cow_faults; /* number of copy-on-writes */ 8774671Stmm u_int v_zfod; /* pages zero filled on demand */ 8874671Stmm u_int v_ozfod; /* optimized zero fill pages */ 8974671Stmm u_int v_swapin; /* swap pager pageins */ 9074671Stmm u_int v_swapout; /* swap pager pageouts */ 9174671Stmm u_int v_swappgsin; /* swap pager pages paged in */ 9274671Stmm u_int v_swappgsout; /* swap pager pages paged out */ 9374671Stmm u_int v_vnodein; /* vnode pager pageins */ 9474671Stmm u_int v_vnodeout; /* vnode pager pageouts */ 9574671Stmm u_int v_vnodepgsin; /* vnode_pager pages paged in */ 9674671Stmm u_int v_vnodepgsout; /* vnode pager pages paged out */ 9774671Stmm u_int v_intrans; /* intransit blocking page faults */ 9874671Stmm u_int v_reactivated; /* number of pages reactivated from free list */ 9974671Stmm u_int v_pdwakeups; /* number of times daemon has awaken from sleep */ 10074671Stmm u_int v_pdpages; /* number of pages analyzed by daemon */ 10174671Stmm 10274671Stmm u_int v_dfree; /* pages freed by daemon */ 10374671Stmm u_int v_pfree; /* pages freed by exiting processes */ 10474671Stmm u_int v_tfree; /* total pages freed */ 10574671Stmm /* 10674671Stmm * Distribution of page usages. 10774671Stmm */ 10874671Stmm u_int v_page_size; /* page size in bytes */ 10974671Stmm u_int v_free_count; /* number of pages free */ 11074671Stmm u_int v_wire_count; /* number of pages wired down */ 11174671Stmm u_int v_active_count; /* number of pages active */ 11274671Stmm u_int v_inactive_count; /* number of pages inactive */ 11374671Stmm u_int v_cache_count; /* number of pages on buffer cache queue */ 1141590Srgrimes struct vmtotal Total; 1151590Srgrimes struct nchstats nchstats; 1161590Srgrimes long nchcount; 1171590Srgrimes long *intrcnt; 11829842Speter int bufspace; 11929842Speter int desiredvnodes; 12069529Sgallatin long numvnodes; 12169529Sgallatin long freevnodes; 12274978Sgallatin int numdirtybuffers; 1231590Srgrimes} s, s1, s2, z; 1241590Srgrimes 12539230Sgibbsstruct statinfo cur, last, run; 12639230Sgibbs 1271590Srgrimes#define total s.Total 1281590Srgrimes#define nchtotal s.nchstats 1291590Srgrimes#define oldnchtotal s1.nchstats 1301590Srgrimes 1311590Srgrimesstatic enum state { BOOT, TIME, RUN } state = TIME; 1321590Srgrimes 13392922Simpstatic void allocinfo(struct Info *); 13492922Simpstatic void copyinfo(struct Info *, struct Info *); 13592922Simpstatic float cputime(int); 13692922Simpstatic void dinfo(int, int, struct statinfo *, struct statinfo *); 13792922Simpstatic void getinfo(struct Info *); 13892922Simpstatic void putint(int, int, int, int); 13992922Simpstatic void putfloat(double, int, int, int, int, int); 14092922Simpstatic void putlongdouble(long double, int, int, int, int, int); 14192922Simpstatic int ucount(void); 1421590Srgrimes 14336430Sjhaystatic int ncpu; 1441590Srgrimesstatic int ut; 1451590Srgrimesstatic char buf[26]; 1461590Srgrimesstatic time_t t; 1471590Srgrimesstatic double etime; 1481590Srgrimesstatic int nintr; 1491590Srgrimesstatic long *intrloc; 1501590Srgrimesstatic char **intrname; 1511590Srgrimesstatic int nextintsrow; 15243756Sdillonstatic int extended_vm_stats; 1531590Srgrimes 1541590Srgrimesstruct utmp utmp; 1551590Srgrimes 1561590Srgrimes 1571590SrgrimesWINDOW * 1581590Srgrimesopenkre() 1591590Srgrimes{ 1601590Srgrimes 1611590Srgrimes ut = open(_PATH_UTMP, O_RDONLY); 1621590Srgrimes if (ut < 0) 1631590Srgrimes error("No utmp"); 1641590Srgrimes return (stdscr); 1651590Srgrimes} 1661590Srgrimes 1671590Srgrimesvoid 1681590Srgrimesclosekre(w) 1691590Srgrimes WINDOW *w; 1701590Srgrimes{ 1711590Srgrimes 1721590Srgrimes (void) close(ut); 1731590Srgrimes if (w == NULL) 1741590Srgrimes return; 1751590Srgrimes wclear(w); 1761590Srgrimes wrefresh(w); 1771590Srgrimes} 1781590Srgrimes 1791590Srgrimes/* 1801590Srgrimes * These constants define where the major pieces are laid out 1811590Srgrimes */ 1821590Srgrimes#define STATROW 0 /* uses 1 row and 68 cols */ 1831590Srgrimes#define STATCOL 2 1841590Srgrimes#define MEMROW 2 /* uses 4 rows and 31 cols */ 1851590Srgrimes#define MEMCOL 0 1861590Srgrimes#define PAGEROW 2 /* uses 4 rows and 26 cols */ 18719687Sjkh#define PAGECOL 46 18819687Sjkh#define INTSROW 6 /* uses all rows to bottom and 17 cols */ 1897455Sdg#define INTSCOL 61 1901590Srgrimes#define PROCSROW 7 /* uses 2 rows and 20 cols */ 1911590Srgrimes#define PROCSCOL 0 1921590Srgrimes#define GENSTATROW 7 /* uses 2 rows and 30 cols */ 1931590Srgrimes#define GENSTATCOL 20 1944808Sdg#define VMSTATROW 6 /* uses 17 rows and 12 cols */ 1951590Srgrimes#define VMSTATCOL 48 1961590Srgrimes#define GRAPHROW 10 /* uses 3 rows and 51 cols */ 1971590Srgrimes#define GRAPHCOL 0 1981590Srgrimes#define NAMEIROW 14 /* uses 3 rows and 38 cols */ 1991590Srgrimes#define NAMEICOL 0 2001590Srgrimes#define DISKROW 18 /* uses 5 rows and 50 cols (for 9 drives) */ 2011590Srgrimes#define DISKCOL 0 2021590Srgrimes 20339230Sgibbs#define DRIVESPACE 7 /* max # for space */ 2041590Srgrimes 2051590Srgrimes#define MAXDRIVES DRIVESPACE /* max # to display */ 2061590Srgrimes 2071590Srgrimesint 2081590Srgrimesinitkre() 2091590Srgrimes{ 2101590Srgrimes char *intrnamebuf, *cp; 2111590Srgrimes int i; 21277583Stmm size_t sz; 2131590Srgrimes 21483131Sken if ((num_devices = devstat_getnumdevs(NULL)) < 0) { 21539230Sgibbs warnx("%s", devstat_errbuf); 2161590Srgrimes return(0); 2171590Srgrimes } 21839230Sgibbs 21939230Sgibbs cur.dinfo = (struct devinfo *)malloc(sizeof(struct devinfo)); 22039230Sgibbs last.dinfo = (struct devinfo *)malloc(sizeof(struct devinfo)); 22139230Sgibbs run.dinfo = (struct devinfo *)malloc(sizeof(struct devinfo)); 22239230Sgibbs bzero(cur.dinfo, sizeof(struct devinfo)); 22339230Sgibbs bzero(last.dinfo, sizeof(struct devinfo)); 22439230Sgibbs bzero(run.dinfo, sizeof(struct devinfo)); 22539230Sgibbs 22639230Sgibbs if (dsinit(MAXDRIVES, &cur, &last, &run) != 1) 22739230Sgibbs return(0); 22839230Sgibbs 2291590Srgrimes if (nintr == 0) { 23077583Stmm if (sysctlbyname("hw.intrcnt", NULL, &sz, NULL, 0) == -1) { 23177583Stmm error("sysctl(hw.intrcnt...) failed: %s", 23277583Stmm strerror(errno)); 23377583Stmm return (0); 23477583Stmm } 23577583Stmm nintr = sz / sizeof(u_long); 2361590Srgrimes intrloc = calloc(nintr, sizeof (long)); 23777583Stmm intrname = calloc(nintr, sizeof (char *)); 23874671Stmm intrnamebuf = sysctl_dynread("hw.intrnames", NULL); 23974671Stmm if (intrnamebuf == NULL || intrname == NULL || 24074671Stmm intrloc == NULL) { 24174671Stmm error("Out of memory"); 2421590Srgrimes if (intrnamebuf) 2431590Srgrimes free(intrnamebuf); 2441590Srgrimes if (intrname) 2451590Srgrimes free(intrname); 2461590Srgrimes if (intrloc) 2471590Srgrimes free(intrloc); 2481590Srgrimes nintr = 0; 2491590Srgrimes return(0); 2501590Srgrimes } 2511590Srgrimes for (cp = intrnamebuf, i = 0; i < nintr; i++) { 2521590Srgrimes intrname[i] = cp; 2531590Srgrimes cp += strlen(cp) + 1; 2541590Srgrimes } 2551590Srgrimes nextintsrow = INTSROW + 2; 2561590Srgrimes allocinfo(&s); 2571590Srgrimes allocinfo(&s1); 2581590Srgrimes allocinfo(&s2); 2591590Srgrimes allocinfo(&z); 2601590Srgrimes } 26187715Smarkm getinfo(&s2); 2621590Srgrimes copyinfo(&s2, &s1); 2631590Srgrimes return(1); 2641590Srgrimes} 2651590Srgrimes 2661590Srgrimesvoid 2671590Srgrimesfetchkre() 2681590Srgrimes{ 2691590Srgrimes time_t now; 27014953Sache struct tm *tp; 27174595Sache static int d_first = -1; 2721590Srgrimes 27374595Sache if (d_first < 0) 27474595Sache d_first = (*nl_langinfo(D_MD_ORDER) == 'd'); 27574595Sache 2761590Srgrimes time(&now); 27714953Sache tp = localtime(&now); 27874595Sache (void) strftime(buf, sizeof(buf), 27974595Sache d_first ? "%e %b %R" : "%b %e %R", tp); 28087715Smarkm getinfo(&s); 2811590Srgrimes} 2821590Srgrimes 2831590Srgrimesvoid 2841590Srgrimeslabelkre() 2851590Srgrimes{ 28687715Smarkm int i, j; 2871590Srgrimes 2881590Srgrimes clear(); 2891590Srgrimes mvprintw(STATROW, STATCOL + 4, "users Load"); 29019687Sjkh mvprintw(MEMROW, MEMCOL, "Mem:KB REAL VIRTUAL"); 29119687Sjkh mvprintw(MEMROW + 1, MEMCOL, " Tot Share Tot Share"); 2921590Srgrimes mvprintw(MEMROW + 2, MEMCOL, "Act"); 2931590Srgrimes mvprintw(MEMROW + 3, MEMCOL, "All"); 2941590Srgrimes 29519687Sjkh mvprintw(MEMROW + 1, MEMCOL + 41, "Free"); 2961590Srgrimes 2973614Sdg mvprintw(PAGEROW, PAGECOL, " VN PAGER SWAP PAGER "); 2983614Sdg mvprintw(PAGEROW + 1, PAGECOL, " in out in out "); 2991590Srgrimes mvprintw(PAGEROW + 2, PAGECOL, "count"); 3001590Srgrimes mvprintw(PAGEROW + 3, PAGECOL, "pages"); 3011590Srgrimes 3021590Srgrimes mvprintw(INTSROW, INTSCOL + 3, " Interrupts"); 3031590Srgrimes mvprintw(INTSROW + 1, INTSCOL + 9, "total"); 3041590Srgrimes 30543756Sdillon mvprintw(VMSTATROW + 1, VMSTATCOL + 10, "cow"); 3067351Sdg mvprintw(VMSTATROW + 2, VMSTATCOL + 10, "wire"); 3077351Sdg mvprintw(VMSTATROW + 3, VMSTATCOL + 10, "act"); 3087351Sdg mvprintw(VMSTATROW + 4, VMSTATCOL + 10, "inact"); 3097351Sdg mvprintw(VMSTATROW + 5, VMSTATCOL + 10, "cache"); 3107351Sdg mvprintw(VMSTATROW + 6, VMSTATCOL + 10, "free"); 3117351Sdg mvprintw(VMSTATROW + 7, VMSTATCOL + 10, "daefr"); 3127351Sdg mvprintw(VMSTATROW + 8, VMSTATCOL + 10, "prcfr"); 3137351Sdg mvprintw(VMSTATROW + 9, VMSTATCOL + 10, "react"); 3147351Sdg mvprintw(VMSTATROW + 10, VMSTATCOL + 10, "pdwake"); 3157351Sdg mvprintw(VMSTATROW + 11, VMSTATCOL + 10, "pdpgs"); 3167351Sdg mvprintw(VMSTATROW + 12, VMSTATCOL + 10, "intrn"); 3177351Sdg mvprintw(VMSTATROW + 13, VMSTATCOL + 10, "buf"); 31849245Sdes mvprintw(VMSTATROW + 14, VMSTATCOL + 10, "dirtybuf"); 3191590Srgrimes 32049245Sdes mvprintw(VMSTATROW + 15, VMSTATCOL + 10, "desiredvnodes"); 32149245Sdes mvprintw(VMSTATROW + 16, VMSTATCOL + 10, "numvnodes"); 32249245Sdes mvprintw(VMSTATROW + 17, VMSTATCOL + 10, "freevnodes"); 32329842Speter 3241590Srgrimes mvprintw(GENSTATROW, GENSTATCOL, " Csw Trp Sys Int Sof Flt"); 3251590Srgrimes 3261590Srgrimes mvprintw(GRAPHROW, GRAPHCOL, 3274930Sbde " . %%Sys . %%Intr . %%User . %%Nice . %%Idle"); 3281590Srgrimes mvprintw(PROCSROW, PROCSCOL, "Proc:r p d s w"); 3291590Srgrimes mvprintw(GRAPHROW + 1, GRAPHCOL, 3301590Srgrimes "| | | | | | | | | | |"); 3311590Srgrimes 33214918Sbde mvprintw(NAMEIROW, NAMEICOL, "Namei Name-cache Dir-cache"); 3331590Srgrimes mvprintw(NAMEIROW + 1, NAMEICOL, 33414918Sbde " Calls hits %% hits %%"); 33551421Sgreen mvprintw(DISKROW, DISKCOL, "Disks"); 33639230Sgibbs mvprintw(DISKROW + 1, DISKCOL, "KB/t"); 33739230Sgibbs mvprintw(DISKROW + 2, DISKCOL, "tps"); 33839230Sgibbs mvprintw(DISKROW + 3, DISKCOL, "MB/s"); 33949245Sdes mvprintw(DISKROW + 4, DISKCOL, "%% busy"); 34039230Sgibbs /* 34139230Sgibbs * For now, we don't support a fourth disk statistic. So there's 34239230Sgibbs * no point in providing a label for it. If someone can think of a 34339230Sgibbs * fourth useful disk statistic, there is room to add it. 34439230Sgibbs */ 34539230Sgibbs /* mvprintw(DISKROW + 4, DISKCOL, " msps"); */ 3461590Srgrimes j = 0; 34739230Sgibbs for (i = 0; i < num_devices && j < MAXDRIVES; i++) 34839230Sgibbs if (dev_select[i].selected) { 34939230Sgibbs char tmpstr[80]; 35039230Sgibbs sprintf(tmpstr, "%s%d", dev_select[i].device_name, 35139230Sgibbs dev_select[i].unit_number); 35239230Sgibbs mvprintw(DISKROW, DISKCOL + 5 + 6 * j, 35339230Sgibbs " %5.5s", tmpstr); 3541590Srgrimes j++; 3551590Srgrimes } 35643756Sdillon 35743756Sdillon if (j <= 4) { 35843756Sdillon /* 35943756Sdillon * room for extended VM stats 36043756Sdillon */ 36143756Sdillon mvprintw(VMSTATROW + 11, VMSTATCOL - 6, "zfod"); 36243757Sdillon mvprintw(VMSTATROW + 12, VMSTATCOL - 6, "ofod"); 36343757Sdillon mvprintw(VMSTATROW + 13, VMSTATCOL - 6, "%%slo-z"); 36443757Sdillon mvprintw(VMSTATROW + 14, VMSTATCOL - 6, "tfree"); 36543756Sdillon extended_vm_stats = 1; 36643756Sdillon } else { 36743756Sdillon extended_vm_stats = 0; 36843756Sdillon mvprintw(VMSTATROW + 0, VMSTATCOL + 10, "zfod"); 36943756Sdillon } 37043756Sdillon 3711590Srgrimes for (i = 0; i < nintr; i++) { 3721590Srgrimes if (intrloc[i] == 0) 3731590Srgrimes continue; 3747455Sdg mvprintw(intrloc[i], INTSCOL + 9, "%-10.10s", intrname[i]); 3751590Srgrimes } 3761590Srgrimes} 3771590Srgrimes 3781590Srgrimes#define X(fld) {t=s.fld[i]; s.fld[i]-=s1.fld[i]; if(state==TIME) s1.fld[i]=t;} 37939230Sgibbs#define Q(fld) {t=cur.fld[i]; cur.fld[i]-=last.fld[i]; if(state==TIME) last.fld[i]=t;} 3801590Srgrimes#define Y(fld) {t = s.fld; s.fld -= s1.fld; if(state == TIME) s1.fld = t;} 3811590Srgrimes#define Z(fld) {t = s.nchstats.fld; s.nchstats.fld -= s1.nchstats.fld; \ 3821590Srgrimes if(state == TIME) s1.nchstats.fld = t;} 3831590Srgrimes#define PUTRATE(fld, l, c, w) \ 3841590Srgrimes Y(fld); \ 3851590Srgrimes putint((int)((float)s.fld/etime + 0.5), l, c, w) 3861590Srgrimes#define MAXFAIL 5 3871590Srgrimes 3884930Sbdestatic char cpuchar[CPUSTATES] = { '=' , '+', '>', '-', ' ' }; 3894930Sbdestatic char cpuorder[CPUSTATES] = { CP_SYS, CP_INTR, CP_USER, CP_NICE, 3904930Sbde CP_IDLE }; 3911590Srgrimes 3921590Srgrimesvoid 3931590Srgrimesshowkre() 3941590Srgrimes{ 3951590Srgrimes float f1, f2; 3961590Srgrimes int psiz, inttotal; 39787715Smarkm int i, j, k, l, lc; 3981590Srgrimes static int failcnt = 0; 39987172Smarkm char intrbuffer[10]; 4001590Srgrimes 4011590Srgrimes etime = 0; 4021590Srgrimes for(i = 0; i < CPUSTATES; i++) { 4031590Srgrimes X(time); 40439230Sgibbs Q(cp_time); 4051590Srgrimes etime += s.time[i]; 4061590Srgrimes } 4071590Srgrimes if (etime < 5.0) { /* < 5 ticks - ignore this trash */ 4081590Srgrimes if (failcnt++ >= MAXFAIL) { 4091590Srgrimes clear(); 4101590Srgrimes mvprintw(2, 10, "The alternate system clock has died!"); 4111590Srgrimes mvprintw(3, 10, "Reverting to ``pigs'' display."); 4121590Srgrimes move(CMDLINE, 0); 4131590Srgrimes refresh(); 4141590Srgrimes failcnt = 0; 4151590Srgrimes sleep(5); 4161590Srgrimes command("pigs"); 4171590Srgrimes } 4181590Srgrimes return; 4191590Srgrimes } 4201590Srgrimes failcnt = 0; 4211590Srgrimes etime /= hertz; 42236430Sjhay etime /= ncpu; 4231590Srgrimes inttotal = 0; 4241590Srgrimes for (i = 0; i < nintr; i++) { 4251590Srgrimes if (s.intrcnt[i] == 0) 4261590Srgrimes continue; 4271590Srgrimes if (intrloc[i] == 0) { 4281590Srgrimes if (nextintsrow == LINES) 4291590Srgrimes continue; 4301590Srgrimes intrloc[i] = nextintsrow++; 43187172Smarkm k = 0; 43287715Smarkm for (j = 0; j < (int)sizeof(intrbuffer); j++) { 43387172Smarkm if (strncmp(&intrname[i][j], "irq", 3) == 0) 43487172Smarkm j += 3; 43587172Smarkm intrbuffer[k++] = intrname[i][j]; 43687172Smarkm } 43787172Smarkm intrbuffer[k] = '\0'; 4387455Sdg mvprintw(intrloc[i], INTSCOL + 9, "%-10.10s", 43987172Smarkm intrbuffer); 4401590Srgrimes } 4411590Srgrimes X(intrcnt); 4421590Srgrimes l = (int)((float)s.intrcnt[i]/etime + 0.5); 4431590Srgrimes inttotal += l; 4447455Sdg putint(l, intrloc[i], INTSCOL + 2, 6); 4451590Srgrimes } 4467455Sdg putint(inttotal, INTSROW + 1, INTSCOL + 2, 6); 4471590Srgrimes Z(ncs_goodhits); Z(ncs_badhits); Z(ncs_miss); 4487138Sphk Z(ncs_long); Z(ncs_pass2); Z(ncs_2passes); Z(ncs_neghits); 4491590Srgrimes s.nchcount = nchtotal.ncs_goodhits + nchtotal.ncs_badhits + 4507012Sphk nchtotal.ncs_miss + nchtotal.ncs_long + nchtotal.ncs_neghits; 4511590Srgrimes if (state == TIME) 4521590Srgrimes s1.nchcount = s.nchcount; 4531590Srgrimes 4541590Srgrimes psiz = 0; 4551590Srgrimes f2 = 0.0; 45687715Smarkm for (lc = 0; lc < CPUSTATES; lc++) { 45787715Smarkm i = cpuorder[lc]; 4581590Srgrimes f1 = cputime(i); 4591590Srgrimes f2 += f1; 4601590Srgrimes l = (int) ((f2 + 1.0) / 2.0) - psiz; 4614930Sbde if (f1 > 99.9) 4624930Sbde f1 = 99.9; /* no room to display 100.0 */ 46387715Smarkm putfloat(f1, GRAPHROW, GRAPHCOL + 10 * lc, 4, 1, 0); 4641590Srgrimes move(GRAPHROW + 2, psiz); 4651590Srgrimes psiz += l; 4661590Srgrimes while (l-- > 0) 46787715Smarkm addch(cpuchar[lc]); 4681590Srgrimes } 4691590Srgrimes 4701590Srgrimes putint(ucount(), STATROW, STATCOL, 3); 4711590Srgrimes putfloat(avenrun[0], STATROW, STATCOL + 17, 6, 2, 0); 4721590Srgrimes putfloat(avenrun[1], STATROW, STATCOL + 23, 6, 2, 0); 4731590Srgrimes putfloat(avenrun[2], STATROW, STATCOL + 29, 6, 2, 0); 4741590Srgrimes mvaddstr(STATROW, STATCOL + 53, buf); 47574671Stmm#define pgtokb(pg) ((pg) * s.v_page_size / 1024) 47619687Sjkh putint(pgtokb(total.t_arm), MEMROW + 2, MEMCOL + 3, 8); 47719687Sjkh putint(pgtokb(total.t_armshr), MEMROW + 2, MEMCOL + 11, 8); 47819687Sjkh putint(pgtokb(total.t_avm), MEMROW + 2, MEMCOL + 19, 9); 47919687Sjkh putint(pgtokb(total.t_avmshr), MEMROW + 2, MEMCOL + 28, 9); 48019687Sjkh putint(pgtokb(total.t_rm), MEMROW + 3, MEMCOL + 3, 8); 48119687Sjkh putint(pgtokb(total.t_rmshr), MEMROW + 3, MEMCOL + 11, 8); 48219687Sjkh putint(pgtokb(total.t_vm), MEMROW + 3, MEMCOL + 19, 9); 48319687Sjkh putint(pgtokb(total.t_vmshr), MEMROW + 3, MEMCOL + 28, 9); 48419687Sjkh putint(pgtokb(total.t_free), MEMROW + 2, MEMCOL + 37, 8); 4851590Srgrimes putint(total.t_rq - 1, PROCSROW + 1, PROCSCOL + 3, 3); 4861590Srgrimes putint(total.t_pw, PROCSROW + 1, PROCSCOL + 6, 3); 4871590Srgrimes putint(total.t_dw, PROCSROW + 1, PROCSCOL + 9, 3); 4881590Srgrimes putint(total.t_sl, PROCSROW + 1, PROCSCOL + 12, 3); 4891590Srgrimes putint(total.t_sw, PROCSROW + 1, PROCSCOL + 15, 3); 49043756Sdillon if (extended_vm_stats == 0) { 49174671Stmm PUTRATE(v_zfod, VMSTATROW + 0, VMSTATCOL + 4, 5); 49243756Sdillon } 49374671Stmm PUTRATE(v_cow_faults, VMSTATROW + 1, VMSTATCOL + 3, 6); 49474671Stmm putint(pgtokb(s.v_wire_count), VMSTATROW + 2, VMSTATCOL, 9); 49574671Stmm putint(pgtokb(s.v_active_count), VMSTATROW + 3, VMSTATCOL, 9); 49674671Stmm putint(pgtokb(s.v_inactive_count), VMSTATROW + 4, VMSTATCOL, 9); 49774671Stmm putint(pgtokb(s.v_cache_count), VMSTATROW + 5, VMSTATCOL, 9); 49874671Stmm putint(pgtokb(s.v_free_count), VMSTATROW + 6, VMSTATCOL, 9); 49974671Stmm PUTRATE(v_dfree, VMSTATROW + 7, VMSTATCOL, 9); 50074671Stmm PUTRATE(v_pfree, VMSTATROW + 8, VMSTATCOL, 9); 50174671Stmm PUTRATE(v_reactivated, VMSTATROW + 9, VMSTATCOL, 9); 50274671Stmm PUTRATE(v_pdwakeups, VMSTATROW + 10, VMSTATCOL, 9); 50374671Stmm PUTRATE(v_pdpages, VMSTATROW + 11, VMSTATCOL, 9); 50474671Stmm PUTRATE(v_intrans, VMSTATROW + 12, VMSTATCOL, 9); 50543756Sdillon 50643756Sdillon if (extended_vm_stats) { 50774671Stmm PUTRATE(v_zfod, VMSTATROW + 11, VMSTATCOL - 16, 9); 50874671Stmm PUTRATE(v_ozfod, VMSTATROW + 12, VMSTATCOL - 16, 9); 50943756Sdillon putint( 51074671Stmm ((s.v_ozfod < s.v_zfod) ? 51174671Stmm s.v_ozfod * 100 / s.v_zfod : 51243756Sdillon 0 51343756Sdillon ), 51443757Sdillon VMSTATROW + 13, 51543756Sdillon VMSTATCOL - 16, 51643756Sdillon 9 51743756Sdillon ); 51874671Stmm PUTRATE(v_tfree, VMSTATROW + 14, VMSTATCOL - 16, 9); 51943756Sdillon } 52043756Sdillon 5217351Sdg putint(s.bufspace/1024, VMSTATROW + 13, VMSTATCOL, 9); 52249245Sdes putint(s.numdirtybuffers, VMSTATROW + 14, VMSTATCOL, 9); 52349245Sdes putint(s.desiredvnodes, VMSTATROW + 15, VMSTATCOL, 9); 52449245Sdes putint(s.numvnodes, VMSTATROW + 16, VMSTATCOL, 9); 52549245Sdes putint(s.freevnodes, VMSTATROW + 17, VMSTATCOL, 9); 52674671Stmm PUTRATE(v_vnodein, PAGEROW + 2, PAGECOL + 5, 5); 52774671Stmm PUTRATE(v_vnodeout, PAGEROW + 2, PAGECOL + 10, 5); 52874671Stmm PUTRATE(v_swapin, PAGEROW + 2, PAGECOL + 17, 5); 52974671Stmm PUTRATE(v_swapout, PAGEROW + 2, PAGECOL + 22, 5); 53074671Stmm PUTRATE(v_vnodepgsin, PAGEROW + 3, PAGECOL + 5, 5); 53174671Stmm PUTRATE(v_vnodepgsout, PAGEROW + 3, PAGECOL + 10, 5); 53274671Stmm PUTRATE(v_swappgsin, PAGEROW + 3, PAGECOL + 17, 5); 53374671Stmm PUTRATE(v_swappgsout, PAGEROW + 3, PAGECOL + 22, 5); 53474671Stmm PUTRATE(v_swtch, GENSTATROW + 1, GENSTATCOL, 5); 53574671Stmm PUTRATE(v_trap, GENSTATROW + 1, GENSTATCOL + 5, 5); 53674671Stmm PUTRATE(v_syscall, GENSTATROW + 1, GENSTATCOL + 10, 5); 53774671Stmm PUTRATE(v_intr, GENSTATROW + 1, GENSTATCOL + 15, 5); 53874671Stmm PUTRATE(v_soft, GENSTATROW + 1, GENSTATCOL + 20, 5); 53974671Stmm PUTRATE(v_vm_faults, GENSTATROW + 1, GENSTATCOL + 25, 5); 5401590Srgrimes mvprintw(DISKROW, DISKCOL + 5, " "); 54187715Smarkm for (i = 0, lc = 0; i < num_devices && lc < MAXDRIVES; i++) 54239230Sgibbs if (dev_select[i].selected) { 54339230Sgibbs char tmpstr[80]; 54439230Sgibbs sprintf(tmpstr, "%s%d", dev_select[i].device_name, 54539230Sgibbs dev_select[i].unit_number); 54687715Smarkm mvprintw(DISKROW, DISKCOL + 5 + 6 * lc, 54739230Sgibbs " %5.5s", tmpstr); 54839230Sgibbs switch(state) { 54939230Sgibbs case TIME: 55087715Smarkm dinfo(i, ++lc, &cur, &last); 55139230Sgibbs break; 55239230Sgibbs case RUN: 55387715Smarkm dinfo(i, ++lc, &cur, &run); 55439230Sgibbs break; 55539230Sgibbs case BOOT: 55687715Smarkm dinfo(i, ++lc, &cur, NULL); 55739230Sgibbs break; 55839230Sgibbs } 5591590Srgrimes } 5601590Srgrimes putint(s.nchcount, NAMEIROW + 2, NAMEICOL, 9); 5617012Sphk putint((nchtotal.ncs_goodhits + nchtotal.ncs_neghits), 5627012Sphk NAMEIROW + 2, NAMEICOL + 9, 9); 5631590Srgrimes#define nz(x) ((x) ? (x) : 1) 5648874Srgrimes putfloat((nchtotal.ncs_goodhits+nchtotal.ncs_neghits) * 5657012Sphk 100.0 / nz(s.nchcount), 5661590Srgrimes NAMEIROW + 2, NAMEICOL + 19, 4, 0, 1); 5671590Srgrimes putint(nchtotal.ncs_pass2, NAMEIROW + 2, NAMEICOL + 23, 9); 5681590Srgrimes putfloat(nchtotal.ncs_pass2 * 100.0 / nz(s.nchcount), 56914918Sbde NAMEIROW + 2, NAMEICOL + 33, 4, 0, 1); 5701590Srgrimes#undef nz 5711590Srgrimes} 5721590Srgrimes 5731590Srgrimesint 5741590Srgrimescmdkre(cmd, args) 57587715Smarkm const char *cmd, *args; 5761590Srgrimes{ 57739230Sgibbs int retval; 5781590Srgrimes 5791590Srgrimes if (prefix(cmd, "run")) { 58039230Sgibbs retval = 1; 5811590Srgrimes copyinfo(&s2, &s1); 58283131Sken switch (devstat_getdevs(NULL, &run)) { 58339230Sgibbs case -1: 58439230Sgibbs errx(1, "%s", devstat_errbuf); 58539230Sgibbs break; 58639230Sgibbs case 1: 58739230Sgibbs num_devices = run.dinfo->numdevs; 58839230Sgibbs generation = run.dinfo->generation; 58939230Sgibbs retval = dscmd("refresh", NULL, MAXDRIVES, &cur); 59039230Sgibbs if (retval == 2) 59139230Sgibbs labelkre(); 59239230Sgibbs break; 59339230Sgibbs default: 59439230Sgibbs break; 59539230Sgibbs } 5961590Srgrimes state = RUN; 59739230Sgibbs return (retval); 5981590Srgrimes } 5991590Srgrimes if (prefix(cmd, "boot")) { 6001590Srgrimes state = BOOT; 6011590Srgrimes copyinfo(&z, &s1); 6021590Srgrimes return (1); 6031590Srgrimes } 6041590Srgrimes if (prefix(cmd, "time")) { 6051590Srgrimes state = TIME; 6061590Srgrimes return (1); 6071590Srgrimes } 6081590Srgrimes if (prefix(cmd, "zero")) { 60939230Sgibbs retval = 1; 61039230Sgibbs if (state == RUN) { 61187715Smarkm getinfo(&s1); 61283131Sken switch (devstat_getdevs(NULL, &run)) { 61339230Sgibbs case -1: 61439230Sgibbs errx(1, "%s", devstat_errbuf); 61539230Sgibbs break; 61639230Sgibbs case 1: 61739230Sgibbs num_devices = run.dinfo->numdevs; 61839230Sgibbs generation = run.dinfo->generation; 61939230Sgibbs retval = dscmd("refresh",NULL, MAXDRIVES, &cur); 62039230Sgibbs if (retval == 2) 62139230Sgibbs labelkre(); 62239230Sgibbs break; 62339230Sgibbs default: 62439230Sgibbs break; 62539230Sgibbs } 62639230Sgibbs } 62739230Sgibbs return (retval); 6281590Srgrimes } 62939230Sgibbs retval = dscmd(cmd, args, MAXDRIVES, &cur); 63039230Sgibbs 63139230Sgibbs if (retval == 2) 63239230Sgibbs labelkre(); 63339230Sgibbs 63439230Sgibbs return(retval); 6351590Srgrimes} 6361590Srgrimes 6371590Srgrimes/* calculate number of users on the system */ 6381590Srgrimesstatic int 6391590Srgrimesucount() 6401590Srgrimes{ 64187715Smarkm int nusers = 0; 6421590Srgrimes 6431590Srgrimes if (ut < 0) 6441590Srgrimes return (0); 6451590Srgrimes while (read(ut, &utmp, sizeof(utmp))) 6461590Srgrimes if (utmp.ut_name[0] != '\0') 6471590Srgrimes nusers++; 6481590Srgrimes 6491590Srgrimes lseek(ut, 0L, L_SET); 6501590Srgrimes return (nusers); 6511590Srgrimes} 6521590Srgrimes 6531590Srgrimesstatic float 6541590Srgrimescputime(indx) 6551590Srgrimes int indx; 6561590Srgrimes{ 65787715Smarkm double lt; 65887715Smarkm int i; 6591590Srgrimes 66087715Smarkm lt = 0; 6611590Srgrimes for (i = 0; i < CPUSTATES; i++) 66287715Smarkm lt += s.time[i]; 66387715Smarkm if (lt == 0.0) 66487715Smarkm lt = 1.0; 66587715Smarkm return (s.time[indx] * 100.0 / lt); 6661590Srgrimes} 6671590Srgrimes 6681590Srgrimesstatic void 66987715Smarkmputint(n, l, lc, w) 67087715Smarkm int n, l, lc, w; 6711590Srgrimes{ 6721590Srgrimes char b[128]; 6731590Srgrimes 67487715Smarkm move(l, lc); 6751590Srgrimes if (n == 0) { 6761590Srgrimes while (w-- > 0) 6771590Srgrimes addch(' '); 6781590Srgrimes return; 6791590Srgrimes } 68036789Simp snprintf(b, sizeof(b), "%*d", w, n); 68187715Smarkm if ((int)strlen(b) > w) { 6821590Srgrimes while (w-- > 0) 6831590Srgrimes addch('*'); 6841590Srgrimes return; 6851590Srgrimes } 6861590Srgrimes addstr(b); 6871590Srgrimes} 6881590Srgrimes 6891590Srgrimesstatic void 69087715Smarkmputfloat(f, l, lc, w, d, nz) 6911590Srgrimes double f; 69287715Smarkm int l, lc, w, d, nz; 6931590Srgrimes{ 6941590Srgrimes char b[128]; 6951590Srgrimes 69687715Smarkm move(l, lc); 6971590Srgrimes if (nz && f == 0.0) { 6981590Srgrimes while (--w >= 0) 6991590Srgrimes addch(' '); 7001590Srgrimes return; 7011590Srgrimes } 70236789Simp snprintf(b, sizeof(b), "%*.*f", w, d, f); 70387715Smarkm if ((int)strlen(b) > w) 70444935Sbde snprintf(b, sizeof(b), "%*.0f", w, f); 70587715Smarkm if ((int)strlen(b) > w) { 7061590Srgrimes while (--w >= 0) 7071590Srgrimes addch('*'); 7081590Srgrimes return; 7091590Srgrimes } 7101590Srgrimes addstr(b); 7111590Srgrimes} 7121590Srgrimes 7131590Srgrimesstatic void 71487715Smarkmputlongdouble(f, l, lc, w, d, nz) 71539230Sgibbs long double f; 71687715Smarkm int l, lc, w, d, nz; 71739230Sgibbs{ 71839230Sgibbs char b[128]; 71939230Sgibbs 72087715Smarkm move(l, lc); 72139230Sgibbs if (nz && f == 0.0) { 72239230Sgibbs while (--w >= 0) 72339230Sgibbs addch(' '); 72439230Sgibbs return; 72539230Sgibbs } 72639230Sgibbs sprintf(b, "%*.*Lf", w, d, f); 72787715Smarkm if ((int)strlen(b) > w) 72844935Sbde sprintf(b, "%*.0Lf", w, f); 72987715Smarkm if ((int)strlen(b) > w) { 73039230Sgibbs while (--w >= 0) 73139230Sgibbs addch('*'); 73239230Sgibbs return; 73339230Sgibbs } 73439230Sgibbs addstr(b); 73539230Sgibbs} 73639230Sgibbs 73739230Sgibbsstatic void 73887715Smarkmgetinfo(ls) 73987715Smarkm struct Info *ls; 7401590Srgrimes{ 74139230Sgibbs struct devinfo *tmp_dinfo; 74274671Stmm size_t size; 74374671Stmm int mib[2]; 7441590Srgrimes 74587715Smarkm GETSYSCTL("kern.cp_time", ls->time); 74674671Stmm GETSYSCTL("kern.cp_time", cur.cp_time); 74787715Smarkm GETSYSCTL("vm.stats.sys.v_swtch", ls->v_swtch); 74887715Smarkm GETSYSCTL("vm.stats.sys.v_trap", ls->v_trap); 74987715Smarkm GETSYSCTL("vm.stats.sys.v_syscall", ls->v_syscall); 75087715Smarkm GETSYSCTL("vm.stats.sys.v_intr", ls->v_intr); 75187715Smarkm GETSYSCTL("vm.stats.sys.v_soft", ls->v_soft); 75287715Smarkm GETSYSCTL("vm.stats.vm.v_vm_faults", ls->v_vm_faults); 75387715Smarkm GETSYSCTL("vm.stats.vm.v_cow_faults", ls->v_cow_faults); 75487715Smarkm GETSYSCTL("vm.stats.vm.v_zfod", ls->v_zfod); 75587715Smarkm GETSYSCTL("vm.stats.vm.v_ozfod", ls->v_ozfod); 75687715Smarkm GETSYSCTL("vm.stats.vm.v_swapin", ls->v_swapin); 75787715Smarkm GETSYSCTL("vm.stats.vm.v_swapout", ls->v_swapout); 75887715Smarkm GETSYSCTL("vm.stats.vm.v_swappgsin", ls->v_swappgsin); 75987715Smarkm GETSYSCTL("vm.stats.vm.v_swappgsout", ls->v_swappgsout); 76087715Smarkm GETSYSCTL("vm.stats.vm.v_vnodein", ls->v_vnodein); 76187715Smarkm GETSYSCTL("vm.stats.vm.v_vnodeout", ls->v_vnodeout); 76287715Smarkm GETSYSCTL("vm.stats.vm.v_vnodepgsin", ls->v_vnodepgsin); 76387715Smarkm GETSYSCTL("vm.stats.vm.v_vnodepgsout", ls->v_vnodepgsout); 76487715Smarkm GETSYSCTL("vm.stats.vm.v_intrans", ls->v_intrans); 76587715Smarkm GETSYSCTL("vm.stats.vm.v_reactivated", ls->v_reactivated); 76687715Smarkm GETSYSCTL("vm.stats.vm.v_pdwakeups", ls->v_pdwakeups); 76787715Smarkm GETSYSCTL("vm.stats.vm.v_pdpages", ls->v_pdpages); 76887715Smarkm GETSYSCTL("vm.stats.vm.v_dfree", ls->v_dfree); 76987715Smarkm GETSYSCTL("vm.stats.vm.v_pfree", ls->v_pfree); 77087715Smarkm GETSYSCTL("vm.stats.vm.v_tfree", ls->v_tfree); 77187715Smarkm GETSYSCTL("vm.stats.vm.v_page_size", ls->v_page_size); 77287715Smarkm GETSYSCTL("vm.stats.vm.v_free_count", ls->v_free_count); 77387715Smarkm GETSYSCTL("vm.stats.vm.v_wire_count", ls->v_wire_count); 77487715Smarkm GETSYSCTL("vm.stats.vm.v_active_count", ls->v_active_count); 77587715Smarkm GETSYSCTL("vm.stats.vm.v_inactive_count", ls->v_inactive_count); 77687715Smarkm GETSYSCTL("vm.stats.vm.v_cache_count", ls->v_cache_count); 77787715Smarkm GETSYSCTL("vfs.bufspace", ls->bufspace); 77887715Smarkm GETSYSCTL("kern.maxvnodes", ls->desiredvnodes); 77997970Sdes GETSYSCTL("vfs.numvnodes", ls->numvnodes); 78097970Sdes GETSYSCTL("vfs.freevnodes", ls->freevnodes); 78187715Smarkm GETSYSCTL("vfs.cache.nchstats", ls->nchstats); 78287715Smarkm GETSYSCTL("vfs.numdirtybuffers", ls->numdirtybuffers); 78387715Smarkm getsysctl("hw.intrcnt", ls->intrcnt, nintr * sizeof(u_long)); 78469143Srwatson 78587715Smarkm size = sizeof(ls->Total); 7861590Srgrimes mib[0] = CTL_VM; 7871590Srgrimes mib[1] = VM_METER; 78887715Smarkm if (sysctl(mib, 2, &ls->Total, &size, NULL, 0) < 0) { 7891590Srgrimes error("Can't get kernel info: %s\n", strerror(errno)); 79087715Smarkm bzero(&ls->Total, sizeof(ls->Total)); 7911590Srgrimes } 79236430Sjhay size = sizeof(ncpu); 79369143Srwatson if (sysctlbyname("hw.ncpu", &ncpu, &size, NULL, 0) < 0 || 79469143Srwatson size != sizeof(ncpu)) 79536430Sjhay ncpu = 1; 79639230Sgibbs 79739230Sgibbs tmp_dinfo = last.dinfo; 79839230Sgibbs last.dinfo = cur.dinfo; 79939230Sgibbs cur.dinfo = tmp_dinfo; 80039230Sgibbs 80139230Sgibbs last.busy_time = cur.busy_time; 80283131Sken switch (devstat_getdevs(NULL, &cur)) { 80339230Sgibbs case -1: 80439230Sgibbs errx(1, "%s", devstat_errbuf); 80539230Sgibbs break; 80639230Sgibbs case 1: 80739230Sgibbs num_devices = cur.dinfo->numdevs; 80839230Sgibbs generation = cur.dinfo->generation; 80939230Sgibbs cmdkre("refresh", NULL); 81039230Sgibbs break; 81139230Sgibbs default: 81239230Sgibbs break; 81339230Sgibbs } 8141590Srgrimes} 8151590Srgrimes 8161590Srgrimesstatic void 81787715Smarkmallocinfo(ls) 81887715Smarkm struct Info *ls; 8191590Srgrimes{ 8201590Srgrimes 82187715Smarkm ls->intrcnt = (long *) calloc(nintr, sizeof(long)); 82287715Smarkm if (ls->intrcnt == NULL) 82328149Scharnier errx(2, "out of memory"); 8241590Srgrimes} 8251590Srgrimes 8261590Srgrimesstatic void 8271590Srgrimescopyinfo(from, to) 82887715Smarkm struct Info *from, *to; 8291590Srgrimes{ 8301590Srgrimes long *intrcnt; 8311590Srgrimes 8321590Srgrimes /* 8331590Srgrimes * time, wds, seek, and xfer are malloc'd so we have to 8348874Srgrimes * save the pointers before the structure copy and then 8351590Srgrimes * copy by hand. 8361590Srgrimes */ 83739230Sgibbs intrcnt = to->intrcnt; 8381590Srgrimes *to = *from; 83939230Sgibbs 8401590Srgrimes bcopy(from->intrcnt, to->intrcnt = intrcnt, nintr * sizeof (int)); 8411590Srgrimes} 8421590Srgrimes 8431590Srgrimesstatic void 84487715Smarkmdinfo(dn, lc, now, then) 84587715Smarkm int dn, lc; 84639230Sgibbs struct statinfo *now, *then; 8471590Srgrimes{ 84839230Sgibbs long double transfers_per_second; 84939230Sgibbs long double kb_per_transfer, mb_per_second; 85049245Sdes long double elapsed_time, device_busy; 85139230Sgibbs int di; 8521590Srgrimes 85339230Sgibbs di = dev_select[dn].position; 85439230Sgibbs 85583131Sken elapsed_time = devstat_compute_etime(now->busy_time, 85683131Sken then ? then->busy_time : now->dinfo->devices[di].dev_creation_time); 85739230Sgibbs 85883131Sken device_busy = devstat_compute_etime(now->dinfo->devices[di].busy_time, 85983131Sken then ? then->dinfo->devices[di].busy_time : 86083131Sken now->dinfo->devices[di].dev_creation_time); 86149245Sdes 86283131Sken if (devstat_compute_statistics(&now->dinfo->devices[di], then ? 86383131Sken &then->dinfo->devices[di] : NULL, elapsed_time, 86483131Sken DSM_KB_PER_TRANSFER, &kb_per_transfer, DSM_TRANSFERS_PER_SECOND, 86583131Sken &transfers_per_second, DSM_MB_PER_SECOND, &mb_per_second, 86683131Sken DSM_NONE) != 0) 86739230Sgibbs errx(1, "%s", devstat_errbuf); 86839230Sgibbs 86949245Sdes if ((device_busy == 0) && (transfers_per_second > 5)) 87049245Sdes /* the device has been 100% busy, fake it because 87149245Sdes * as long as the device is 100% busy the busy_time 87249245Sdes * field in the devstat struct is not updated */ 87349245Sdes device_busy = elapsed_time; 87449245Sdes if (device_busy > elapsed_time) 87549245Sdes /* this normally happens after one or more periods 87649245Sdes * where the device has been 100% busy, correct it */ 87749245Sdes device_busy = elapsed_time; 87849245Sdes 87987715Smarkm lc = DISKCOL + lc * 6; 88087715Smarkm putlongdouble(kb_per_transfer, DISKROW + 1, lc, 5, 2, 0); 88187715Smarkm putlongdouble(transfers_per_second, DISKROW + 2, lc, 5, 0, 0); 88287715Smarkm putlongdouble(mb_per_second, DISKROW + 3, lc, 5, 2, 0); 88387715Smarkm putlongdouble(device_busy * 100 / elapsed_time, DISKROW + 4, lc, 5, 0, 0); 8841590Srgrimes} 885