121585Sdist /* 221585Sdist * Copyright (c) 1980 Regents of the University of California. 321585Sdist * All rights reserved. The Berkeley software License Agreement 421585Sdist * specifies the terms and conditions for redistribution. 521585Sdist */ 621585Sdist 710826Ssam #ifndef lint 821585Sdist char copyright[] = 921585Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 1021585Sdist All rights reserved.\n"; 1121585Sdist #endif not lint 1210826Ssam 1321585Sdist #ifndef lint 14*25960Ssam static char sccsid[] = "@(#)vmstat.c 5.5 (Berkeley) 01/24/86"; 1521585Sdist #endif not lint 1621585Sdist 171155Sbill #include <stdio.h> 1818761Ssam #include <ctype.h> 1918761Ssam #include <nlist.h> 2018761Ssam 211155Sbill #include <sys/param.h> 2218761Ssam #include <sys/file.h> 231155Sbill #include <sys/vm.h> 241155Sbill #include <sys/dk.h> 253162Stoy #include <sys/buf.h> 2615807Smckusick #include <sys/dir.h> 2718761Ssam #include <sys/inode.h> 2817262Smckusick #include <sys/namei.h> 2925708Ssam #include <sys/text.h> 301155Sbill 311155Sbill struct nlist nl[] = { 321448Sbill #define X_CPTIME 0 331448Sbill { "_cp_time" }, 341448Sbill #define X_RATE 1 351155Sbill { "_rate" }, 361448Sbill #define X_TOTAL 2 371155Sbill { "_total" }, 381448Sbill #define X_DEFICIT 3 391155Sbill { "_deficit" }, 401448Sbill #define X_FORKSTAT 4 411155Sbill { "_forkstat" }, 421448Sbill #define X_SUM 5 431155Sbill { "_sum" }, 441448Sbill #define X_FIRSTFREE 6 451155Sbill { "_firstfree" }, 461448Sbill #define X_MAXFREE 7 471155Sbill { "_maxfree" }, 489249Ssam #define X_BOOTTIME 8 499249Ssam { "_boottime" }, 501448Sbill #define X_DKXFER 9 511448Sbill { "_dk_xfer" }, 5210826Ssam #define X_REC 10 531155Sbill { "_rectime" }, 5410826Ssam #define X_PGIN 11 551155Sbill { "_pgintime" }, 5610826Ssam #define X_HZ 12 573162Stoy { "_hz" }, 5818761Ssam #define X_PHZ 13 5915266Ssam { "_phz" }, 6015807Smckusick #define X_NCHSTATS 14 6115807Smckusick { "_nchstats" }, 6217262Smckusick #define X_INTRNAMES 15 6317262Smckusick { "_intrnames" }, 6417262Smckusick #define X_EINTRNAMES 16 6517262Smckusick { "_eintrnames" }, 6617262Smckusick #define X_INTRCNT 17 6717262Smckusick { "_intrcnt" }, 6817262Smckusick #define X_EINTRCNT 18 6917262Smckusick { "_eintrcnt" }, 7018761Ssam #define X_DK_NDRIVE 19 7118761Ssam { "_dk_ndrive" }, 7225512Ssam #define X_XSTATS 20 7325512Ssam { "_xstats" }, 7410826Ssam #ifdef vax 7525708Ssam #define X_MBDINIT (X_XSTATS+1) 7610826Ssam { "_mbdinit" }, 7725708Ssam #define X_UBDINIT (X_XSTATS+2) 7810826Ssam { "_ubdinit" }, 7910826Ssam #endif 8025708Ssam #ifdef sun 8125708Ssam #define X_MBDINIT (X_XSTATS+1) 8225708Ssam { "_mbdinit" }, 8325708Ssam #endif 8425708Ssam #ifdef tahoe 8525708Ssam #define X_VBDINIT (X_XSTATS+1) 8625708Ssam { "_vbdinit" }, 87*25960Ssam #define X_CKEYSTATS (X_XSTATS+2) 88*25960Ssam { "_ckeystats" }, 89*25960Ssam #define X_DKEYSTATS (X_XSTATS+3) 90*25960Ssam { "_dkeystats" }, 9125708Ssam #endif 9210826Ssam { "" }, 931155Sbill }; 941155Sbill 9518761Ssam char **dr_name; 9618761Ssam int *dr_select; 9718761Ssam int dk_ndrive; 9818761Ssam int ndrives = 0; 9918761Ssam #ifdef vax 10018761Ssam char *defdrives[] = { "hp0", "hp1", "hp2", 0 }; 10118761Ssam #else 10218761Ssam char *defdrives[] = { 0 }; 10318761Ssam #endif 1041155Sbill double stat1(); 1051155Sbill int firstfree, maxfree; 1063162Stoy int hz; 10715266Ssam int phz; 10815266Ssam int HZ; 10918761Ssam 11018761Ssam struct { 1111155Sbill int busy; 1121448Sbill long time[CPUSTATES]; 11318761Ssam long *xfer; 1141155Sbill struct vmmeter Rate; 1151155Sbill struct vmtotal Total; 1161155Sbill struct vmmeter Sum; 1171155Sbill struct forkstat Forkstat; 1181155Sbill unsigned rectime; 1191155Sbill unsigned pgintime; 1201155Sbill } s, s1, z; 1211155Sbill #define rate s.Rate 1221155Sbill #define total s.Total 1231155Sbill #define sum s.Sum 1241155Sbill #define forkstat s.Forkstat 1251155Sbill 12610826Ssam struct vmmeter osum; 1271155Sbill int zero; 1281155Sbill int deficit; 1291155Sbill double etime; 1301155Sbill int mf; 13117262Smckusick time_t now, boottime; 13217262Smckusick int printhdr(); 13318768Ssam int lines = 1; 1341155Sbill 1351155Sbill main(argc, argv) 13610826Ssam int argc; 13710826Ssam char **argv; 1381155Sbill { 1391155Sbill extern char *ctime(); 1401155Sbill register i,j; 14117262Smckusick int iter, nintv, iflag = 0; 1421155Sbill double f1, f2; 1431155Sbill long t; 14418761Ssam char *arg, **cp, name[6], buf[BUFSIZ]; 1451155Sbill 1461155Sbill nlist("/vmunix", nl); 1471155Sbill if(nl[0].n_type == 0) { 1481155Sbill printf("no /vmunix namelist\n"); 1491155Sbill exit(1); 1501155Sbill } 1511155Sbill mf = open("/dev/kmem", 0); 1521155Sbill if(mf < 0) { 1531155Sbill printf("cannot open /dev/kmem\n"); 1541155Sbill exit(1); 1551155Sbill } 1561155Sbill iter = 0; 1571155Sbill argc--, argv++; 1581155Sbill while (argc>0 && argv[0][0]=='-') { 1591155Sbill char *cp = *argv++; 1601155Sbill argc--; 1611155Sbill while (*++cp) switch (*cp) { 1621155Sbill 1631155Sbill case 't': 1641155Sbill dotimes(); 1651155Sbill exit(0); 16610826Ssam 1671155Sbill case 'z': 1681155Sbill close(mf); 1691155Sbill mf = open("/dev/kmem", 2); 17018761Ssam lseek(mf, (long)nl[X_SUM].n_value, L_SET); 1711155Sbill write(mf, &z.Sum, sizeof z.Sum); 1721155Sbill exit(0); 1731155Sbill 1741155Sbill case 'f': 1751155Sbill doforkst(); 1761155Sbill exit(0); 1771155Sbill 1781155Sbill case 's': 1791155Sbill dosum(); 1801155Sbill exit(0); 1811155Sbill 18217262Smckusick case 'i': 18317262Smckusick iflag++; 18417262Smckusick break; 18517262Smckusick 1861155Sbill default: 18718761Ssam fprintf(stderr, 18818761Ssam "usage: vmstat [ -fsi ] [ interval ] [ count]\n"); 1891155Sbill exit(1); 1901155Sbill } 1911155Sbill } 19218761Ssam lseek(mf, (long)nl[X_FIRSTFREE].n_value, L_SET); 1931155Sbill read(mf, &firstfree, sizeof firstfree); 19418761Ssam lseek(mf, (long)nl[X_MAXFREE].n_value, L_SET); 1951155Sbill read(mf, &maxfree, sizeof maxfree); 19618761Ssam lseek(mf, (long)nl[X_BOOTTIME].n_value, L_SET); 1979249Ssam read(mf, &boottime, sizeof boottime); 19818761Ssam lseek(mf, (long)nl[X_HZ].n_value, L_SET); 1993162Stoy read(mf, &hz, sizeof hz); 20018761Ssam if (nl[X_PHZ].n_value != 0) { 20118761Ssam lseek(mf, (long)nl[X_PHZ].n_value, L_SET); 20218761Ssam read(mf, &phz, sizeof phz); 20318761Ssam } 20415266Ssam HZ = phz ? phz : hz; 20518761Ssam if (nl[DK_NDRIVE].n_value == 0) { 20618761Ssam printf("dk_ndrive undefined in system\n"); 20718761Ssam exit(1); 2083162Stoy } 20918761Ssam lseek(mf, nl[X_DK_NDRIVE].n_value, L_SET); 21018761Ssam read(mf, &dk_ndrive, sizeof (dk_ndrive)); 21118761Ssam if (dk_ndrive <= 0) { 21218761Ssam printf("dk_ndrive %d\n", dk_ndrive); 21318761Ssam exit(1); 21418761Ssam } 21518761Ssam dr_select = (int *)calloc(dk_ndrive, sizeof (int)); 21618761Ssam dr_name = (char **)calloc(dk_ndrive, sizeof (char *)); 21718761Ssam #define allocate(e, t) \ 21818761Ssam s./**/e = (t *)calloc(dk_ndrive, sizeof (t)); \ 21918761Ssam s1./**/e = (t *)calloc(dk_ndrive, sizeof (t)); 22018761Ssam allocate(xfer, long); 22118761Ssam for (arg = buf, i = 0; i < dk_ndrive; i++) { 22218761Ssam dr_name[i] = arg; 22318761Ssam sprintf(dr_name[i], "dk%d", i); 22418761Ssam arg += strlen(dr_name[i]) + 1; 22518761Ssam } 2263162Stoy read_names(); 2271155Sbill time(&now); 2289249Ssam nintv = now - boottime; 2291155Sbill if (nintv <= 0 || nintv > 60*60*24*365*10) { 2301155Sbill printf("Time makes no sense... namelist must be wrong.\n"); 2311155Sbill exit(1); 2321155Sbill } 23317262Smckusick if (iflag) { 23417262Smckusick dointr(nintv); 23517262Smckusick exit(0); 23617262Smckusick } 23718761Ssam /* 23818761Ssam * Choose drives to be displayed. Priority 23918761Ssam * goes to (in order) drives supplied as arguments, 24018761Ssam * default drives. If everything isn't filled 24118761Ssam * in and there are drives not taken care of, 24218761Ssam * display the first few that fit. 24318761Ssam */ 24418761Ssam ndrives = 0; 24518761Ssam while (argc > 0 && !isdigit(argv[0][0])) { 24618761Ssam for (i = 0; i < dk_ndrive; i++) { 24718761Ssam if (strcmp(dr_name[i], argv[0])) 24818761Ssam continue; 24918761Ssam dr_select[i] = 1; 25018761Ssam ndrives++; 25118761Ssam } 25218761Ssam argc--, argv++; 25318761Ssam } 25418761Ssam for (i = 0; i < dk_ndrive && ndrives < 4; i++) { 25518761Ssam if (dr_select[i]) 25618761Ssam continue; 25718761Ssam for (cp = defdrives; *cp; cp++) 25818761Ssam if (strcmp(dr_name[i], *cp) == 0) { 25918761Ssam dr_select[i] = 1; 26018761Ssam ndrives++; 26118761Ssam break; 26218761Ssam } 26318761Ssam } 26418761Ssam for (i = 0; i < dk_ndrive && ndrives < 4; i++) { 26518761Ssam if (dr_select[i]) 26618761Ssam continue; 26718761Ssam dr_select[i] = 1; 26818761Ssam ndrives++; 26918761Ssam } 27018761Ssam if (argc > 1) 27118761Ssam iter = atoi(argv[1]); 27217262Smckusick signal(SIGCONT, printhdr); 2731155Sbill loop: 27418768Ssam if (--lines == 0) 27518768Ssam printhdr(); 27618761Ssam lseek(mf, (long)nl[X_CPTIME].n_value, L_SET); 2771448Sbill read(mf, s.time, sizeof s.time); 27818761Ssam lseek(mf, (long)nl[X_DKXFER].n_value, L_SET); 27918761Ssam read(mf, s.xfer, dk_ndrive * sizeof (long)); 28018761Ssam if (nintv != 1) 28118761Ssam lseek(mf, (long)nl[X_SUM].n_value, L_SET); 28218761Ssam else 28318761Ssam lseek(mf, (long)nl[X_RATE].n_value, L_SET); 28418761Ssam read(mf, &rate, sizeof rate); 28518761Ssam lseek(mf, (long)nl[X_TOTAL].n_value, L_SET); 2861155Sbill read(mf, &total, sizeof total); 28710826Ssam osum = sum; 28818761Ssam lseek(mf, (long)nl[X_SUM].n_value, L_SET); 28910826Ssam read(mf, &sum, sizeof sum); 29018761Ssam lseek(mf, (long)nl[X_DEFICIT].n_value, L_SET); 2911155Sbill read(mf, &deficit, sizeof deficit); 2921448Sbill etime = 0; 29318761Ssam for (i=0; i < dk_ndrive; i++) { 2941448Sbill t = s.xfer[i]; 2951448Sbill s.xfer[i] -= s1.xfer[i]; 2961448Sbill s1.xfer[i] = t; 2971155Sbill } 2981155Sbill for (i=0; i < CPUSTATES; i++) { 2991448Sbill t = s.time[i]; 3001448Sbill s.time[i] -= s1.time[i]; 3011448Sbill s1.time[i] = t; 3021448Sbill etime += s.time[i]; 3031155Sbill } 3041155Sbill if(etime == 0.) 3051155Sbill etime = 1.; 3063162Stoy printf("%2d%2d%2d", total.t_rq, total.t_dw+total.t_pw, total.t_sw); 30710826Ssam #define pgtok(a) ((a)*NBPG/1024) 30810826Ssam printf("%6d%5d", pgtok(total.t_avm), pgtok(total.t_free)); 30915266Ssam printf("%4d%3d", (rate.v_pgrec - (rate.v_xsfrec+rate.v_xifrec))/nintv, 31015266Ssam (rate.v_xsfrec+rate.v_xifrec)/nintv); 31110826Ssam printf("%4d", pgtok(rate.v_pgpgin)/nintv); 31210826Ssam printf("%4d%4d%4d%4d", pgtok(rate.v_pgpgout)/nintv, 31310826Ssam pgtok(rate.v_dfree)/nintv, pgtok(deficit), rate.v_scan/nintv); 31418761Ssam etime /= (float)HZ; 31518761Ssam for (i = 0; i < dk_ndrive; i++) 31618761Ssam if (dr_select[i]) 31718761Ssam stats(i); 31825708Ssam #define INTS(x) ((x) - (hz + phz)) 31915266Ssam printf("%4d%4d%4d", INTS(rate.v_intr/nintv), rate.v_syscall/nintv, 32015266Ssam rate.v_swtch/nintv); 3211155Sbill for(i=0; i<CPUSTATES; i++) { 3221155Sbill float f = stat1(i); 3231155Sbill if (i == 0) { /* US+NI */ 3241155Sbill i++; 3251155Sbill f += stat1(i); 3261155Sbill } 3271155Sbill printf("%3.0f", f); 3281155Sbill } 3291155Sbill printf("\n"); 3301155Sbill fflush(stdout); 3311155Sbill contin: 3321155Sbill nintv = 1; 33318768Ssam if (--iter &&argc > 0) { 3341155Sbill sleep(atoi(argv[0])); 3351155Sbill goto loop; 3361155Sbill } 3371155Sbill } 3381155Sbill 33917262Smckusick printhdr() 34017262Smckusick { 34118761Ssam register int i, j; 34218761Ssam 34318761Ssam printf(" procs memory page "); 34418761Ssam i = (ndrives * 3 - 6) / 2; 34518761Ssam if (i < 0) 34618761Ssam i = 0; 34718761Ssam for (j = 0; j < i; j++) 34818761Ssam putchar(' '); 34918761Ssam printf("faults"); 35018761Ssam i = ndrives * 3 - 6 - i; 35118761Ssam for (j = 0; j < i; j++) 35218761Ssam putchar(' '); 35318761Ssam printf(" cpu\n"); 35418761Ssam printf(" r b w avm fre re at pi po fr de sr "); 35518761Ssam for (i = 0; i < dk_ndrive; i++) 35618761Ssam if (dr_select[i]) 35718761Ssam printf("%c%c ", dr_name[i][0], dr_name[i][2]); 35818761Ssam printf(" in sy cs us sy id\n"); 35918768Ssam lines = 19; 36017262Smckusick } 36117262Smckusick 3621155Sbill dotimes() 3631155Sbill { 3641155Sbill 36518761Ssam lseek(mf, (long)nl[X_REC].n_value, L_SET); 3661155Sbill read(mf, &s.rectime, sizeof s.rectime); 36718761Ssam lseek(mf, (long)nl[X_PGIN].n_value, L_SET); 3681155Sbill read(mf, &s.pgintime, sizeof s.pgintime); 36918761Ssam lseek(mf, (long)nl[X_SUM].n_value, L_SET); 3701155Sbill read(mf, &sum, sizeof sum); 3711155Sbill printf("%d reclaims, %d total time (usec)\n", sum.v_pgrec, s.rectime); 3721155Sbill printf("average: %d usec / reclaim\n", s.rectime/sum.v_pgrec); 3731155Sbill printf("\n"); 3741155Sbill printf("%d page ins, %d total time (msec)\n",sum.v_pgin, s.pgintime/10); 3751155Sbill printf("average: %8.1f msec / page in\n", s.pgintime/(sum.v_pgin*10.0)); 3761155Sbill } 3771155Sbill 3781155Sbill dosum() 3791155Sbill { 38018761Ssam struct nchstats nchstats; 381*25960Ssam struct xstats xstats; 38215807Smckusick long nchtotal; 383*25960Ssam #if defined(tahoe) 384*25960Ssam struct keystats keystats; 385*25960Ssam #endif 3861155Sbill 38718761Ssam lseek(mf, (long)nl[X_SUM].n_value, L_SET); 3881155Sbill read(mf, &sum, sizeof sum); 3891155Sbill printf("%9d swap ins\n", sum.v_swpin); 3901155Sbill printf("%9d swap outs\n", sum.v_swpout); 3911155Sbill printf("%9d pages swapped in\n", sum.v_pswpin / CLSIZE); 3921155Sbill printf("%9d pages swapped out\n", sum.v_pswpout / CLSIZE); 3931155Sbill printf("%9d total address trans. faults taken\n", sum.v_faults); 3941155Sbill printf("%9d page ins\n", sum.v_pgin); 3951155Sbill printf("%9d page outs\n", sum.v_pgout); 3963612Sroot printf("%9d pages paged in\n", sum.v_pgpgin); 3973612Sroot printf("%9d pages paged out\n", sum.v_pgpgout); 3983612Sroot printf("%9d sequential process pages freed\n", sum.v_seqfree); 39925708Ssam #define nz(x) ((x) ? (x) : 1) 40012830Ssam printf("%9d total reclaims (%d%% fast)\n", sum.v_pgrec, 40125708Ssam (sum.v_fastpgrec * 100) / nz(sum.v_pgrec)); 4021155Sbill printf("%9d reclaims from free list\n", sum.v_pgfrec); 4031155Sbill printf("%9d intransit blocking page faults\n", sum.v_intrans); 4041155Sbill printf("%9d zero fill pages created\n", sum.v_nzfod / CLSIZE); 4051155Sbill printf("%9d zero fill page faults\n", sum.v_zfod / CLSIZE); 4061155Sbill printf("%9d executable fill pages created\n", sum.v_nexfod / CLSIZE); 4071155Sbill printf("%9d executable fill page faults\n", sum.v_exfod / CLSIZE); 4081155Sbill printf("%9d swap text pages found in free list\n", sum.v_xsfrec); 4091155Sbill printf("%9d inode text pages found in free list\n", sum.v_xifrec); 4101155Sbill printf("%9d file fill pages created\n", sum.v_nvrfod / CLSIZE); 4111155Sbill printf("%9d file fill page faults\n", sum.v_vrfod / CLSIZE); 4121155Sbill printf("%9d pages examined by the clock daemon\n", sum.v_scan); 4131155Sbill printf("%9d revolutions of the clock hand\n", sum.v_rev); 4141155Sbill printf("%9d pages freed by the clock daemon\n", sum.v_dfree / CLSIZE); 4151155Sbill printf("%9d cpu context switches\n", sum.v_swtch); 4161155Sbill printf("%9d device interrupts\n", sum.v_intr); 41717262Smckusick printf("%9d software interrupts\n", sum.v_soft); 41818761Ssam #ifdef vax 41924429Smckusick printf("%9d pseudo-dma dz interrupts\n", sum.v_pdma); 42018761Ssam #endif 4211155Sbill printf("%9d traps\n", sum.v_trap); 4221155Sbill printf("%9d system calls\n", sum.v_syscall); 42315807Smckusick lseek(mf, (long)nl[X_NCHSTATS].n_value, 0); 42418761Ssam read(mf, &nchstats, sizeof nchstats); 42518761Ssam nchtotal = nchstats.ncs_goodhits + nchstats.ncs_badhits + 42618761Ssam nchstats.ncs_falsehits + nchstats.ncs_miss + nchstats.ncs_long; 42715807Smckusick printf("%9d total name lookups", nchtotal); 42815807Smckusick printf(" (cache hits %d%% system %d%% per-process)\n", 42918761Ssam nchstats.ncs_goodhits * 100 / nz(nchtotal), 43018761Ssam nchstats.ncs_pass2 * 100 / nz(nchtotal)); 43116586Ssam printf("%9s badhits %d, falsehits %d, toolong %d\n", "", 43218761Ssam nchstats.ncs_badhits, nchstats.ncs_falsehits, nchstats.ncs_long); 43325512Ssam lseek(mf, (long)nl[X_XSTATS].n_value, 0); 43425512Ssam read(mf, &xstats, sizeof xstats); 43525512Ssam printf("%9d total calls to xalloc (cache hits %d%%)\n", 43625512Ssam xstats.alloc, xstats.alloc_cachehit * 100 / nz(xstats.alloc)); 43725512Ssam printf("%9s sticky %d flushed %d unused %d\n", "", 43825512Ssam xstats.alloc_inuse, xstats.alloc_cacheflush, xstats.alloc_unused); 43925512Ssam printf("%9d total calls to xfree", xstats.free); 44025512Ssam printf(" (sticky %d cached %d swapped %d)\n", 44125512Ssam xstats.free_inuse, xstats.free_cache, xstats.free_cacheswap); 442*25960Ssam #if defined(tahoe) 443*25960Ssam lseek(mf, (long)nl[X_CKEYSTATS].n_value, 0); 444*25960Ssam read(mf, &keystats, sizeof keystats); 445*25960Ssam printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n", 446*25960Ssam keystats.ks_allocs, "code cache keys allocated", 447*25960Ssam keystats.ks_free * 100 / nz(keystats.ks_allocs), 448*25960Ssam keystats.ks_norefs * 100 / nz(keystats.ks_allocs), 449*25960Ssam keystats.ks_taken * 100 / nz(keystats.ks_allocs), 450*25960Ssam keystats.ks_shared * 100 / nz(keystats.ks_allocs)); 451*25960Ssam lseek(mf, (long)nl[X_DKEYSTATS].n_value, 0); 452*25960Ssam read(mf, &keystats, sizeof keystats); 453*25960Ssam printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n", 454*25960Ssam keystats.ks_allocs, "data cache keys allocated", 455*25960Ssam keystats.ks_free * 100 / nz(keystats.ks_allocs), 456*25960Ssam keystats.ks_norefs * 100 / nz(keystats.ks_allocs), 457*25960Ssam keystats.ks_taken * 100 / nz(keystats.ks_allocs), 458*25960Ssam keystats.ks_shared * 100 / nz(keystats.ks_allocs)); 459*25960Ssam #endif 4601155Sbill } 4611155Sbill 4621155Sbill doforkst() 4631155Sbill { 4641155Sbill 46518761Ssam lseek(mf, (long)nl[X_FORKSTAT].n_value, L_SET); 4661155Sbill read(mf, &forkstat, sizeof forkstat); 4671155Sbill printf("%d forks, %d pages, average=%.2f\n", 4681155Sbill forkstat.cntfork, forkstat.sizfork, 4691155Sbill (float) forkstat.sizfork / forkstat.cntfork); 4701155Sbill printf("%d vforks, %d pages, average=%.2f\n", 4711155Sbill forkstat.cntvfork, forkstat.sizvfork, 4721155Sbill (float)forkstat.sizvfork / forkstat.cntvfork); 4731155Sbill } 4741155Sbill 4751155Sbill stats(dn) 4761155Sbill { 4771155Sbill 47818761Ssam if (dn >= dk_ndrive) { 4791155Sbill printf(" 0"); 4801155Sbill return; 4811155Sbill } 4821448Sbill printf("%3.0f", s.xfer[dn]/etime); 4831155Sbill } 4841155Sbill 4851155Sbill double 4861155Sbill stat1(row) 4871155Sbill { 4881448Sbill double t; 4891448Sbill register i; 4901155Sbill 4911155Sbill t = 0; 4921155Sbill for(i=0; i<CPUSTATES; i++) 4931448Sbill t += s.time[i]; 4941448Sbill if(t == 0.) 4951448Sbill t = 1.; 4961448Sbill return(s.time[row]*100./t); 4971155Sbill } 4981155Sbill 4991155Sbill pct(top, bot) 5001155Sbill { 5011155Sbill 5021155Sbill if (bot == 0) 5031155Sbill return (0); 5041155Sbill return ((top * 100) / bot); 5051155Sbill } 5063162Stoy 50717262Smckusick dointr(nintv) 50817262Smckusick { 50917262Smckusick int nintr, inttotal; 51017262Smckusick long *intrcnt; 51117262Smckusick char *intrname, *malloc(); 51217262Smckusick 51317262Smckusick nintr = (nl[X_EINTRCNT].n_value - nl[X_INTRCNT].n_value) / sizeof(long); 51417262Smckusick intrcnt = (long *) malloc(nl[X_EINTRCNT].n_value - 51517262Smckusick nl[X_INTRCNT].n_value); 51617262Smckusick intrname = malloc(nl[X_EINTRNAMES].n_value - nl[X_INTRNAMES].n_value); 51717262Smckusick if (intrcnt == NULL || intrname == NULL) { 51817262Smckusick fprintf(stderr, "vmstat: out of memory\n"); 51917262Smckusick exit(9); 52017262Smckusick } 52118761Ssam lseek(mf, (long)nl[X_INTRCNT].n_value, L_SET); 52217262Smckusick read(mf, intrcnt, nintr * sizeof (long)); 52318761Ssam lseek(mf, (long)nl[X_INTRNAMES].n_value, L_SET); 52417262Smckusick read(mf, intrname, nl[X_EINTRNAMES].n_value - nl[X_INTRNAMES].n_value); 52517262Smckusick printf("interrupt total rate\n"); 52617262Smckusick inttotal = 0; 52717262Smckusick while (nintr--) { 52817262Smckusick if (*intrcnt) 52917262Smckusick printf("%-12s %8ld %8ld\n", intrname, 53017262Smckusick *intrcnt, *intrcnt / nintv); 53117262Smckusick intrname += strlen(intrname) + 1; 53217262Smckusick inttotal += *intrcnt++; 53317262Smckusick } 53417262Smckusick printf("Total %8ld %8ld\n", inttotal, inttotal / nintv); 53517262Smckusick } 53617262Smckusick 53718761Ssam #define steal(where, var) \ 53818761Ssam lseek(mf, where, L_SET); read(mf, &var, sizeof var); 5393162Stoy /* 5403162Stoy * Read the drive names out of kmem. 5413162Stoy */ 54210826Ssam #ifdef vax 54318761Ssam #include <vaxuba/ubavar.h> 54418761Ssam #include <vaxmba/mbavar.h> 54518761Ssam 5463162Stoy read_names() 5473162Stoy { 5483162Stoy struct mba_device mdev; 5493162Stoy register struct mba_device *mp; 5503162Stoy struct mba_driver mdrv; 5513162Stoy short two_char; 5523162Stoy char *cp = (char *) &two_char; 5533162Stoy struct uba_device udev, *up; 5543162Stoy struct uba_driver udrv; 5553162Stoy 5563162Stoy mp = (struct mba_device *) nl[X_MBDINIT].n_value; 5573162Stoy up = (struct uba_device *) nl[X_UBDINIT].n_value; 5583492Sroot if (up == 0) { 55910826Ssam fprintf(stderr, "vmstat: Disk init info not in namelist\n"); 5603162Stoy exit(1); 5613162Stoy } 5623492Sroot if (mp) for (;;) { 5633162Stoy steal(mp++, mdev); 5643162Stoy if (mdev.mi_driver == 0) 5653162Stoy break; 5663162Stoy if (mdev.mi_dk < 0 || mdev.mi_alive == 0) 5673162Stoy continue; 5683162Stoy steal(mdev.mi_driver, mdrv); 5693162Stoy steal(mdrv.md_dname, two_char); 57018761Ssam sprintf(dr_name[mdev.mi_dk], "%c%c%d", 57118761Ssam cp[0], cp[1], mdev.mi_unit); 5723162Stoy } 5733492Sroot for (;;) { 5743162Stoy steal(up++, udev); 5753162Stoy if (udev.ui_driver == 0) 5763162Stoy break; 5773162Stoy if (udev.ui_dk < 0 || udev.ui_alive == 0) 5783162Stoy continue; 5793162Stoy steal(udev.ui_driver, udrv); 5803162Stoy steal(udrv.ud_dname, two_char); 58118761Ssam sprintf(dr_name[udev.ui_dk], "%c%c%d", 58218761Ssam cp[0], cp[1], udev.ui_unit); 5833162Stoy } 5843162Stoy } 58510826Ssam #endif 58625708Ssam 58725708Ssam #ifdef sun 58825708Ssam #include <sundev/mbvar.h> 58925708Ssam 59025708Ssam read_names() 59125708Ssam { 59225708Ssam struct mb_device mdev; 59325708Ssam register struct mb_device *mp; 59425708Ssam struct mb_driver mdrv; 59525708Ssam short two_char; 59625708Ssam char *cp = (char *) &two_char; 59725708Ssam 59825708Ssam mp = (struct mb_device *) nl[X_MBDINIT].n_value; 59925708Ssam if (mp == 0) { 60025708Ssam fprintf(stderr, "vmstat: Disk init info not in namelist\n"); 60125708Ssam exit(1); 60225708Ssam } 60325708Ssam for (;;) { 60425708Ssam steal(mp++, mdev); 60525708Ssam if (mdev.md_driver == 0) 60625708Ssam break; 60725708Ssam if (mdev.md_dk < 0 || mdev.md_alive == 0) 60825708Ssam continue; 60925708Ssam steal(mdev.md_driver, mdrv); 61025708Ssam steal(mdrv.mdr_dname, two_char); 61125708Ssam sprintf(dr_name[mdev.md_dk], "%c%c%d", 61225708Ssam cp[0], cp[1], mdev.md_unit); 61325708Ssam } 61425708Ssam } 61525708Ssam #endif 61625708Ssam 61725708Ssam #ifdef tahoe 61825708Ssam #include <tahoevba/vbavar.h> 61925708Ssam 62025708Ssam /* 62125708Ssam * Read the drive names out of kmem. 62225708Ssam */ 62325708Ssam read_names() 62425708Ssam { 62525708Ssam struct vba_device udev, *up; 62625708Ssam struct vba_driver udrv; 62725708Ssam short two_char; 62825708Ssam char *cp = (char *)&two_char; 62925708Ssam 63025708Ssam up = (struct vba_device *) nl[X_VBDINIT].n_value; 63125708Ssam if (up == 0) { 63225708Ssam fprintf(stderr, "vmstat: Disk init info not in namelist\n"); 63325708Ssam exit(1); 63425708Ssam } 63525708Ssam for (;;) { 63625708Ssam steal(up++, udev); 63725708Ssam if (udev.ui_driver == 0) 63825708Ssam break; 63925708Ssam if (udev.ui_dk < 0 || udev.ui_alive == 0) 64025708Ssam continue; 64125708Ssam steal(udev.ui_driver, udrv); 64225708Ssam steal(udrv.ud_dname, two_char); 64325708Ssam sprintf(dr_name[udev.ui_dk], "%c%c%d", 64425708Ssam cp[0], cp[1], udev.ui_unit); 64525708Ssam } 64625708Ssam } 64725708Ssam #endif 648