1: /*
   2:  * Copyright (c) 1980 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #if defined(DOSCCS) && !defined(lint)
   8: char copyright[] =
   9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
  10:  All rights reserved.\n";
  11: 
  12: static char sccsid[] = "@(#)vmstat.c	5.4.2 (2.11BSD GTE) 1997/3/28";
  13: #endif
  14: 
  15: #include <stdio.h>
  16: #include <ctype.h>
  17: #include <nlist.h>
  18: 
  19: #include <sys/param.h>
  20: #include <sys/file.h>
  21: #include <sys/vm.h>
  22: #include <sys/dk.h>
  23: #include <sys/buf.h>
  24: #include <sys/dir.h>
  25: #include <sys/inode.h>
  26: #include <sys/namei.h>
  27: #ifdef pdp11
  28: #include <machine/machparam.h>
  29: #include <sys/text.h>
  30: #endif
  31: 
  32: struct nlist nl[] = {
  33: #define X_CPTIME    0
  34:     { "_cp_time" },
  35: #define X_RATE      1
  36:     { "_rate" },
  37: #define X_TOTAL     2
  38:     { "_total" },
  39: #define X_DEFICIT   3
  40:     { "_deficit" },
  41: #define X_FORKSTAT  4
  42:     { "_forkstat" },
  43: #define X_SUM       5
  44:     { "_sum" },
  45: #define X_FIRSTFREE 6
  46:     { "_firstfree" },
  47: #define X_MAXFREE   7
  48:     { "_maxfree" },
  49: #define X_BOOTTIME  8
  50:     { "_boottime" },
  51: #define X_DKXFER    9
  52:     { "_dk_xfer" },
  53: #define X_REC       10
  54:     { "_rectime" },
  55: #define X_PGIN      11
  56:     { "_pgintime" },
  57: #define X_HZ        12
  58:     { "_hz" },
  59: #define X_PHZ       13
  60:     { "_phz" },
  61: #define X_NCHSTATS  14
  62:     { "_nchstats" },
  63: #define X_INTRNAMES 15
  64:     { "_intrnames" },
  65: #define X_EINTRNAMES    16
  66:     { "_eintrnames" },
  67: #define X_INTRCNT   17
  68:     { "_intrcnt" },
  69: #define X_EINTRCNT  18
  70:     { "_eintrcnt" },
  71: #define X_DK_NDRIVE 19
  72:     { "_dk_ndrive" },
  73: #define X_XSTATS    20
  74:     { "_xstats" },
  75: #ifdef pdp11
  76: #define X_DK_NAME   21
  77:     { "_dk_name" },
  78: #define X_DK_UNIT   22
  79:     { "_dk_unit" },
  80: #define X_FREEMEM   23
  81:     { "_freemem" },
  82: #else
  83: #define X_MBDINIT   21
  84:     { "_mbdinit" },
  85: #define X_UBDINIT   22
  86:     { "_ubdinit" },
  87: #endif
  88:     { "" },
  89: };
  90: 
  91: #ifdef pdp11
  92: char    **dk_name;
  93: int *dk_unit;
  94: struct  xstats  pxstats, cxstats;
  95: size_t  pfree;
  96: int flag29;
  97: #endif
  98: char    **dr_name;
  99: int *dr_select;
 100: int dk_ndrive;
 101: int ndrives = 0;
 102: #ifdef pdp11
 103: char    *defdrives[] = { "rp0", 0 };
 104: #else
 105: char    *defdrives[] = { "hp0", "hp1", "hp2",  0 };
 106: #endif
 107: double  stat1();
 108: int firstfree, maxfree;
 109: int hz;
 110: int phz;
 111: int HZ;
 112: 
 113: #if defined(vax) ||  defined(pdp11)
 114: #define INTS(x) ((x) - (hz + phz) < 0 ? 0 : (x) - (hz + phz))
 115: #endif
 116: 
 117: struct {
 118:     int busy;
 119:     long    time[CPUSTATES];
 120:     long    *xfer;
 121: #ifdef pdp11
 122:     struct  vmrate Rate;
 123:     struct  vmtotal Total;
 124:     struct  vmsum Sum;
 125: #else
 126:     struct  vmmeter Rate;
 127:     struct  vmtotal Total;
 128:     struct  vmmeter Sum;
 129: #endif
 130:     struct  forkstat Forkstat;
 131:     unsigned rectime;
 132:     unsigned pgintime;
 133: } s, s1, z;
 134: #define rate        s.Rate
 135: #define total       s.Total
 136: #define sum     s.Sum
 137: #define forkstat    s.Forkstat
 138: 
 139: #ifdef pdp11
 140: struct  vmsum osum;
 141: #else
 142: struct  vmmeter osum;
 143: #endif
 144: int deficit;
 145: double  etime;
 146: int     mf;
 147: time_t  now, boottime;
 148: int printhdr();
 149: int lines = 1;
 150: extern  char *calloc();
 151: 
 152: main(argc, argv)
 153:     int argc;
 154:     char **argv;
 155: {
 156:     extern char *ctime();
 157:     register i;
 158:     int iter, iflag = 0;
 159:     long nintv, t;
 160:     char *arg, **cp, buf[BUFSIZ];
 161: 
 162:     nlist("/vmunix", nl);
 163:     if(nl[0].n_type == 0) {
 164:         fprintf(stderr, "no /vmunix namelist\n");
 165:         exit(1);
 166:     }
 167:     mf = open("/dev/kmem", 0);
 168:     if(mf < 0) {
 169:         fprintf(stderr, "cannot open /dev/kmem\n");
 170:         exit(1);
 171:     }
 172:     iter = 0;
 173:     argc--, argv++;
 174:     while (argc>0 && argv[0][0]=='-') {
 175:         char *cp = *argv++;
 176:         argc--;
 177:         while (*++cp) switch (*cp) {
 178: 
 179:         case 't':
 180:             dotimes();
 181:             exit(0);
 182: 
 183:         case 'z':
 184:             close(mf);
 185:             mf = open("/dev/kmem", 2);
 186:             lseek(mf, (long)nl[X_SUM].n_value, L_SET);
 187:             write(mf, &z.Sum, sizeof z.Sum);
 188:             exit(0);
 189: 
 190:         case 'f':
 191:             doforkst();
 192:             exit(0);
 193: 
 194:         case 's':
 195:             dosum();
 196:             exit(0);
 197: 
 198:         case 'i':
 199:             iflag++;
 200:             break;
 201: #ifdef pdp11
 202:         case 'p':
 203:             flag29++;
 204:             break;
 205: #endif
 206: 
 207:         default:
 208:             fprintf(stderr,
 209:                 "usage: vmstat [ -fsi ] [ interval ] [ count]\n");
 210:             exit(1);
 211:         }
 212:     }
 213: #ifndef pdp11
 214:     lseek(mf, (long)nl[X_FIRSTFREE].n_value, L_SET);
 215:     read(mf, &firstfree, sizeof firstfree);
 216:     lseek(mf, (long)nl[X_MAXFREE].n_value, L_SET);
 217:     read(mf, &maxfree, sizeof maxfree);
 218: #endif
 219:     lseek(mf, (long)nl[X_BOOTTIME].n_value, L_SET);
 220:     read(mf, &boottime, sizeof boottime);
 221:     lseek(mf, (long)nl[X_HZ].n_value, L_SET);
 222:     read(mf, &hz, sizeof hz);
 223:     if (nl[X_PHZ].n_value != 0) {
 224:         lseek(mf, (long)nl[X_PHZ].n_value, L_SET);
 225:         read(mf, &phz, sizeof phz);
 226:     }
 227:     HZ = phz ? phz : hz;
 228:     if (nl[X_DK_NDRIVE].n_value == 0) {
 229:         fprintf(stderr, "dk_ndrive undefined in system\n");
 230:         exit(1);
 231:     }
 232:     lseek(mf, (long)nl[X_DK_NDRIVE].n_value, L_SET);
 233:     read(mf, &dk_ndrive, sizeof (dk_ndrive));
 234:     if (dk_ndrive <= 0) {
 235:         fprintf(stderr, "dk_ndrive %d\n", dk_ndrive);
 236:         exit(1);
 237:     }
 238:     dr_select = (int *)calloc(dk_ndrive, sizeof (int));
 239:     dr_name = (char **)calloc(dk_ndrive, sizeof (char *));
 240:     dk_name = (char **)calloc(dk_ndrive, sizeof (char *));
 241:     dk_unit = (int *)calloc(dk_ndrive, sizeof (int));
 242: #define allocate(e, t) \
 243:     s./**/e = (t *)calloc(dk_ndrive, sizeof (t)); \
 244:     s1./**/e = (t *)calloc(dk_ndrive, sizeof (t));
 245:     allocate(xfer, long);
 246:     for (arg = buf, i = 0; i < dk_ndrive; i++) {
 247:         dr_name[i] = arg;
 248:         sprintf(dr_name[i], "dk%d", i);
 249:         arg += strlen(dr_name[i]) + 1;
 250:     }
 251:     read_names();
 252:     time(&now);
 253:     nintv = now - boottime;
 254:     if (nintv <= 0 || nintv > 60L*60L*24L*365L*10L) {
 255:         fprintf(stderr,
 256:             "Time makes no sense... namelist must be wrong.\n");
 257:         exit(1);
 258:     }
 259:     if (iflag) {
 260:         dointr(nintv);
 261:         exit(0);
 262:     }
 263:     /*
 264: 	 * Choose drives to be displayed.  Priority
 265: 	 * goes to (in order) drives supplied as arguments,
 266: 	 * default drives.  If everything isn't filled
 267: 	 * in and there are drives not taken care of,
 268: 	 * display the first few that fit.
 269: 	 */
 270:     ndrives = 0;
 271:     while (argc > 0 && !isdigit(argv[0][0])) {
 272:         for (i = 0; i < dk_ndrive; i++) {
 273:             if (strcmp(dr_name[i], argv[0]))
 274:                 continue;
 275:             dr_select[i] = 1;
 276:             ndrives++;
 277:         }
 278:         argc--, argv++;
 279:     }
 280:     for (i = 0; i < dk_ndrive && ndrives < 4; i++) {
 281:         if (dr_select[i])
 282:             continue;
 283:         for (cp = defdrives; *cp; cp++)
 284:             if (strcmp(dr_name[i], *cp) == 0) {
 285:                 dr_select[i] = 1;
 286:                 ndrives++;
 287:                 break;
 288:             }
 289:     }
 290:     for (i = 0; i < dk_ndrive && ndrives < 4; i++) {
 291:         if (dr_select[i])
 292:             continue;
 293:         dr_select[i] = 1;
 294:         ndrives++;
 295:     }
 296: #ifdef pdp11
 297:     /* handle initial retrieval of the xstats structure */
 298:     lseek(mf, (long)nl[X_XSTATS].n_value, L_SET);
 299:     read(mf, &cxstats, sizeof(cxstats));
 300: #endif
 301:     if (argc > 1)
 302:         iter = atoi(argv[1]);
 303:     signal(SIGCONT, printhdr);
 304: loop:
 305:     if (--lines == 0)
 306:         printhdr();
 307:     lseek(mf, (long)nl[X_CPTIME].n_value, L_SET);
 308:     read(mf, s.time, sizeof s.time);
 309:     lseek(mf, (long)nl[X_DKXFER].n_value, L_SET);
 310:     read(mf, s.xfer, dk_ndrive * sizeof (long));
 311: #ifdef pdp11
 312:     /*
 313: 	 * This would be a whole lot easier if the variables in each
 314: 	 * were all longs...
 315: 	 */
 316:     if (nintv != 1) {
 317:         lseek(mf, (long)nl[X_SUM].n_value, L_SET);
 318:         read(mf, &sum, sizeof(sum));
 319:         rate.v_swtch = sum.v_swtch;
 320:         rate.v_trap = sum.v_trap;
 321:         rate.v_syscall = sum.v_syscall;
 322:         rate.v_intr = sum.v_intr;
 323:         rate.v_pdma = sum.v_pdma;
 324:         rate.v_ovly = sum.v_ovly;
 325:         rate.v_pgin = sum.v_pgin;
 326:         rate.v_pgout = sum.v_pgout;
 327:         rate.v_swpin = sum.v_swpin;
 328:         rate.v_swpout = sum.v_swpout;
 329:     }
 330:     else {
 331:         lseek(mf, (long)nl[X_RATE].n_value, L_SET);
 332:         read(mf, &rate, sizeof rate);
 333:         lseek(mf, (long)nl[X_SUM].n_value, L_SET);
 334:         read(mf, &sum, sizeof sum);
 335:     }
 336:     pxstats = cxstats;
 337:     lseek(mf, (long)nl[X_XSTATS].n_value, L_SET);
 338:     read(mf, &cxstats, sizeof(cxstats));
 339:     lseek(mf, (long)nl[X_FREEMEM].n_value, L_SET);
 340:     read(mf, &pfree, sizeof(pfree));
 341: #else
 342:     if (nintv != 1)
 343:         lseek(mf, (long)nl[X_SUM].n_value, L_SET);
 344:     else
 345:         lseek(mf, (long)nl[X_RATE].n_value, L_SET);
 346:     read(mf, &rate, sizeof rate);
 347: #endif
 348:     lseek(mf, (long)nl[X_TOTAL].n_value, L_SET);
 349:     read(mf, &total, sizeof total);
 350:     osum = sum;
 351:     lseek(mf, (long)nl[X_SUM].n_value, L_SET);
 352:     read(mf, &sum, sizeof sum);
 353:     lseek(mf, (long)nl[X_DEFICIT].n_value, L_SET);
 354:     read(mf, &deficit, sizeof deficit);
 355:     etime = 0;
 356:     for (i=0; i < dk_ndrive; i++) {
 357:         t = s.xfer[i];
 358:         s.xfer[i] -= s1.xfer[i];
 359:         s1.xfer[i] = t;
 360:     }
 361:     for (i=0; i < CPUSTATES; i++) {
 362:         t = s.time[i];
 363:         s.time[i] -= s1.time[i];
 364:         s1.time[i] = t;
 365:         etime += s.time[i];
 366:     }
 367:     if(etime == 0.)
 368:         etime = 1.;
 369: #ifdef pdp11
 370:     printf("%2d%2d%2d", total.t_rq, total.t_dw, total.t_sw);
 371:     /*
 372: 	 * We don't use total.t_free because it slops around too much
 373: 	 * within this kernel
 374: 	 */
 375:     printf("%6D", ctok(total.t_avm));
 376:     if (flag29)
 377:         printf("%4D",
 378:             total.t_avm ? (total.t_avmtxt * 100) / total.t_avm : 0);
 379:     printf("%6d", ctok(pfree));
 380: #else
 381:     printf("%2d%2d%2d", total.t_rq, total.t_dw+total.t_pw, total.t_sw);
 382: #define pgtok(a) ((a)*NBPG/1024)
 383:     printf("%6d%6d", pgtok(total.t_avm), pgtok(total.t_free));
 384: #endif
 385: #ifdef pdp11
 386:     if (flag29)
 387:         printf("%4D%3D  ", rate.v_swpin / nintv, rate.v_swpout / nintv);
 388:     else {
 389:         printf("%4D",
 390:             (cxstats.alloc_inuse - pxstats.alloc_inuse) / iter);
 391:         printf("%3D",
 392:             (cxstats.alloc_cachehit - pxstats.alloc_cachehit) / iter);
 393:         printf("%4D%4D", rate.v_pgin / nintv, rate.v_pgout / nintv);
 394:         printf("%4D", (cxstats.free - pxstats.free) / iter);
 395:         printf("%4D", (cxstats.free_cache - pxstats.free_cache) / iter);
 396:         printf("%4D", rate.v_ovly / nintv);
 397:     }
 398: #else
 399:     printf("%4d%3d", (rate.v_pgrec - (rate.v_xsfrec+rate.v_xifrec))/nintv,
 400:         (rate.v_xsfrec+rate.v_xifrec)/nintv);
 401:     printf("%4d", pgtok(rate.v_pgpgin)/nintv);
 402:     printf("%4d%4d%4d%4d", pgtok(rate.v_pgpgout)/nintv,
 403:         pgtok(rate.v_dfree)/nintv, pgtok(deficit), rate.v_scan/nintv);
 404: #endif
 405:     etime /= (float)HZ;
 406:     for (i = 0; i < dk_ndrive; i++)
 407:         if (dr_select[i])
 408:             stats(i);
 409: #ifdef pdp11
 410:     if (flag29)
 411:         printf("%4D%4D%4D%4D%4D%4D",
 412:             rate.v_pdma / nintv, INTS(rate.v_intr / nintv),
 413:             rate.v_syscall / nintv, rate.v_trap / nintv,
 414:             rate.v_ovly / nintv, rate.v_swtch / nintv);
 415:     else
 416: #endif
 417:     printf("%4D%4D%4D", INTS(rate.v_intr/nintv), rate.v_syscall/nintv,
 418:         rate.v_swtch/nintv);
 419:     for(i=0; i<CPUSTATES; i++) {
 420:         float f = stat1(i);
 421: #ifdef pdp11
 422:         if (!flag29)
 423: #endif
 424:         if (i == 0) {       /* US+NI */
 425:             i++;
 426:             f += stat1(i);
 427:         }
 428:         printf("%3.0f", f);
 429:     }
 430:     printf("\n");
 431:     fflush(stdout);
 432:     nintv = 1;
 433:     if (--iter &&argc > 0) {
 434:         sleep(atoi(argv[0]));
 435:         goto loop;
 436:     }
 437: }
 438: 
 439: printhdr()
 440: {
 441:     register int i, j;
 442: 
 443: #ifdef pdp11
 444:     if (flag29)
 445:         printf(" procs       memory      swap      ");
 446:     else
 447:         printf(" procs     memory              page           ");
 448: #else
 449:     printf(" procs     memory              page           ");
 450: #endif
 451:     i = (ndrives * 3 - 6) / 2;
 452:     if (i < 0)
 453:         i = 0;
 454:     for (j = 0; j < i; j++)
 455:         putchar(' ');
 456:     printf("faults");
 457:     i = ndrives * 3 - 6 - i;
 458:     for (j = 0; j < i; j++)
 459:         putchar(' ');
 460: #ifdef pdp11
 461:     if (flag29) {
 462:         printf("              cpu\n");
 463:         printf(" r b w   avm  tx   fre   i  o   ");
 464:     }
 465:     else {
 466:         printf("               cpu\n");
 467:         printf(" r b w   avm   fre  ti tc  pi  po  fr  fc  ov ");
 468:     }
 469: #else
 470:     printf("               cpu\n");
 471:     printf(" r b w   avm   fre  re at  pi  po  fr  de  sr ");
 472: #endif
 473:     for (i = 0; i < dk_ndrive; i++)
 474:         if (dr_select[i])
 475:             printf("%c%c ", dr_name[i][0], dr_name[i][2]);
 476: #ifdef pdp11
 477:     if (flag29)
 478:         printf(" pd  in  sy  tr  ov  cs us ni sy id\n");
 479:     else
 480: #endif
 481:     printf(" in  sy  cs us sy id\n");
 482:     lines = 19;
 483: }
 484: 
 485: dotimes()
 486: {
 487: #ifdef pdp11
 488:     printf("page in/out/reclamation is not applicable to 2.11BSD\n");
 489: #else
 490:     lseek(mf, (long)nl[X_REC].n_value, L_SET);
 491:     read(mf, &s.rectime, sizeof s.rectime);
 492:     lseek(mf, (long)nl[X_PGIN].n_value, L_SET);
 493:     read(mf, &s.pgintime, sizeof s.pgintime);
 494:     lseek(mf, (long)nl[X_SUM].n_value, L_SET);
 495:     read(mf, &sum, sizeof sum);
 496:     printf("%d reclaims, %d total time (usec)\n", sum.v_pgrec, s.rectime);
 497:     printf("average: %d usec / reclaim\n", s.rectime/sum.v_pgrec);
 498:     printf("\n");
 499:     printf("%d page ins, %d total time (msec)\n",sum.v_pgin, s.pgintime/10);
 500:     printf("average: %8.1f msec / page in\n", s.pgintime/(sum.v_pgin*10.0));
 501: #endif
 502: }
 503: 
 504: dosum()
 505: {
 506:     struct nchstats nchstats;
 507:     long nchtotal;
 508:     struct xstats  xstats;
 509: 
 510:     lseek(mf, (long)nl[X_SUM].n_value, L_SET);
 511:     read(mf, &sum, sizeof sum);
 512:     printf("%9D swap ins\n", sum.v_swpin);
 513:     printf("%9D swap outs\n", sum.v_swpout);
 514:     printf("%9D pages swapped in\n", sum.v_pswpin / CLSIZE);
 515:     printf("%9D pages swapped out\n", sum.v_pswpout / CLSIZE);
 516: #ifndef pdp11
 517:     printf("%9D total address trans. faults taken\n", sum.v_faults);
 518: #endif
 519:     printf("%9D page ins\n", sum.v_pgin);
 520:     printf("%9D page outs\n", sum.v_pgout);
 521: #ifndef pdp11
 522:     printf("%9D pages paged in\n", sum.v_pgpgin);
 523:     printf("%9D pages paged out\n", sum.v_pgpgout);
 524:     printf("%9D sequential process pages freed\n", sum.v_seqfree);
 525:     printf("%9D total reclaims (%d%% fast)\n", sum.v_pgrec,
 526:         (sum.v_fastpgrec * 100) / (sum.v_pgrec == 0 ? 1 : sum.v_pgrec));
 527:     printf("%9D reclaims from free list\n", sum.v_pgfrec);
 528:     printf("%9D intransit blocking page faults\n", sum.v_intrans);
 529:     printf("%9D zero fill pages created\n", sum.v_nzfod / CLSIZE);
 530:     printf("%9D zero fill page faults\n", sum.v_zfod / CLSIZE);
 531:     printf("%9D executable fill pages created\n", sum.v_nexfod / CLSIZE);
 532:     printf("%9D executable fill page faults\n", sum.v_exfod / CLSIZE);
 533:     printf("%9D swap text pages found in free list\n", sum.v_xsfrec);
 534:     printf("%9D inode text pages found in free list\n", sum.v_xifrec);
 535:     printf("%9D file fill pages created\n", sum.v_nvrfod / CLSIZE);
 536:     printf("%9D file fill page faults\n", sum.v_vrfod / CLSIZE);
 537:     printf("%9D pages examined by the clock daemon\n", sum.v_scan);
 538:     printf("%9D revolutions of the clock hand\n", sum.v_rev);
 539:     printf("%9D pages freed by the clock daemon\n", sum.v_dfree / CLSIZE);
 540: #endif
 541:     printf("%9D cpu context switches\n", sum.v_swtch);
 542:     printf("%9D device interrupts\n", sum.v_intr);
 543:     printf("%9D software interrupts\n", sum.v_soft);
 544: #if defined(vax) || defined(pdp11)
 545:     printf("%9D pseudo-dma dz interrupts\n", sum.v_pdma);
 546: #endif
 547:     printf("%9D traps\n", sum.v_trap);
 548: #ifdef pdp11
 549:     printf("%9D overlay emts\n", sum.v_ovly);
 550: #endif
 551:     printf("%9D system calls\n", sum.v_syscall);
 552: #define nz(x)   ((x) ? (x) : 1)
 553:     lseek(mf, (long)nl[X_NCHSTATS].n_value, 0);
 554:     read(mf, &nchstats, sizeof nchstats);
 555:     nchtotal = nchstats.ncs_goodhits + nchstats.ncs_badhits +
 556:         nchstats.ncs_falsehits + nchstats.ncs_miss + nchstats.ncs_long;
 557:     printf("%9D total name lookups", nchtotal);
 558:     printf(" (cache hits %D%% system %D%% per-process)\n",
 559:         nchstats.ncs_goodhits * 100 / nz(nchtotal),
 560:         nchstats.ncs_pass2 * 100 / nz(nchtotal));
 561:     printf("%9s badhits %D, falsehits %D, toolong %D\n", "",
 562:         nchstats.ncs_badhits, nchstats.ncs_falsehits, nchstats.ncs_long);
 563:     lseek(mf, (long)nl[X_XSTATS].n_value, 0);
 564:     read(mf, &xstats, sizeof xstats);
 565:     printf("%9D total calls to xalloc (cache hits %D%%)\n",
 566:         xstats.alloc, xstats.alloc_cachehit * 100 / nz(xstats.alloc));
 567:     printf("%9s sticky %ld flushed %ld unused %ld\n", "",
 568:         xstats.alloc_inuse, xstats.alloc_cacheflush, xstats.alloc_unused);
 569:     printf("%9D total calls to xfree", xstats.free);
 570:     printf(" (sticky %D cached %D swapped %D)\n",
 571:         xstats.free_inuse, xstats.free_cache, xstats.free_cacheswap);
 572: }
 573: 
 574: #ifdef pdp11
 575: char Pages[] = "clicks";
 576: #else
 577: char Pages[] = "pages";
 578: #endif
 579: 
 580: doforkst()
 581: {
 582:     lseek(mf, (long)nl[X_FORKSTAT].n_value, L_SET);
 583:     read(mf, &forkstat, sizeof forkstat);
 584:     printf("%D forks, %D %s, average=%.2f\n",
 585:         forkstat.cntfork, forkstat.sizfork, Pages,
 586:         (float) forkstat.sizfork / forkstat.cntfork);
 587:     printf("%D vforks, %D %s, average=%.2f\n",
 588:         forkstat.cntvfork, forkstat.sizvfork, Pages,
 589:         (float)forkstat.sizvfork / forkstat.cntvfork);
 590: }
 591: 
 592: stats(dn)
 593: {
 594: 
 595:     if (dn >= dk_ndrive) {
 596:         printf("  0");
 597:         return;
 598:     }
 599:     printf("%3.0f", s.xfer[dn]/etime);
 600: }
 601: 
 602: double
 603: stat1(row)
 604: {
 605:     double t;
 606:     register i;
 607: 
 608:     t = 0;
 609:     for(i=0; i<CPUSTATES; i++)
 610:         t += s.time[i];
 611:     if(t == 0.)
 612:         t = 1.;
 613:     return(s.time[row]*100./t);
 614: }
 615: 
 616: dointr(nintv)
 617:     long nintv;
 618: {
 619: #ifdef pdp11
 620:     printf("Device interrupt statistics are not applicable to 2.11BSD\n");
 621: #else
 622:     int nintr, inttotal;
 623:     long *intrcnt;
 624:     char *intrname, *malloc();
 625: 
 626:     nintr = (nl[X_EINTRCNT].n_value - nl[X_INTRCNT].n_value) / sizeof(long);
 627:     intrcnt = (long *) malloc(nl[X_EINTRCNT].n_value -
 628:         nl[X_INTRCNT].n_value);
 629:     intrname = malloc(nl[X_EINTRNAMES].n_value - nl[X_INTRNAMES].n_value);
 630:     if (intrcnt == NULL || intrname == NULL) {
 631:         fprintf(stderr, "vmstat: out of memory\n");
 632:         exit(9);
 633:     }
 634:     lseek(mf, (long)nl[X_INTRCNT].n_value, L_SET);
 635:     read(mf, intrcnt, nintr * sizeof (long));
 636:     lseek(mf, (long)nl[X_INTRNAMES].n_value, L_SET);
 637:     read(mf, intrname, nl[X_EINTRNAMES].n_value - nl[X_INTRNAMES].n_value);
 638:     printf("interrupt      total      rate\n");
 639:     inttotal = 0;
 640:     while (nintr--) {
 641:         if (*intrcnt)
 642:             printf("%-12s %8ld %8ld\n", intrname,
 643:                 *intrcnt, *intrcnt / nintv);
 644:         intrname += strlen(intrname) + 1;
 645:         inttotal += *intrcnt++;
 646:     }
 647:     printf("Total        %8ld %8ld\n", inttotal, inttotal / nintv);
 648: #endif
 649: }
 650: 
 651: #define steal(where, var) \
 652:     lseek(mf, where, L_SET); read(mf, &var, sizeof var);
 653: /*
 654:  * Read the drive names out of kmem.
 655:  */
 656: 
 657: #ifdef vax
 658: #include <vaxuba/ubavar.h>
 659: #include <vaxmba/mbavar.h>
 660: #endif
 661: 
 662: read_names()
 663: {
 664: #ifdef pdp11
 665:     char two_char[2];
 666:     register int i;
 667: 
 668:     lseek(mf, (long)nl[X_DK_NAME].n_value, L_SET);
 669:     read(mf, dk_name, dk_ndrive * sizeof (char *));
 670:     lseek(mf, (long)nl[X_DK_UNIT].n_value, L_SET);
 671:     read(mf, dk_unit, dk_ndrive * sizeof (int));
 672: 
 673:     for(i = 0; dk_name[i]; i++) {
 674:         lseek(mf, (long)dk_name[i], L_SET);
 675:         read(mf, two_char, sizeof two_char);
 676:         sprintf(dr_name[i], "%c%c%d", two_char[0], two_char[1],
 677:             dk_unit[i]);
 678:     }
 679: #else
 680: #ifdef vax
 681:     struct mba_device mdev;
 682:     register struct mba_device *mp;
 683:     struct mba_driver mdrv;
 684:     short two_char;
 685:     char *cp = (char *) &two_char;
 686:     struct uba_device udev, *up;
 687:     struct uba_driver udrv;
 688: 
 689:     mp = (struct mba_device *) nl[X_MBDINIT].n_value;
 690:     up = (struct uba_device *) nl[X_UBDINIT].n_value;
 691:     if (up == 0) {
 692:         fprintf(stderr, "vmstat: Disk init info not in namelist\n");
 693:         exit(1);
 694:     }
 695:     if (mp) for (;;) {
 696:         steal(mp++, mdev);
 697:         if (mdev.mi_driver == 0)
 698:             break;
 699:         if (mdev.mi_dk < 0 || mdev.mi_alive == 0)
 700:             continue;
 701:         steal(mdev.mi_driver, mdrv);
 702:         steal(mdrv.md_dname, two_char);
 703:         sprintf(dr_name[mdev.mi_dk], "%c%c%d",
 704:             cp[0], cp[1], mdev.mi_unit);
 705:     }
 706:     for (;;) {
 707:         steal(up++, udev);
 708:         if (udev.ui_driver == 0)
 709:             break;
 710:         if (udev.ui_dk < 0 || udev.ui_alive == 0)
 711:             continue;
 712:         steal(udev.ui_driver, udrv);
 713:         steal(udrv.ud_dname, two_char);
 714:         sprintf(dr_name[udev.ui_dk], "%c%c%d",
 715:             cp[0], cp[1], udev.ui_unit);
 716:     }
 717: #endif vax
 718: #endif /* pdp11 */
 719: }

Defined functions

doforkst defined in line 580; used 1 times
dointr defined in line 616; used 1 times
dosum defined in line 504; used 1 times
dotimes defined in line 485; used 1 times
main defined in line 152; never used
printhdr defined in line 439; used 3 times
read_names defined in line 662; used 1 times
stat1 defined in line 602; used 3 times
stats defined in line 592; used 1 times

Defined variables

HZ defined in line 111; used 2 times
Pages defined in line 577; used 2 times
boottime defined in line 147; used 3 times
copyright defined in line 8; never used
cxstats defined in line 94; used 9 times
defdrives defined in line 105; used 1 times
deficit defined in line 144; used 3 times
dk_name defined in line 92; used 4 times
dk_ndrive defined in line 100; used 21 times
dk_unit defined in line 93; used 3 times
dr_name defined in line 98; used 11 times
dr_select defined in line 99; used 8 times
etime defined in line 145; used 6 times
firstfree defined in line 108; used 2 times
  • in line 215(2)
flag29 defined in line 96; used 8 times
hz defined in line 109; used 5 times
lines defined in line 149; used 2 times
maxfree defined in line 108; used 2 times
  • in line 217(2)
mf defined in line 146; used 69 times
ndrives defined in line 101; used 8 times
nl defined in line 32; used 45 times
now defined in line 147; used 2 times
osum defined in line 142; used 1 times
pfree defined in line 95; used 3 times
phz defined in line 110; used 6 times
pxstats defined in line 94; used 5 times
sccsid defined in line 12; never used

Defined macros

INTS defined in line 114; used 2 times
X_BOOTTIME defined in line 49; used 1 times
X_CPTIME defined in line 33; used 1 times
X_DEFICIT defined in line 39; used 1 times
X_DKXFER defined in line 51; used 1 times
X_DK_NAME defined in line 76; used 1 times
X_DK_NDRIVE defined in line 71; used 2 times
X_DK_UNIT defined in line 78; used 1 times
X_EINTRCNT defined in line 69; used 2 times
X_EINTRNAMES defined in line 65; used 2 times
X_FIRSTFREE defined in line 45; used 1 times
X_FORKSTAT defined in line 41; used 1 times
X_FREEMEM defined in line 80; used 1 times
X_HZ defined in line 57; used 1 times
X_INTRCNT defined in line 67; used 3 times
X_INTRNAMES defined in line 63; used 3 times
X_MAXFREE defined in line 47; used 1 times
X_MBDINIT defined in line 83; used 1 times
X_NCHSTATS defined in line 61; used 1 times
X_PGIN defined in line 55; used 1 times
X_PHZ defined in line 59; used 2 times
X_RATE defined in line 35; used 2 times
X_REC defined in line 53; used 1 times
X_SUM defined in line 43; used 7 times
X_TOTAL defined in line 37; used 1 times
X_UBDINIT defined in line 85; used 1 times
X_XSTATS defined in line 73; used 3 times
allocate defined in line 242; used 1 times
forkstat defined in line 137; used 10 times
nz defined in line 552; used 3 times
pgtok defined in line 382; used 6 times
rate defined in line 134; used 37 times
steal defined in line 651; used 6 times
sum defined in line 136; used 59 times
total defined in line 135; used 15 times
Last modified: 1997-03-29
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4807
Valid CSS Valid XHTML 1.0 Strict