Annotation of 42BSD/ucb/vmstat.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char *sccsid = "@(#)vmstat.c    4.11 (Berkeley) 9/25/83";
                      3: #endif
                      4: 
                      5: #include <stdio.h>
                      6: #include <sys/param.h>
                      7: #include <sys/vm.h>
                      8: #include <sys/dk.h>
                      9: #include <nlist.h>
                     10: #include <sys/buf.h>
                     11: #ifdef vax
                     12: #include <vaxuba/ubavar.h>
                     13: #include <vaxmba/mbavar.h>
                     14: #endif
                     15: #ifdef sun
                     16: #include <sundev/mbvar.h>
                     17: #endif
                     18: 
                     19: struct nlist nl[] = {
                     20: #define        X_CPTIME        0
                     21:        { "_cp_time" },
                     22: #define        X_RATE          1
                     23:        { "_rate" },
                     24: #define X_TOTAL                2
                     25:        { "_total" },
                     26: #define        X_DEFICIT       3
                     27:        { "_deficit" },
                     28: #define        X_FORKSTAT      4
                     29:        { "_forkstat" },
                     30: #define X_SUM          5
                     31:        { "_sum" },
                     32: #define        X_FIRSTFREE     6
                     33:        { "_firstfree" },
                     34: #define        X_MAXFREE       7
                     35:        { "_maxfree" },
                     36: #define        X_BOOTTIME      8
                     37:        { "_boottime" },
                     38: #define        X_DKXFER        9
                     39:        { "_dk_xfer" },
                     40: #define X_REC          10
                     41:        { "_rectime" },
                     42: #define X_PGIN         11
                     43:        { "_pgintime" },
                     44: #define X_HZ           12
                     45:        { "_hz" },
                     46: #ifdef vax
                     47: #define X_MBDINIT      13
                     48:        { "_mbdinit" },
                     49: #define X_UBDINIT      14
                     50:        { "_ubdinit" },
                     51: #endif
                     52: #ifdef sun
                     53: #define X_MBDINIT      13
                     54:        { "_mbdinit" },
                     55: #endif
                     56:        { "" },
                     57: };
                     58: 
                     59: char dr_name[DK_NDRIVE][10];
                     60: char dr_unit[DK_NDRIVE];
                     61: double stat1();
                     62: int    firstfree, maxfree;
                     63: int    hz;
                     64: struct
                     65: {
                     66:        int     busy;
                     67:        long    time[CPUSTATES];
                     68:        long    xfer[DK_NDRIVE];
                     69:        struct  vmmeter Rate;
                     70:        struct  vmtotal Total;
                     71:        struct  vmmeter Sum;
                     72:        struct  forkstat Forkstat;
                     73:        unsigned rectime;
                     74:        unsigned pgintime;
                     75: } s, s1, z;
                     76: #define        rate            s.Rate
                     77: #define        total           s.Total
                     78: #define        sum             s.Sum
                     79: #define        forkstat        s.Forkstat
                     80: 
                     81: struct vmmeter osum;
                     82: int    zero;
                     83: int    deficit;
                     84: double etime;
                     85: int    mf;
                     86: int    swflag;
                     87: 
                     88: main(argc, argv)
                     89:        int argc;
                     90:        char **argv;
                     91: {
                     92:        time_t now;
                     93:        int lines;
                     94:        extern char *ctime();
                     95:        register i,j;
                     96:        int iter, nintv;
                     97:        time_t boottime;
                     98:        double f1, f2;
                     99:        long t;
                    100:        extern char _sobuf[];
                    101: 
                    102: #ifdef sun
                    103:        swflag = 1;
                    104: #endif
                    105:        setbuf(stdout, _sobuf);
                    106:        nlist("/vmunix", nl);
                    107:        if(nl[0].n_type == 0) {
                    108:                printf("no /vmunix namelist\n");
                    109:                exit(1);
                    110:        }
                    111:        mf = open("/dev/kmem", 0);
                    112:        if(mf < 0) {
                    113:                printf("cannot open /dev/kmem\n");
                    114:                exit(1);
                    115:        }
                    116:        iter = 0;
                    117:        argc--, argv++;
                    118:        while (argc>0 && argv[0][0]=='-') {
                    119:                char *cp = *argv++;
                    120:                argc--;
                    121:                while (*++cp) switch (*cp) {
                    122: 
                    123:                case 'S':
                    124:                        swflag = 1 - swflag;
                    125:                        break;
                    126: 
                    127: 
                    128:                case 't':
                    129:                        dotimes();
                    130:                        exit(0);
                    131: 
                    132:                case 'z':
                    133:                        close(mf);
                    134:                        mf = open("/dev/kmem", 2);
                    135:                        lseek(mf, (long)nl[X_SUM].n_value, 0);
                    136:                        write(mf, &z.Sum, sizeof z.Sum);
                    137:                        exit(0);
                    138: 
                    139:                case 'f':
                    140:                        doforkst();
                    141:                        exit(0);
                    142:                
                    143:                case 's':
                    144:                        dosum();
                    145:                        exit(0);
                    146: 
                    147:                default:
                    148:                        fprintf(stderr, "usage: vmstat [ -fs ] [ interval ] [ count]\n");
                    149:                        exit(1);
                    150:                }
                    151:        }
                    152:        if(argc > 1)
                    153:                iter = atoi(argv[1]);
                    154:        lseek(mf, (long)nl[X_FIRSTFREE].n_value, 0);
                    155:        read(mf, &firstfree, sizeof firstfree);
                    156:        lseek(mf, (long)nl[X_MAXFREE].n_value, 0);
                    157:        read(mf, &maxfree, sizeof maxfree);
                    158:        lseek(mf, (long)nl[X_BOOTTIME].n_value, 0);
                    159:        read(mf, &boottime, sizeof boottime);
                    160:        lseek(mf, (long)nl[X_HZ].n_value, 0);
                    161:        read(mf, &hz, sizeof hz);
                    162:        for (i = 0; i < DK_NDRIVE; i++) {
                    163:                strcpy(dr_name[i], "xx");
                    164:                dr_unit[i] = i;
                    165:        }
                    166:        read_names();
                    167:        time(&now);
                    168:        nintv = now - boottime;
                    169:        if (nintv <= 0 || nintv > 60*60*24*365*10) {
                    170:                printf("Time makes no sense... namelist must be wrong.\n");
                    171:                exit(1);
                    172:        }
                    173: reprint:
                    174:        lines = 20;
                    175:        /* s1 = z; */
                    176: printf("\
                    177:  procs     memory                       page      disk  faults          cpu\n\
                    178:  r b w   avm  fre  %5s  pi  po  fr  de  sr %c%d %c%d %c%d %c%d  in  sy  cs us sy id\n\
                    179: ", swflag ? "si so" : "re at",
                    180:  dr_name[0][0], dr_unit[0], dr_name[1][0], dr_unit[1], dr_name[2][0], dr_unit[2], dr_name[3][0], dr_unit[3]);
                    181: loop:
                    182:        lseek(mf, (long)nl[X_CPTIME].n_value, 0);
                    183:        read(mf, s.time, sizeof s.time);
                    184:        lseek(mf, (long)nl[X_DKXFER].n_value, 0);
                    185:        read(mf, s.xfer, sizeof s.xfer);
                    186:        if (nintv != 1) {
                    187:                lseek(mf, (long)nl[X_SUM].n_value, 0);
                    188:                read(mf, &rate, sizeof rate);
                    189:        } else {
                    190:                lseek(mf, (long)nl[X_RATE].n_value, 0);
                    191:                read(mf, &rate, sizeof rate);
                    192:        }
                    193:        lseek(mf, (long)nl[X_TOTAL].n_value, 0);
                    194:        read(mf, &total, sizeof total);
                    195:        osum = sum;
                    196:        lseek(mf, (long)nl[X_SUM].n_value, 0);
                    197:        read(mf, &sum, sizeof sum);
                    198:        lseek(mf, (long)nl[X_DEFICIT].n_value, 0);
                    199:        read(mf, &deficit, sizeof deficit);
                    200:        etime = 0;
                    201:        for (i=0; i < DK_NDRIVE; i++) {
                    202:                t = s.xfer[i];
                    203:                s.xfer[i] -= s1.xfer[i];
                    204:                s1.xfer[i] = t;
                    205:        }
                    206:        for (i=0; i < CPUSTATES; i++) {
                    207:                t = s.time[i];
                    208:                s.time[i] -= s1.time[i];
                    209:                s1.time[i] = t;
                    210:                etime += s.time[i];
                    211:        }
                    212:        if(etime == 0.)
                    213:                etime = 1.;
                    214:        printf("%2d%2d%2d", total.t_rq, total.t_dw+total.t_pw, total.t_sw);
                    215: #define pgtok(a) ((a)*NBPG/1024)
                    216:        printf("%6d%5d", pgtok(total.t_avm), pgtok(total.t_free));
                    217:        printf("%4d%3d",
                    218:            swflag ?
                    219:                sum.v_swpin-osum.v_swpin :
                    220:                (rate.v_pgrec - (rate.v_xsfrec+rate.v_xifrec))/nintv,
                    221:            swflag ?
                    222:                sum.v_swpout-osum.v_swpout :
                    223:                (rate.v_xsfrec+rate.v_xifrec)/nintv);
                    224:        printf("%4d", pgtok(rate.v_pgpgin)/nintv);
                    225:        printf("%4d%4d%4d%4d", pgtok(rate.v_pgpgout)/nintv,
                    226:            pgtok(rate.v_dfree)/nintv, pgtok(deficit), rate.v_scan/nintv);
                    227:        etime /= (float) hz;
                    228:        for(i=0; i<4; i++)
                    229:                stats(i);
                    230: #ifdef sun
                    231:        printf("%4d%4d", (rate.v_intr/nintv), rate.v_syscall/nintv);
                    232: #endif
                    233: #ifdef vax
                    234:        printf("%4d%4d", (rate.v_intr/nintv) - hz, rate.v_syscall/nintv);
                    235: #endif
                    236:        printf("%4d", rate.v_swtch/nintv);
                    237:        for(i=0; i<CPUSTATES; i++) {
                    238:                float f = stat1(i);
                    239:                if (i == 0) {           /* US+NI */
                    240:                        i++;
                    241:                        f += stat1(i);
                    242:                }
                    243:                printf("%3.0f", f);
                    244:        }
                    245:        printf("\n");
                    246:        fflush(stdout);
                    247: contin:
                    248:        nintv = 1;
                    249:        --iter;
                    250:        if(iter)
                    251:        if(argc > 0) {
                    252:                sleep(atoi(argv[0]));
                    253:                if (--lines <= 0)
                    254:                        goto reprint;
                    255:                goto loop;
                    256:        }
                    257: }
                    258: 
                    259: dotimes()
                    260: {
                    261: 
                    262:        lseek(mf, (long)nl[X_REC].n_value, 0);
                    263:        read(mf, &s.rectime, sizeof s.rectime);
                    264:        lseek(mf, (long)nl[X_PGIN].n_value, 0);
                    265:        read(mf, &s.pgintime, sizeof s.pgintime);
                    266:        lseek(mf, (long)nl[X_SUM].n_value, 0);
                    267:        read(mf, &sum, sizeof sum);
                    268:        printf("%d reclaims, %d total time (usec)\n", sum.v_pgrec, s.rectime);
                    269:        printf("average: %d usec / reclaim\n", s.rectime/sum.v_pgrec);
                    270:        printf("\n");
                    271:        printf("%d page ins, %d total time (msec)\n",sum.v_pgin, s.pgintime/10);
                    272:        printf("average: %8.1f msec / page in\n", s.pgintime/(sum.v_pgin*10.0));
                    273: }
                    274: 
                    275: dosum()
                    276: {
                    277: 
                    278:        lseek(mf, (long)nl[X_SUM].n_value, 0);
                    279:        read(mf, &sum, sizeof sum);
                    280:        printf("%9d swap ins\n", sum.v_swpin);
                    281:        printf("%9d swap outs\n", sum.v_swpout);
                    282:        printf("%9d pages swapped in\n", sum.v_pswpin / CLSIZE);
                    283:        printf("%9d pages swapped out\n", sum.v_pswpout / CLSIZE);
                    284:        printf("%9d total address trans. faults taken\n", sum.v_faults);
                    285:        printf("%9d page ins\n", sum.v_pgin);
                    286:        printf("%9d page outs\n", sum.v_pgout);
                    287:        printf("%9d pages paged in\n", sum.v_pgpgin);
                    288:        printf("%9d pages paged out\n", sum.v_pgpgout);
                    289:        printf("%9d sequential process pages freed\n", sum.v_seqfree);
                    290:        printf("%9d total reclaims (%d%% fast)\n", sum.v_pgrec,
                    291:            (sum.v_fastpgrec * 100) / (sum.v_pgrec == 0 ? 1 : sum.v_pgrec));
                    292:        printf("%9d reclaims from free list\n", sum.v_pgfrec);
                    293:        printf("%9d intransit blocking page faults\n", sum.v_intrans);
                    294:        printf("%9d zero fill pages created\n", sum.v_nzfod / CLSIZE);
                    295:        printf("%9d zero fill page faults\n", sum.v_zfod / CLSIZE);
                    296:        printf("%9d executable fill pages created\n", sum.v_nexfod / CLSIZE);
                    297:        printf("%9d executable fill page faults\n", sum.v_exfod / CLSIZE);
                    298:        printf("%9d swap text pages found in free list\n", sum.v_xsfrec);
                    299:        printf("%9d inode text pages found in free list\n", sum.v_xifrec);
                    300:        printf("%9d file fill pages created\n", sum.v_nvrfod / CLSIZE);
                    301:        printf("%9d file fill page faults\n", sum.v_vrfod / CLSIZE);
                    302:        printf("%9d pages examined by the clock daemon\n", sum.v_scan);
                    303:        printf("%9d revolutions of the clock hand\n", sum.v_rev);
                    304:        printf("%9d pages freed by the clock daemon\n", sum.v_dfree / CLSIZE);
                    305:        printf("%9d cpu context switches\n", sum.v_swtch);
                    306:        printf("%9d device interrupts\n", sum.v_intr);
                    307:        printf("%9d pseduo-dma dz interrupts\n", sum.v_pdma);
                    308:        printf("%9d traps\n", sum.v_trap);
                    309:        printf("%9d system calls\n", sum.v_syscall);
                    310: }
                    311: 
                    312: doforkst()
                    313: {
                    314: 
                    315:        lseek(mf, (long)nl[X_FORKSTAT].n_value, 0);
                    316:        read(mf, &forkstat, sizeof forkstat);
                    317:        printf("%d forks, %d pages, average=%.2f\n",
                    318:                forkstat.cntfork, forkstat.sizfork,
                    319:                (float) forkstat.sizfork / forkstat.cntfork);
                    320:        printf("%d vforks, %d pages, average=%.2f\n",
                    321:                forkstat.cntvfork, forkstat.sizvfork,
                    322:                (float)forkstat.sizvfork / forkstat.cntvfork);
                    323: }
                    324: 
                    325: stats(dn)
                    326: {
                    327: 
                    328:        if (dn >= DK_NDRIVE) {
                    329:                printf("  0");
                    330:                return;
                    331:        }
                    332:        printf("%3.0f", s.xfer[dn]/etime);
                    333: }
                    334: 
                    335: double
                    336: stat1(row)
                    337: {
                    338:        double t;
                    339:        register i;
                    340: 
                    341:        t = 0;
                    342:        for(i=0; i<CPUSTATES; i++)
                    343:                t += s.time[i];
                    344:        if(t == 0.)
                    345:                t = 1.;
                    346:        return(s.time[row]*100./t);
                    347: }
                    348: 
                    349: pct(top, bot)
                    350: {
                    351: 
                    352:        if (bot == 0)
                    353:                return (0);
                    354:        return ((top * 100) / bot);
                    355: }
                    356: 
                    357: #define steal(where, var) lseek(mf, where, 0); read(mf, &var, sizeof var);
                    358: /*
                    359:  * Read the drive names out of kmem.
                    360:  */
                    361: #ifdef vax
                    362: read_names()
                    363: {
                    364:        struct mba_device mdev;
                    365:        register struct mba_device *mp;
                    366:        struct mba_driver mdrv;
                    367:        short two_char;
                    368:        char *cp = (char *) &two_char;
                    369:        struct uba_device udev, *up;
                    370:        struct uba_driver udrv;
                    371: 
                    372:        mp = (struct mba_device *) nl[X_MBDINIT].n_value;
                    373:        up = (struct uba_device *) nl[X_UBDINIT].n_value;
                    374:        if (up == 0) {
                    375:                fprintf(stderr, "vmstat: Disk init info not in namelist\n");
                    376:                exit(1);
                    377:        }
                    378:        if (mp) for (;;) {
                    379:                steal(mp++, mdev);
                    380:                if (mdev.mi_driver == 0)
                    381:                        break;
                    382:                if (mdev.mi_dk < 0 || mdev.mi_alive == 0)
                    383:                        continue;
                    384:                steal(mdev.mi_driver, mdrv);
                    385:                steal(mdrv.md_dname, two_char);
                    386:                sprintf(dr_name[mdev.mi_dk], "%c%c", cp[0], cp[1]);
                    387:                dr_unit[mdev.mi_dk] = mdev.mi_unit;
                    388:        }
                    389:        for (;;) {
                    390:                steal(up++, udev);
                    391:                if (udev.ui_driver == 0)
                    392:                        break;
                    393:                if (udev.ui_dk < 0 || udev.ui_alive == 0)
                    394:                        continue;
                    395:                steal(udev.ui_driver, udrv);
                    396:                steal(udrv.ud_dname, two_char);
                    397:                sprintf(dr_name[udev.ui_dk], "%c%c", cp[0], cp[1]);
                    398:                dr_unit[udev.ui_dk] = udev.ui_unit;
                    399:        }
                    400: }
                    401: #endif
                    402: 
                    403: #ifdef sun
                    404: read_names()
                    405: {
                    406:        struct mb_device mdev;
                    407:        register struct mb_device *mp;
                    408:        struct mb_driver mdrv;
                    409:        short two_char;
                    410:        char *cp = (char *) &two_char;
                    411: 
                    412:        mp = (struct mb_device *) nl[X_MBDINIT].n_value;
                    413:        if (mp == 0) {
                    414:                fprintf(stderr, "iostat: Disk init info not in namelist\n");
                    415:                exit(1);
                    416:        }
                    417:        for (;;) {
                    418:                steal(mp++, mdev);
                    419:                if (mdev.md_driver == 0)
                    420:                        break;
                    421:                if (mdev.md_dk < 0 || mdev.md_alive == 0)
                    422:                        continue;
                    423:                steal(mdev.md_driver, mdrv);
                    424:                steal(mdrv.mdr_dname, two_char);
                    425:                sprintf(dr_name[mdev.md_dk], "%c%c%d", cp[0], cp[1]);
                    426:                dr_unit[mdev.md_dk] = mdev.md_unit;
                    427:        }
                    428: }
                    429: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.