1*1448Sbill static char *sccsid = "@(#)vmstat.c 4.2 (Berkeley) 10/16/80"; 21155Sbill #include <stdio.h> 31155Sbill #include <sys/param.h> 41155Sbill #include <sys/vm.h> 51155Sbill #include <sys/dk.h> 61155Sbill #include <nlist.h> 71155Sbill 81155Sbill struct nlist nl[] = { 9*1448Sbill #define X_CPTIME 0 10*1448Sbill { "_cp_time" }, 11*1448Sbill #define X_RATE 1 121155Sbill { "_rate" }, 13*1448Sbill #define X_TOTAL 2 141155Sbill { "_total" }, 15*1448Sbill #define X_DEFICIT 3 161155Sbill { "_deficit" }, 17*1448Sbill #define X_FORKSTAT 4 181155Sbill { "_forkstat" }, 19*1448Sbill #define X_SUM 5 201155Sbill { "_sum" }, 21*1448Sbill #define X_FIRSTFREE 6 221155Sbill { "_firstfree" }, 23*1448Sbill #define X_MAXFREE 7 241155Sbill { "_maxfree" }, 25*1448Sbill #define X_BOOTIME 8 261155Sbill { "_bootime" }, 27*1448Sbill #define X_DKXFER 9 28*1448Sbill { "_dk_xfer" }, 291155Sbill #ifdef ERNIE 30*1448Sbill #define X_REC 10 311155Sbill { "_rectime" }, 32*1448Sbill #define X_PGIN 11 331155Sbill { "_pgintime" }, 341155Sbill #endif 351155Sbill { 0 }, 361155Sbill }; 371155Sbill 381155Sbill double stat1(); 391155Sbill int firstfree, maxfree; 401155Sbill struct 411155Sbill { 421155Sbill int busy; 43*1448Sbill long time[CPUSTATES]; 44*1448Sbill long xfer[DK_NDRIVE]; 451155Sbill struct vmmeter Rate; 461155Sbill struct vmtotal Total; 471155Sbill struct vmmeter Sum; 481155Sbill struct forkstat Forkstat; 491155Sbill #ifdef ERNIE 501155Sbill unsigned rectime; 511155Sbill unsigned pgintime; 521155Sbill #endif 531155Sbill } s, s1, z; 541155Sbill #define rate s.Rate 551155Sbill #define total s.Total 561155Sbill #define sum s.Sum 571155Sbill #define forkstat s.Forkstat 581155Sbill 591155Sbill int iflag = 1; 601155Sbill int zero; 611155Sbill int deficit; 621155Sbill double etime; 631155Sbill int mf; 641155Sbill 651155Sbill main(argc, argv) 661155Sbill char **argv; 671155Sbill { 681155Sbill time_t now; 691155Sbill int lines; 701155Sbill extern char *ctime(); 711155Sbill register i,j; 721155Sbill int iter, nintv; 731155Sbill time_t bootime; 741155Sbill double f1, f2; 751155Sbill long t; 761155Sbill extern char _sobuf[]; 771155Sbill 781155Sbill setbuf(stdout, _sobuf); 791155Sbill nlist("/vmunix", nl); 801155Sbill if(nl[0].n_type == 0) { 811155Sbill printf("no /vmunix namelist\n"); 821155Sbill exit(1); 831155Sbill } 841155Sbill mf = open("/dev/kmem", 0); 851155Sbill if(mf < 0) { 861155Sbill printf("cannot open /dev/kmem\n"); 871155Sbill exit(1); 881155Sbill } 891155Sbill iter = 0; 901155Sbill argc--, argv++; 911155Sbill while (argc>0 && argv[0][0]=='-') { 921155Sbill char *cp = *argv++; 931155Sbill argc--; 941155Sbill while (*++cp) switch (*cp) { 951155Sbill 961155Sbill #ifdef ERNIE 971155Sbill case 't': 981155Sbill dotimes(); 991155Sbill exit(0); 1001155Sbill #endif 1011155Sbill case 'z': 1021155Sbill close(mf); 1031155Sbill mf = open("/dev/kmem", 2); 1041155Sbill lseek(mf, (long)nl[X_SUM].n_value, 0); 1051155Sbill write(mf, &z.Sum, sizeof z.Sum); 1061155Sbill exit(0); 1071155Sbill 1081155Sbill case 'f': 1091155Sbill doforkst(); 1101155Sbill exit(0); 1111155Sbill 1121155Sbill case 's': 1131155Sbill dosum(); 1141155Sbill exit(0); 1151155Sbill 1161155Sbill case 'i': 1171155Sbill iflag = 0; 1181155Sbill break; 1191155Sbill 1201155Sbill default: 1211155Sbill fprintf(stderr, "usage: vmstat [ -fs ] [ interval ] [ count]\n"); 1221155Sbill exit(1); 1231155Sbill } 1241155Sbill } 1251155Sbill if(argc > 1) 1261155Sbill iter = atoi(argv[1]); 1271155Sbill lseek(mf, (long)nl[X_FIRSTFREE].n_value, 0); 1281155Sbill read(mf, &firstfree, sizeof firstfree); 1291155Sbill lseek(mf, (long)nl[X_MAXFREE].n_value, 0); 1301155Sbill read(mf, &maxfree, sizeof maxfree); 1311155Sbill lseek(mf, (long)nl[X_BOOTIME].n_value, 0); 1321155Sbill read(mf, &bootime, sizeof bootime); 1331155Sbill time(&now); 1341155Sbill nintv = now - bootime; 1351155Sbill if (nintv <= 0 || nintv > 60*60*24*365*10) { 1361155Sbill printf("Time makes no sense... namelist must be wrong.\n"); 1371155Sbill exit(1); 1381155Sbill } 1391155Sbill reprint: 1401155Sbill lines = 20; 1411155Sbill /* s1 = z; */ 1421155Sbill if (iflag==0) 1431155Sbill printf("\ 1441155Sbill Procs Virtual Real Page Swap Disk Cpu\n\ 1451155Sbill RQ DW PW SW AVM TX FRE RE AT PI PO FR DE SR I O D0 D1 D2 D3 CS US SY ID\n\ 1461155Sbill "); 1471155Sbill else 1481155Sbill printf("\ 1491155Sbill Procs Memory Page Swap Disk Faults Cpu\n\ 1501155Sbill R B W AVM FRE RE AT PI PO FR DE SR I O D0 D1 D2 D3 IN SY CS US SY ID\n\ 1511155Sbill "); 1521155Sbill loop: 153*1448Sbill lseek(mf, (long)nl[X_CPTIME].n_value, 0); 154*1448Sbill read(mf, s.time, sizeof s.time); 155*1448Sbill lseek(mf, (long)nl[X_DKXFER].n_value, 0); 156*1448Sbill read(mf, s.xfer, sizeof s.xfer); 1571155Sbill if (nintv != 1) { 1581155Sbill lseek(mf, (long)nl[X_SUM].n_value, 0); 1591155Sbill read(mf, &rate, sizeof rate); 1601155Sbill } else { 1611155Sbill lseek(mf, (long)nl[X_RATE].n_value, 0); 1621155Sbill read(mf, &rate, sizeof rate); 1631155Sbill } 1641155Sbill lseek(mf, (long)nl[X_TOTAL].n_value, 0); 1651155Sbill read(mf, &total, sizeof total); 1661155Sbill lseek(mf, (long)nl[X_DEFICIT].n_value, 0); 1671155Sbill read(mf, &deficit, sizeof deficit); 168*1448Sbill etime = 0; 1691155Sbill for (i=0; i < DK_NDRIVE; i++) { 170*1448Sbill t = s.xfer[i]; 171*1448Sbill s.xfer[i] -= s1.xfer[i]; 172*1448Sbill s1.xfer[i] = t; 1731155Sbill } 1741155Sbill for (i=0; i < CPUSTATES; i++) { 175*1448Sbill t = s.time[i]; 176*1448Sbill s.time[i] -= s1.time[i]; 177*1448Sbill s1.time[i] = t; 178*1448Sbill etime += s.time[i]; 1791155Sbill } 1801155Sbill if(etime == 0.) 1811155Sbill etime = 1.; 1821155Sbill if (iflag) 1831155Sbill printf("%2d%2d%2d", total.t_rq, total.t_dw+total.t_pw, 1841155Sbill total.t_sw); 1851155Sbill else 1861155Sbill printf("%2d%3d%3d%3d%3d", total.t_rq, total.t_dw, total.t_pw, 1871155Sbill total.t_sw); 1881155Sbill if (iflag) 1891155Sbill printf("%6d%5d", total.t_avm/2, total.t_free/2); 1901155Sbill else 1911155Sbill printf("%6d%3d%5d", total.t_avm/2, 1921155Sbill pct(total.t_avmtxt, total.t_avm), total.t_free/2); 1931155Sbill printf("%4d%3d%3d", 1941155Sbill (rate.v_pgrec - (rate.v_xsfrec+rate.v_xifrec))/nintv, 1951155Sbill (rate.v_xsfrec+rate.v_xifrec)/nintv, rate.v_pgin/nintv); 1961155Sbill printf("%3d%3d%4d%4.1f%2d%2d", rate.v_pgout/nintv, 1971155Sbill rate.v_dfree/nintv, deficit/2, 1981155Sbill (60.0 * rate.v_scan) / (LOOPSIZ*nintv), 1991155Sbill rate.v_swpin/nintv, rate.v_swpout/nintv); 2001155Sbill etime /= 60.; 2011155Sbill printf(" "); 2021155Sbill for(i=0; i<4; i++) 2031155Sbill stats(i); 2041155Sbill if (iflag) 2051155Sbill printf("%4d%4d", (rate.v_intr/nintv) - HZ, 2061155Sbill rate.v_syscall/nintv); 2071155Sbill printf("%4d", rate.v_swtch/nintv); 2081155Sbill for(i=0; i<CPUSTATES; i++) { 2091155Sbill float f = stat1(i); 2101155Sbill if (i == 0) { /* US+NI */ 2111155Sbill i++; 2121155Sbill f += stat1(i); 2131155Sbill } 2141155Sbill printf("%3.0f", f); 2151155Sbill } 2161155Sbill printf("\n"); 2171155Sbill fflush(stdout); 2181155Sbill contin: 2191155Sbill nintv = 1; 2201155Sbill --iter; 2211155Sbill if(iter) 2221155Sbill if(argc > 0) { 2231155Sbill sleep(atoi(argv[0])); 2241155Sbill if (--lines <= 0) 2251155Sbill goto reprint; 2261155Sbill goto loop; 2271155Sbill } 2281155Sbill } 2291155Sbill 2301155Sbill #ifdef ERNIE 2311155Sbill dotimes() 2321155Sbill { 2331155Sbill 2341155Sbill lseek(mf, (long)nl[X_REC].n_value, 0); 2351155Sbill read(mf, &s.rectime, sizeof s.rectime); 2361155Sbill lseek(mf, (long)nl[X_PGIN].n_value, 0); 2371155Sbill read(mf, &s.pgintime, sizeof s.pgintime); 2381155Sbill lseek(mf, (long)nl[X_SUM].n_value, 0); 2391155Sbill read(mf, &sum, sizeof sum); 2401155Sbill printf("%d reclaims, %d total time (usec)\n", sum.v_pgrec, s.rectime); 2411155Sbill printf("average: %d usec / reclaim\n", s.rectime/sum.v_pgrec); 2421155Sbill printf("\n"); 2431155Sbill printf("%d page ins, %d total time (msec)\n",sum.v_pgin, s.pgintime/10); 2441155Sbill printf("average: %8.1f msec / page in\n", s.pgintime/(sum.v_pgin*10.0)); 2451155Sbill } 2461155Sbill #endif 2471155Sbill 2481155Sbill dosum() 2491155Sbill { 2501155Sbill 2511155Sbill lseek(mf, (long)nl[X_SUM].n_value, 0); 2521155Sbill read(mf, &sum, sizeof sum); 2531155Sbill printf("%9d swap ins\n", sum.v_swpin); 2541155Sbill printf("%9d swap outs\n", sum.v_swpout); 2551155Sbill printf("%9d pages swapped in\n", sum.v_pswpin / CLSIZE); 2561155Sbill printf("%9d pages swapped out\n", sum.v_pswpout / CLSIZE); 2571155Sbill printf("%9d total address trans. faults taken\n", sum.v_faults); 2581155Sbill printf("%9d page ins\n", sum.v_pgin); 2591155Sbill printf("%9d page outs\n", sum.v_pgout); 2601155Sbill printf("%9d total reclaims\n", sum.v_pgrec); 2611155Sbill printf("%9d reclaims from free list\n", sum.v_pgfrec); 2621155Sbill printf("%9d intransit blocking page faults\n", sum.v_intrans); 2631155Sbill printf("%9d zero fill pages created\n", sum.v_nzfod / CLSIZE); 2641155Sbill printf("%9d zero fill page faults\n", sum.v_zfod / CLSIZE); 2651155Sbill printf("%9d executable fill pages created\n", sum.v_nexfod / CLSIZE); 2661155Sbill printf("%9d executable fill page faults\n", sum.v_exfod / CLSIZE); 2671155Sbill printf("%9d swap text pages found in free list\n", sum.v_xsfrec); 2681155Sbill printf("%9d inode text pages found in free list\n", sum.v_xifrec); 2691155Sbill printf("%9d file fill pages created\n", sum.v_nvrfod / CLSIZE); 2701155Sbill printf("%9d file fill page faults\n", sum.v_vrfod / CLSIZE); 2711155Sbill printf("%9d pages examined by the clock daemon\n", sum.v_scan); 2721155Sbill printf("%9d revolutions of the clock hand\n", sum.v_rev); 2731155Sbill printf("%9d pages freed by the clock daemon\n", sum.v_dfree / CLSIZE); 2741155Sbill printf("%9d cpu context switches\n", sum.v_swtch); 2751155Sbill printf("%9d device interrupts\n", sum.v_intr); 2761155Sbill printf("%9d pseduo-dma dz interrupts\n", sum.v_pdma); 2771155Sbill printf("%9d traps\n", sum.v_trap); 2781155Sbill printf("%9d system calls\n", sum.v_syscall); 2791155Sbill } 2801155Sbill 2811155Sbill 2821155Sbill doforkst() 2831155Sbill { 2841155Sbill 2851155Sbill lseek(mf, (long)nl[X_FORKSTAT].n_value, 0); 2861155Sbill read(mf, &forkstat, sizeof forkstat); 2871155Sbill printf("%d forks, %d pages, average=%.2f\n", 2881155Sbill forkstat.cntfork, forkstat.sizfork, 2891155Sbill (float) forkstat.sizfork / forkstat.cntfork); 2901155Sbill printf("%d vforks, %d pages, average=%.2f\n", 2911155Sbill forkstat.cntvfork, forkstat.sizvfork, 2921155Sbill (float)forkstat.sizvfork / forkstat.cntvfork); 2931155Sbill } 2941155Sbill 2951155Sbill stats(dn) 2961155Sbill { 2971155Sbill 2981155Sbill if (dn >= DK_NDRIVE) { 2991155Sbill printf(" 0"); 3001155Sbill return; 3011155Sbill } 302*1448Sbill printf("%3.0f", s.xfer[dn]/etime); 3031155Sbill } 3041155Sbill 3051155Sbill double 3061155Sbill stat1(row) 3071155Sbill { 308*1448Sbill double t; 309*1448Sbill register i; 3101155Sbill 3111155Sbill t = 0; 3121155Sbill for(i=0; i<CPUSTATES; i++) 313*1448Sbill t += s.time[i]; 314*1448Sbill if(t == 0.) 315*1448Sbill t = 1.; 316*1448Sbill return(s.time[row]*100./t); 3171155Sbill } 3181155Sbill 3191155Sbill pct(top, bot) 3201155Sbill { 3211155Sbill 3221155Sbill if (bot == 0) 3231155Sbill return (0); 3241155Sbill return ((top * 100) / bot); 3251155Sbill } 326