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*36513Smarc static char sccsid[] = "@(#)vmstat.c 5.11 (Berkeley) 01/05/89"; 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> 2429664Ssam #include <sys/dkstat.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> 3033610Smckusick #include <sys/malloc.h> 311155Sbill 321155Sbill struct nlist nl[] = { 331448Sbill #define X_CPTIME 0 341448Sbill { "_cp_time" }, 351448Sbill #define X_RATE 1 361155Sbill { "_rate" }, 371448Sbill #define X_TOTAL 2 381155Sbill { "_total" }, 391448Sbill #define X_DEFICIT 3 401155Sbill { "_deficit" }, 411448Sbill #define X_FORKSTAT 4 421155Sbill { "_forkstat" }, 431448Sbill #define X_SUM 5 441155Sbill { "_sum" }, 451448Sbill #define X_FIRSTFREE 6 461155Sbill { "_firstfree" }, 471448Sbill #define X_MAXFREE 7 481155Sbill { "_maxfree" }, 499249Ssam #define X_BOOTTIME 8 509249Ssam { "_boottime" }, 511448Sbill #define X_DKXFER 9 521448Sbill { "_dk_xfer" }, 5310826Ssam #define X_REC 10 541155Sbill { "_rectime" }, 5510826Ssam #define X_PGIN 11 561155Sbill { "_pgintime" }, 5710826Ssam #define X_HZ 12 583162Stoy { "_hz" }, 5918761Ssam #define X_PHZ 13 6015266Ssam { "_phz" }, 6115807Smckusick #define X_NCHSTATS 14 6215807Smckusick { "_nchstats" }, 6317262Smckusick #define X_INTRNAMES 15 6417262Smckusick { "_intrnames" }, 6517262Smckusick #define X_EINTRNAMES 16 6617262Smckusick { "_eintrnames" }, 6717262Smckusick #define X_INTRCNT 17 6817262Smckusick { "_intrcnt" }, 6917262Smckusick #define X_EINTRCNT 18 7017262Smckusick { "_eintrcnt" }, 7118761Ssam #define X_DK_NDRIVE 19 7218761Ssam { "_dk_ndrive" }, 7325512Ssam #define X_XSTATS 20 7425512Ssam { "_xstats" }, 7533610Smckusick #define X_KMEMSTAT 21 7633610Smckusick { "_kmemstats" }, 7733610Smckusick #define X_KMEMBUCKETS 22 7833610Smckusick { "_bucket" }, 7910826Ssam #ifdef vax 8025708Ssam #define X_MBDINIT (X_XSTATS+1) 8110826Ssam { "_mbdinit" }, 8225708Ssam #define X_UBDINIT (X_XSTATS+2) 8310826Ssam { "_ubdinit" }, 8410826Ssam #endif 8525708Ssam #ifdef tahoe 8625708Ssam #define X_VBDINIT (X_XSTATS+1) 8725708Ssam { "_vbdinit" }, 8825960Ssam #define X_CKEYSTATS (X_XSTATS+2) 8925960Ssam { "_ckeystats" }, 9025960Ssam #define X_DKEYSTATS (X_XSTATS+3) 9125960Ssam { "_dkeystats" }, 9225708Ssam #endif 9310826Ssam { "" }, 941155Sbill }; 951155Sbill 9618761Ssam char **dr_name; 9718761Ssam int *dr_select; 9818761Ssam int dk_ndrive; 9918761Ssam int ndrives = 0; 10018761Ssam #ifdef vax 10118761Ssam char *defdrives[] = { "hp0", "hp1", "hp2", 0 }; 10218761Ssam #else 10318761Ssam char *defdrives[] = { 0 }; 10418761Ssam #endif 1051155Sbill double stat1(); 1061155Sbill int firstfree, maxfree; 1073162Stoy int hz; 10815266Ssam int phz; 10915266Ssam int HZ; 11018761Ssam 11118761Ssam struct { 1121155Sbill int busy; 1131448Sbill long time[CPUSTATES]; 11418761Ssam long *xfer; 1151155Sbill struct vmmeter Rate; 1161155Sbill struct vmtotal Total; 1171155Sbill struct vmmeter Sum; 1181155Sbill struct forkstat Forkstat; 1191155Sbill unsigned rectime; 1201155Sbill unsigned pgintime; 1211155Sbill } s, s1, z; 1221155Sbill #define rate s.Rate 1231155Sbill #define total s.Total 1241155Sbill #define sum s.Sum 1251155Sbill #define forkstat s.Forkstat 1261155Sbill 12710826Ssam struct vmmeter osum; 1281155Sbill int deficit; 1291155Sbill double etime; 1301155Sbill int mf; 13117262Smckusick time_t now, boottime; 13217262Smckusick int printhdr(); 13318768Ssam int lines = 1; 1341155Sbill 13529664Ssam #define INTS(x) ((x) - (hz + phz)) 13629664Ssam 1371155Sbill main(argc, argv) 13810826Ssam int argc; 13910826Ssam char **argv; 1401155Sbill { 1411155Sbill extern char *ctime(); 14229664Ssam register i; 14317262Smckusick int iter, nintv, iflag = 0; 1441155Sbill long t; 14529664Ssam char *arg, **cp, buf[BUFSIZ]; 1461155Sbill 1471155Sbill nlist("/vmunix", nl); 1481155Sbill if(nl[0].n_type == 0) { 14929664Ssam fprintf(stderr, "no /vmunix namelist\n"); 1501155Sbill exit(1); 1511155Sbill } 1521155Sbill mf = open("/dev/kmem", 0); 1531155Sbill if(mf < 0) { 15429664Ssam fprintf(stderr, "cannot open /dev/kmem\n"); 1551155Sbill exit(1); 1561155Sbill } 1571155Sbill iter = 0; 1581155Sbill argc--, argv++; 1591155Sbill while (argc>0 && argv[0][0]=='-') { 1601155Sbill char *cp = *argv++; 1611155Sbill argc--; 1621155Sbill while (*++cp) switch (*cp) { 1631155Sbill 1641155Sbill case 't': 1651155Sbill dotimes(); 1661155Sbill exit(0); 16710826Ssam 1681155Sbill case 'z': 1691155Sbill close(mf); 1701155Sbill mf = open("/dev/kmem", 2); 17118761Ssam lseek(mf, (long)nl[X_SUM].n_value, L_SET); 1721155Sbill write(mf, &z.Sum, sizeof z.Sum); 1731155Sbill exit(0); 1741155Sbill 1751155Sbill case 'f': 1761155Sbill doforkst(); 1771155Sbill exit(0); 1781155Sbill 17933610Smckusick case 'm': 18033610Smckusick domem(); 18133610Smckusick exit(0); 18233610Smckusick 1831155Sbill case 's': 1841155Sbill dosum(); 1851155Sbill exit(0); 1861155Sbill 18717262Smckusick case 'i': 18817262Smckusick iflag++; 18917262Smckusick break; 19017262Smckusick 1911155Sbill default: 19218761Ssam fprintf(stderr, 19333610Smckusick "usage: vmstat [ -fsim ] [ interval ] [ count]\n"); 1941155Sbill exit(1); 1951155Sbill } 1961155Sbill } 19718761Ssam lseek(mf, (long)nl[X_FIRSTFREE].n_value, L_SET); 1981155Sbill read(mf, &firstfree, sizeof firstfree); 19918761Ssam lseek(mf, (long)nl[X_MAXFREE].n_value, L_SET); 2001155Sbill read(mf, &maxfree, sizeof maxfree); 20118761Ssam lseek(mf, (long)nl[X_BOOTTIME].n_value, L_SET); 2029249Ssam read(mf, &boottime, sizeof boottime); 20318761Ssam lseek(mf, (long)nl[X_HZ].n_value, L_SET); 2043162Stoy read(mf, &hz, sizeof hz); 20518761Ssam if (nl[X_PHZ].n_value != 0) { 20618761Ssam lseek(mf, (long)nl[X_PHZ].n_value, L_SET); 20718761Ssam read(mf, &phz, sizeof phz); 20818761Ssam } 20915266Ssam HZ = phz ? phz : hz; 21030266Sbostic if (nl[X_DK_NDRIVE].n_value == 0) { 21129664Ssam fprintf(stderr, "dk_ndrive undefined in system\n"); 21218761Ssam exit(1); 2133162Stoy } 21418761Ssam lseek(mf, nl[X_DK_NDRIVE].n_value, L_SET); 21518761Ssam read(mf, &dk_ndrive, sizeof (dk_ndrive)); 21618761Ssam if (dk_ndrive <= 0) { 21729664Ssam fprintf(stderr, "dk_ndrive %d\n", dk_ndrive); 21818761Ssam exit(1); 21918761Ssam } 22018761Ssam dr_select = (int *)calloc(dk_ndrive, sizeof (int)); 22118761Ssam dr_name = (char **)calloc(dk_ndrive, sizeof (char *)); 22218761Ssam #define allocate(e, t) \ 22318761Ssam s./**/e = (t *)calloc(dk_ndrive, sizeof (t)); \ 22418761Ssam s1./**/e = (t *)calloc(dk_ndrive, sizeof (t)); 22518761Ssam allocate(xfer, long); 22618761Ssam for (arg = buf, i = 0; i < dk_ndrive; i++) { 22718761Ssam dr_name[i] = arg; 22818761Ssam sprintf(dr_name[i], "dk%d", i); 22918761Ssam arg += strlen(dr_name[i]) + 1; 23018761Ssam } 2313162Stoy read_names(); 2321155Sbill time(&now); 2339249Ssam nintv = now - boottime; 2341155Sbill if (nintv <= 0 || nintv > 60*60*24*365*10) { 23529664Ssam fprintf(stderr, 23629664Ssam "Time makes no sense... namelist must be wrong.\n"); 2371155Sbill exit(1); 2381155Sbill } 23917262Smckusick if (iflag) { 24017262Smckusick dointr(nintv); 24117262Smckusick exit(0); 24217262Smckusick } 24318761Ssam /* 24418761Ssam * Choose drives to be displayed. Priority 24518761Ssam * goes to (in order) drives supplied as arguments, 24618761Ssam * default drives. If everything isn't filled 24718761Ssam * in and there are drives not taken care of, 24818761Ssam * display the first few that fit. 24918761Ssam */ 25018761Ssam ndrives = 0; 25118761Ssam while (argc > 0 && !isdigit(argv[0][0])) { 25218761Ssam for (i = 0; i < dk_ndrive; i++) { 25318761Ssam if (strcmp(dr_name[i], argv[0])) 25418761Ssam continue; 25518761Ssam dr_select[i] = 1; 25618761Ssam ndrives++; 25718761Ssam } 25818761Ssam argc--, argv++; 25918761Ssam } 26018761Ssam for (i = 0; i < dk_ndrive && ndrives < 4; i++) { 26118761Ssam if (dr_select[i]) 26218761Ssam continue; 26318761Ssam for (cp = defdrives; *cp; cp++) 26418761Ssam if (strcmp(dr_name[i], *cp) == 0) { 26518761Ssam dr_select[i] = 1; 26618761Ssam ndrives++; 26718761Ssam break; 26818761Ssam } 26918761Ssam } 27018761Ssam for (i = 0; i < dk_ndrive && ndrives < 4; i++) { 27118761Ssam if (dr_select[i]) 27218761Ssam continue; 27318761Ssam dr_select[i] = 1; 27418761Ssam ndrives++; 27518761Ssam } 27618761Ssam if (argc > 1) 27718761Ssam iter = atoi(argv[1]); 27817262Smckusick signal(SIGCONT, printhdr); 2791155Sbill loop: 28018768Ssam if (--lines == 0) 28118768Ssam printhdr(); 28218761Ssam lseek(mf, (long)nl[X_CPTIME].n_value, L_SET); 2831448Sbill read(mf, s.time, sizeof s.time); 28418761Ssam lseek(mf, (long)nl[X_DKXFER].n_value, L_SET); 28518761Ssam read(mf, s.xfer, dk_ndrive * sizeof (long)); 28618761Ssam if (nintv != 1) 28718761Ssam lseek(mf, (long)nl[X_SUM].n_value, L_SET); 28818761Ssam else 28918761Ssam lseek(mf, (long)nl[X_RATE].n_value, L_SET); 29018761Ssam read(mf, &rate, sizeof rate); 29118761Ssam lseek(mf, (long)nl[X_TOTAL].n_value, L_SET); 2921155Sbill read(mf, &total, sizeof total); 29310826Ssam osum = sum; 29418761Ssam lseek(mf, (long)nl[X_SUM].n_value, L_SET); 29510826Ssam read(mf, &sum, sizeof sum); 29618761Ssam lseek(mf, (long)nl[X_DEFICIT].n_value, L_SET); 2971155Sbill read(mf, &deficit, sizeof deficit); 2981448Sbill etime = 0; 29918761Ssam for (i=0; i < dk_ndrive; i++) { 3001448Sbill t = s.xfer[i]; 3011448Sbill s.xfer[i] -= s1.xfer[i]; 3021448Sbill s1.xfer[i] = t; 3031155Sbill } 3041155Sbill for (i=0; i < CPUSTATES; i++) { 3051448Sbill t = s.time[i]; 3061448Sbill s.time[i] -= s1.time[i]; 3071448Sbill s1.time[i] = t; 3081448Sbill etime += s.time[i]; 3091155Sbill } 3101155Sbill if(etime == 0.) 3111155Sbill etime = 1.; 3123162Stoy printf("%2d%2d%2d", total.t_rq, total.t_dw+total.t_pw, total.t_sw); 31310826Ssam #define pgtok(a) ((a)*NBPG/1024) 31429664Ssam printf("%6d%6d", pgtok(total.t_avm), pgtok(total.t_free)); 31515266Ssam printf("%4d%3d", (rate.v_pgrec - (rate.v_xsfrec+rate.v_xifrec))/nintv, 31615266Ssam (rate.v_xsfrec+rate.v_xifrec)/nintv); 31710826Ssam printf("%4d", pgtok(rate.v_pgpgin)/nintv); 31810826Ssam printf("%4d%4d%4d%4d", pgtok(rate.v_pgpgout)/nintv, 31910826Ssam pgtok(rate.v_dfree)/nintv, pgtok(deficit), rate.v_scan/nintv); 32018761Ssam etime /= (float)HZ; 32118761Ssam for (i = 0; i < dk_ndrive; i++) 32218761Ssam if (dr_select[i]) 32318761Ssam stats(i); 32415266Ssam printf("%4d%4d%4d", INTS(rate.v_intr/nintv), rate.v_syscall/nintv, 32515266Ssam rate.v_swtch/nintv); 3261155Sbill for(i=0; i<CPUSTATES; i++) { 3271155Sbill float f = stat1(i); 3281155Sbill if (i == 0) { /* US+NI */ 3291155Sbill i++; 3301155Sbill f += stat1(i); 3311155Sbill } 3321155Sbill printf("%3.0f", f); 3331155Sbill } 3341155Sbill printf("\n"); 3351155Sbill fflush(stdout); 3361155Sbill nintv = 1; 33718768Ssam if (--iter &&argc > 0) { 3381155Sbill sleep(atoi(argv[0])); 3391155Sbill goto loop; 3401155Sbill } 3411155Sbill } 3421155Sbill 34317262Smckusick printhdr() 34417262Smckusick { 34518761Ssam register int i, j; 34618761Ssam 34729664Ssam printf(" procs memory page "); 34818761Ssam i = (ndrives * 3 - 6) / 2; 34918761Ssam if (i < 0) 35018761Ssam i = 0; 35118761Ssam for (j = 0; j < i; j++) 35218761Ssam putchar(' '); 35318761Ssam printf("faults"); 35418761Ssam i = ndrives * 3 - 6 - i; 35518761Ssam for (j = 0; j < i; j++) 35618761Ssam putchar(' '); 35718761Ssam printf(" cpu\n"); 35829664Ssam printf(" r b w avm fre re at pi po fr de sr "); 35918761Ssam for (i = 0; i < dk_ndrive; i++) 36018761Ssam if (dr_select[i]) 36118761Ssam printf("%c%c ", dr_name[i][0], dr_name[i][2]); 36218761Ssam printf(" in sy cs us sy id\n"); 36318768Ssam lines = 19; 36417262Smckusick } 36517262Smckusick 3661155Sbill dotimes() 3671155Sbill { 3681155Sbill 36918761Ssam lseek(mf, (long)nl[X_REC].n_value, L_SET); 3701155Sbill read(mf, &s.rectime, sizeof s.rectime); 37118761Ssam lseek(mf, (long)nl[X_PGIN].n_value, L_SET); 3721155Sbill read(mf, &s.pgintime, sizeof s.pgintime); 37318761Ssam lseek(mf, (long)nl[X_SUM].n_value, L_SET); 3741155Sbill read(mf, &sum, sizeof sum); 3751155Sbill printf("%d reclaims, %d total time (usec)\n", sum.v_pgrec, s.rectime); 3761155Sbill printf("average: %d usec / reclaim\n", s.rectime/sum.v_pgrec); 3771155Sbill printf("\n"); 3781155Sbill printf("%d page ins, %d total time (msec)\n",sum.v_pgin, s.pgintime/10); 3791155Sbill printf("average: %8.1f msec / page in\n", s.pgintime/(sum.v_pgin*10.0)); 3801155Sbill } 3811155Sbill 38230069Ssam #if defined(tahoe) 38330069Ssam #include <tahoe/cpu.h> 38430069Ssam #endif 38530069Ssam 3861155Sbill dosum() 3871155Sbill { 38818761Ssam struct nchstats nchstats; 38925960Ssam struct xstats xstats; 39015807Smckusick long nchtotal; 39125960Ssam #if defined(tahoe) 39225960Ssam struct keystats keystats; 39325960Ssam #endif 3941155Sbill 39518761Ssam lseek(mf, (long)nl[X_SUM].n_value, L_SET); 3961155Sbill read(mf, &sum, sizeof sum); 3971155Sbill printf("%9d swap ins\n", sum.v_swpin); 3981155Sbill printf("%9d swap outs\n", sum.v_swpout); 3991155Sbill printf("%9d pages swapped in\n", sum.v_pswpin / CLSIZE); 4001155Sbill printf("%9d pages swapped out\n", sum.v_pswpout / CLSIZE); 4011155Sbill printf("%9d total address trans. faults taken\n", sum.v_faults); 4021155Sbill printf("%9d page ins\n", sum.v_pgin); 4031155Sbill printf("%9d page outs\n", sum.v_pgout); 4043612Sroot printf("%9d pages paged in\n", sum.v_pgpgin); 4053612Sroot printf("%9d pages paged out\n", sum.v_pgpgout); 4063612Sroot printf("%9d sequential process pages freed\n", sum.v_seqfree); 40712830Ssam printf("%9d total reclaims (%d%% fast)\n", sum.v_pgrec, 40829664Ssam pct(sum.v_fastpgrec, sum.v_pgrec)); 4091155Sbill printf("%9d reclaims from free list\n", sum.v_pgfrec); 4101155Sbill printf("%9d intransit blocking page faults\n", sum.v_intrans); 4111155Sbill printf("%9d zero fill pages created\n", sum.v_nzfod / CLSIZE); 4121155Sbill printf("%9d zero fill page faults\n", sum.v_zfod / CLSIZE); 4131155Sbill printf("%9d executable fill pages created\n", sum.v_nexfod / CLSIZE); 4141155Sbill printf("%9d executable fill page faults\n", sum.v_exfod / CLSIZE); 4151155Sbill printf("%9d swap text pages found in free list\n", sum.v_xsfrec); 4161155Sbill printf("%9d inode text pages found in free list\n", sum.v_xifrec); 4171155Sbill printf("%9d file fill pages created\n", sum.v_nvrfod / CLSIZE); 4181155Sbill printf("%9d file fill page faults\n", sum.v_vrfod / CLSIZE); 4191155Sbill printf("%9d pages examined by the clock daemon\n", sum.v_scan); 4201155Sbill printf("%9d revolutions of the clock hand\n", sum.v_rev); 4211155Sbill printf("%9d pages freed by the clock daemon\n", sum.v_dfree / CLSIZE); 4221155Sbill printf("%9d cpu context switches\n", sum.v_swtch); 4231155Sbill printf("%9d device interrupts\n", sum.v_intr); 42417262Smckusick printf("%9d software interrupts\n", sum.v_soft); 42518761Ssam #ifdef vax 42624429Smckusick printf("%9d pseudo-dma dz interrupts\n", sum.v_pdma); 42718761Ssam #endif 4281155Sbill printf("%9d traps\n", sum.v_trap); 4291155Sbill printf("%9d system calls\n", sum.v_syscall); 43015807Smckusick lseek(mf, (long)nl[X_NCHSTATS].n_value, 0); 43118761Ssam read(mf, &nchstats, sizeof nchstats); 43218761Ssam nchtotal = nchstats.ncs_goodhits + nchstats.ncs_badhits + 43318761Ssam nchstats.ncs_falsehits + nchstats.ncs_miss + nchstats.ncs_long; 43415807Smckusick printf("%9d total name lookups", nchtotal); 43515807Smckusick printf(" (cache hits %d%% system %d%% per-process)\n", 43629664Ssam pct(nchstats.ncs_goodhits, nchtotal), 43729664Ssam pct(nchstats.ncs_pass2, nchtotal)); 43816586Ssam printf("%9s badhits %d, falsehits %d, toolong %d\n", "", 43918761Ssam nchstats.ncs_badhits, nchstats.ncs_falsehits, nchstats.ncs_long); 44025512Ssam lseek(mf, (long)nl[X_XSTATS].n_value, 0); 44125512Ssam read(mf, &xstats, sizeof xstats); 44225512Ssam printf("%9d total calls to xalloc (cache hits %d%%)\n", 44329664Ssam xstats.alloc, pct(xstats.alloc_cachehit, xstats.alloc)); 44425512Ssam printf("%9s sticky %d flushed %d unused %d\n", "", 44525512Ssam xstats.alloc_inuse, xstats.alloc_cacheflush, xstats.alloc_unused); 44625512Ssam printf("%9d total calls to xfree", xstats.free); 44725512Ssam printf(" (sticky %d cached %d swapped %d)\n", 44825512Ssam xstats.free_inuse, xstats.free_cache, xstats.free_cacheswap); 44925960Ssam #if defined(tahoe) 45025960Ssam lseek(mf, (long)nl[X_CKEYSTATS].n_value, 0); 45125960Ssam read(mf, &keystats, sizeof keystats); 45225960Ssam printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n", 45325960Ssam keystats.ks_allocs, "code cache keys allocated", 45433610Smckusick pct(keystats.ks_allocfree, keystats.ks_allocs), 45529664Ssam pct(keystats.ks_norefs, keystats.ks_allocs), 45629664Ssam pct(keystats.ks_taken, keystats.ks_allocs), 45729664Ssam pct(keystats.ks_shared, keystats.ks_allocs)); 45825960Ssam lseek(mf, (long)nl[X_DKEYSTATS].n_value, 0); 45925960Ssam read(mf, &keystats, sizeof keystats); 46025960Ssam printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n", 46125960Ssam keystats.ks_allocs, "data cache keys allocated", 46233610Smckusick pct(keystats.ks_allocfree, keystats.ks_allocs), 46329664Ssam pct(keystats.ks_norefs, keystats.ks_allocs), 46429664Ssam pct(keystats.ks_taken, keystats.ks_allocs), 46529664Ssam pct(keystats.ks_shared, keystats.ks_allocs)); 46625960Ssam #endif 4671155Sbill } 4681155Sbill 4691155Sbill doforkst() 4701155Sbill { 4711155Sbill 47218761Ssam lseek(mf, (long)nl[X_FORKSTAT].n_value, L_SET); 4731155Sbill read(mf, &forkstat, sizeof forkstat); 4741155Sbill printf("%d forks, %d pages, average=%.2f\n", 4751155Sbill forkstat.cntfork, forkstat.sizfork, 4761155Sbill (float) forkstat.sizfork / forkstat.cntfork); 4771155Sbill printf("%d vforks, %d pages, average=%.2f\n", 4781155Sbill forkstat.cntvfork, forkstat.sizvfork, 4791155Sbill (float)forkstat.sizvfork / forkstat.cntvfork); 4801155Sbill } 4811155Sbill 4821155Sbill stats(dn) 4831155Sbill { 4841155Sbill 48518761Ssam if (dn >= dk_ndrive) { 4861155Sbill printf(" 0"); 4871155Sbill return; 4881155Sbill } 4891448Sbill printf("%3.0f", s.xfer[dn]/etime); 4901155Sbill } 4911155Sbill 4921155Sbill double 4931155Sbill stat1(row) 4941155Sbill { 4951448Sbill double t; 4961448Sbill register i; 4971155Sbill 4981155Sbill t = 0; 4991155Sbill for(i=0; i<CPUSTATES; i++) 5001448Sbill t += s.time[i]; 5011448Sbill if(t == 0.) 5021448Sbill t = 1.; 5031448Sbill return(s.time[row]*100./t); 5041155Sbill } 5051155Sbill 5061155Sbill pct(top, bot) 5071155Sbill { 5081155Sbill 5091155Sbill if (bot == 0) 5101155Sbill return (0); 5111155Sbill return ((top * 100) / bot); 5121155Sbill } 5133162Stoy 51417262Smckusick dointr(nintv) 51517262Smckusick { 51617262Smckusick int nintr, inttotal; 51717262Smckusick long *intrcnt; 51817262Smckusick char *intrname, *malloc(); 51917262Smckusick 52017262Smckusick nintr = (nl[X_EINTRCNT].n_value - nl[X_INTRCNT].n_value) / sizeof(long); 52117262Smckusick intrcnt = (long *) malloc(nl[X_EINTRCNT].n_value - 52217262Smckusick nl[X_INTRCNT].n_value); 52317262Smckusick intrname = malloc(nl[X_EINTRNAMES].n_value - nl[X_INTRNAMES].n_value); 52417262Smckusick if (intrcnt == NULL || intrname == NULL) { 52517262Smckusick fprintf(stderr, "vmstat: out of memory\n"); 52617262Smckusick exit(9); 52717262Smckusick } 52818761Ssam lseek(mf, (long)nl[X_INTRCNT].n_value, L_SET); 52917262Smckusick read(mf, intrcnt, nintr * sizeof (long)); 53018761Ssam lseek(mf, (long)nl[X_INTRNAMES].n_value, L_SET); 53117262Smckusick read(mf, intrname, nl[X_EINTRNAMES].n_value - nl[X_INTRNAMES].n_value); 53217262Smckusick printf("interrupt total rate\n"); 53317262Smckusick inttotal = 0; 53417262Smckusick while (nintr--) { 53517262Smckusick if (*intrcnt) 53617262Smckusick printf("%-12s %8ld %8ld\n", intrname, 53717262Smckusick *intrcnt, *intrcnt / nintv); 53817262Smckusick intrname += strlen(intrname) + 1; 53917262Smckusick inttotal += *intrcnt++; 54017262Smckusick } 54117262Smckusick printf("Total %8ld %8ld\n", inttotal, inttotal / nintv); 54217262Smckusick } 54317262Smckusick 54433610Smckusick /* 54533610Smckusick * These names must be kept in sync with 54633610Smckusick * the types defined in <sys/malloc.h>. 54733610Smckusick */ 54833610Smckusick char *kmemnames[] = { 54936510Smarc "free", /* 0 M_FREE */ 55036510Smarc "mbuf", /* 1 M_MBUF */ 55136510Smarc "devbuf", /* 2 M_DEVBUF */ 55236510Smarc "socket", /* 3 M_SOCKET */ 55336510Smarc "pcb", /* 4 M_PCB */ 55436510Smarc "routetbl", /* 5 M_RTABLE */ 55536510Smarc "hosttbl", /* 6 M_HTABLE */ 55636510Smarc "fragtbl", /* 7 M_FTABLE */ 55736510Smarc "zombie", /* 8 M_ZOMBIE */ 55836510Smarc "ifaddr", /* 9 M_IFADDR */ 55936510Smarc "soopts", /* 10 M_SOOPTS */ 56036510Smarc "soname", /* 11 M_SONAME */ 56136510Smarc "namei", /* 12 M_NAMEI */ 56236510Smarc "gprof", /* 13 M_GPROF */ 56336510Smarc "ioctlops", /* 14 M_IOCTLOPS */ 56436510Smarc "superblk", /* 15 M_SUPERBLK */ 56536510Smarc "cred", /* 16 M_CRED */ 56636510Smarc "pgrp", /* 17 M_PGRP */ 56736510Smarc "session", /* 18 M_SESSION */ 568*36513Smarc "iov", /* 19 M_IOV */ 56936510Smarc 0, 0, 0, 0, 0, 57036510Smarc 0, 0, 0, 0, 0, 57136510Smarc 0, 0, 0, 0, 0, 57236510Smarc 0, 0, 0, 0, 0, 57336510Smarc 0, 0, 0, 0, 0, 574*36513Smarc 0, 0, 0, 0, 57536510Smarc "temp", /* 49 M_TEMP */ 57633610Smckusick }; 57733610Smckusick 57833610Smckusick domem() 57933610Smckusick { 58033610Smckusick struct kmemstats kmemstats[M_LAST]; 58133610Smckusick struct kmembuckets buckets[MINBUCKET + 16]; 58233610Smckusick register struct kmembuckets *kp; 58333610Smckusick register struct kmemstats *ks; 58433610Smckusick int i; 58533610Smckusick 58633610Smckusick lseek(mf, (long)nl[X_KMEMBUCKETS].n_value, L_SET); 58733610Smckusick read(mf, buckets, sizeof buckets); 58833610Smckusick printf("Memory statistics by bucket size\n"); 58933610Smckusick printf(" Size In Use Free Requests HighWater Couldfree\n"); 59033610Smckusick for (i = MINBUCKET, kp = &buckets[i]; i < MINBUCKET + 16; i++, kp++) { 59133610Smckusick if (kp->kb_calls == 0) 59233610Smckusick continue; 59333610Smckusick printf("%8d%9d%7d%11d%8d%11d\n", 1 << i, 59433610Smckusick kp->kb_total - kp->kb_totalfree, 59533610Smckusick kp->kb_totalfree, kp->kb_calls, 59633610Smckusick kp->kb_highwat, kp->kb_couldfree); 59733610Smckusick 59833610Smckusick } 59933610Smckusick lseek(mf, (long)nl[X_KMEMSTAT].n_value, L_SET); 60033610Smckusick read(mf, kmemstats, sizeof kmemstats); 60133610Smckusick printf("Memory statistics by type\n"); 60233610Smckusick printf(" Type In Use MemUse HighUse Limit Requests %s\n", 60333610Smckusick "TypeLimit KernLimit"); 60433610Smckusick for (i = 0, ks = &kmemstats[0]; i < M_LAST; i++, ks++) { 60533610Smckusick if (ks->ks_calls == 0) 60633610Smckusick continue; 60733610Smckusick printf("%10s%7d%8dK%9dK%6dK%9d%7d%10d\n", 60833610Smckusick kmemnames[i] ? kmemnames[i] : "undefined", 60933610Smckusick ks->ks_inuse, (ks->ks_memuse + 1023) / 1024, 61033610Smckusick (ks->ks_maxused + 1023) / 1024, 61133610Smckusick (ks->ks_limit + 1023) / 1024, ks->ks_calls, 61233610Smckusick ks->ks_limblocks, ks->ks_mapblocks); 61333610Smckusick } 61433610Smckusick } 61533610Smckusick 61618761Ssam #define steal(where, var) \ 61718761Ssam lseek(mf, where, L_SET); read(mf, &var, sizeof var); 6183162Stoy /* 6193162Stoy * Read the drive names out of kmem. 6203162Stoy */ 62110826Ssam #ifdef vax 62218761Ssam #include <vaxuba/ubavar.h> 62318761Ssam #include <vaxmba/mbavar.h> 62418761Ssam 6253162Stoy read_names() 6263162Stoy { 6273162Stoy struct mba_device mdev; 6283162Stoy register struct mba_device *mp; 6293162Stoy struct mba_driver mdrv; 6303162Stoy short two_char; 6313162Stoy char *cp = (char *) &two_char; 6323162Stoy struct uba_device udev, *up; 6333162Stoy struct uba_driver udrv; 6343162Stoy 6353162Stoy mp = (struct mba_device *) nl[X_MBDINIT].n_value; 6363162Stoy up = (struct uba_device *) nl[X_UBDINIT].n_value; 6373492Sroot if (up == 0) { 63810826Ssam fprintf(stderr, "vmstat: Disk init info not in namelist\n"); 6393162Stoy exit(1); 6403162Stoy } 6413492Sroot if (mp) for (;;) { 6423162Stoy steal(mp++, mdev); 6433162Stoy if (mdev.mi_driver == 0) 6443162Stoy break; 6453162Stoy if (mdev.mi_dk < 0 || mdev.mi_alive == 0) 6463162Stoy continue; 6473162Stoy steal(mdev.mi_driver, mdrv); 6483162Stoy steal(mdrv.md_dname, two_char); 64918761Ssam sprintf(dr_name[mdev.mi_dk], "%c%c%d", 65018761Ssam cp[0], cp[1], mdev.mi_unit); 6513162Stoy } 6523492Sroot for (;;) { 6533162Stoy steal(up++, udev); 6543162Stoy if (udev.ui_driver == 0) 6553162Stoy break; 6563162Stoy if (udev.ui_dk < 0 || udev.ui_alive == 0) 6573162Stoy continue; 6583162Stoy steal(udev.ui_driver, udrv); 6593162Stoy steal(udrv.ud_dname, two_char); 66018761Ssam sprintf(dr_name[udev.ui_dk], "%c%c%d", 66118761Ssam cp[0], cp[1], udev.ui_unit); 6623162Stoy } 6633162Stoy } 66410826Ssam #endif 66525708Ssam 66625708Ssam #ifdef tahoe 66725708Ssam #include <tahoevba/vbavar.h> 66825708Ssam 66925708Ssam /* 67025708Ssam * Read the drive names out of kmem. 67125708Ssam */ 67225708Ssam read_names() 67325708Ssam { 67425708Ssam struct vba_device udev, *up; 67525708Ssam struct vba_driver udrv; 67625708Ssam short two_char; 67725708Ssam char *cp = (char *)&two_char; 67825708Ssam 67925708Ssam up = (struct vba_device *) nl[X_VBDINIT].n_value; 68025708Ssam if (up == 0) { 68125708Ssam fprintf(stderr, "vmstat: Disk init info not in namelist\n"); 68225708Ssam exit(1); 68325708Ssam } 68425708Ssam for (;;) { 68525708Ssam steal(up++, udev); 68625708Ssam if (udev.ui_driver == 0) 68725708Ssam break; 68825708Ssam if (udev.ui_dk < 0 || udev.ui_alive == 0) 68925708Ssam continue; 69025708Ssam steal(udev.ui_driver, udrv); 69125708Ssam steal(udrv.ud_dname, two_char); 69225708Ssam sprintf(dr_name[udev.ui_dk], "%c%c%d", 69325708Ssam cp[0], cp[1], udev.ui_unit); 69425708Ssam } 69525708Ssam } 69625708Ssam #endif 697