|
|
1.1 ! root 1: static char *sccsid = "@(#)vmstat.c 4.7 (Berkeley) 4/28/81"; ! 2: #include <stdio.h> ! 3: #include <sys/param.h> ! 4: #include <sys/vm.h> ! 5: #include <sys/dk.h> ! 6: #include <nlist.h> ! 7: #include <sys/buf.h> ! 8: #include <machine/mbvar.h> ! 9: ! 10: struct nlist nl[] = { ! 11: #define X_CPTIME 0 ! 12: { "_cp_time" }, ! 13: #define X_RATE 1 ! 14: { "_rate" }, ! 15: #define X_TOTAL 2 ! 16: { "_total" }, ! 17: #define X_DEFICIT 3 ! 18: { "_deficit" }, ! 19: #define X_FORKSTAT 4 ! 20: { "_forkstat" }, ! 21: #define X_SUM 5 ! 22: { "_sum" }, ! 23: #define X_FIRSTFREE 6 ! 24: { "_firstfree" }, ! 25: #define X_MAXFREE 7 ! 26: { "_maxfree" }, ! 27: #define X_BOOTIME 8 ! 28: { "_bootime" }, ! 29: #define X_DKXFER 9 ! 30: { "_dk_xfer" }, ! 31: #define X_MBDINIT 10 ! 32: { "_mbdinit" }, ! 33: #define X_REC 11 ! 34: { "_rectime" }, ! 35: #define X_PGIN 12 ! 36: { "_pgintime" }, ! 37: #define X_HZ 13 ! 38: { "_hz" }, ! 39: { 0 }, ! 40: }; ! 41: ! 42: char dr_name[DK_NDRIVE][10]; ! 43: char dr_unit[DK_NDRIVE]; ! 44: double stat1(); ! 45: int firstfree, maxfree; ! 46: int hz; ! 47: struct ! 48: { ! 49: int busy; ! 50: long time[CPUSTATES]; ! 51: long xfer[DK_NDRIVE]; ! 52: struct vmmeter Rate; ! 53: struct vmtotal Total; ! 54: struct vmmeter Sum; ! 55: struct forkstat Forkstat; ! 56: unsigned rectime; ! 57: unsigned pgintime; ! 58: } s, s1, z; ! 59: #define rate s.Rate ! 60: #define total s.Total ! 61: #define sum s.Sum ! 62: #define forkstat s.Forkstat ! 63: ! 64: int zero; ! 65: int deficit; ! 66: double etime; ! 67: int mf; ! 68: ! 69: main(argc, argv) ! 70: char **argv; ! 71: { ! 72: time_t now; ! 73: int lines; ! 74: extern char *ctime(); ! 75: register i,j; ! 76: int iter, nintv; ! 77: time_t bootime; ! 78: double f1, f2; ! 79: long t; ! 80: extern char _sobuf[]; ! 81: ! 82: setbuf(stdout, _sobuf); ! 83: nlist("/unix", nl); ! 84: if(nl[0].n_type == 0) { ! 85: printf("no /unix namelist\n"); ! 86: exit(1); ! 87: } ! 88: mf = open("/dev/kmem", 0); ! 89: if(mf < 0) { ! 90: printf("cannot open /dev/kmem\n"); ! 91: exit(1); ! 92: } ! 93: iter = 0; ! 94: argc--, argv++; ! 95: while (argc>0 && argv[0][0]=='-') { ! 96: char *cp = *argv++; ! 97: argc--; ! 98: while (*++cp) switch (*cp) { ! 99: ! 100: case 't': ! 101: dotimes(); ! 102: exit(0); ! 103: case 'z': ! 104: close(mf); ! 105: mf = open("/dev/kmem", 2); ! 106: lseek(mf, (long)nl[X_SUM].n_value, 0); ! 107: write(mf, &z.Sum, sizeof z.Sum); ! 108: exit(0); ! 109: ! 110: case 'f': ! 111: doforkst(); ! 112: exit(0); ! 113: ! 114: case 's': ! 115: dosum(); ! 116: exit(0); ! 117: ! 118: default: ! 119: fprintf(stderr, "usage: vmstat [ -fs ] [ interval ] [ count]\n"); ! 120: exit(1); ! 121: } ! 122: } ! 123: if(argc > 1) ! 124: iter = atoi(argv[1]); ! 125: lseek(mf, (long)nl[X_FIRSTFREE].n_value, 0); ! 126: read(mf, &firstfree, sizeof firstfree); ! 127: lseek(mf, (long)nl[X_MAXFREE].n_value, 0); ! 128: read(mf, &maxfree, sizeof maxfree); ! 129: lseek(mf, (long)nl[X_BOOTIME].n_value, 0); ! 130: read(mf, &bootime, sizeof bootime); ! 131: lseek(mf, (long)nl[X_HZ].n_value, 0); ! 132: read(mf, &hz, sizeof hz); ! 133: for (i = 0; i < DK_NDRIVE; i++) { ! 134: strcpy(dr_name[i], "xx"); ! 135: dr_unit[i] = i; ! 136: } ! 137: read_names(); ! 138: time(&now); ! 139: nintv = now - bootime; ! 140: if (nintv <= 0 || nintv > 60*60*24*365*10) { ! 141: printf("Time makes no sense... namelist must be wrong.\n"); ! 142: exit(1); ! 143: } ! 144: reprint: ! 145: lines = 20; ! 146: /* s1 = z; */ ! 147: printf("\ ! 148: procs memory page disk faults cpu\n\ ! 149: r b w avm fre re at pi po fr de sr %c%d %c%d %c%d %c%d in sy cs us sy id\n\ ! 150: ", 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]); ! 151: loop: ! 152: lseek(mf, (long)nl[X_CPTIME].n_value, 0); ! 153: read(mf, s.time, sizeof s.time); ! 154: lseek(mf, (long)nl[X_DKXFER].n_value, 0); ! 155: read(mf, s.xfer, sizeof s.xfer); ! 156: if (nintv != 1) { ! 157: lseek(mf, (long)nl[X_SUM].n_value, 0); ! 158: read(mf, &rate, sizeof rate); ! 159: } else { ! 160: lseek(mf, (long)nl[X_RATE].n_value, 0); ! 161: read(mf, &rate, sizeof rate); ! 162: } ! 163: lseek(mf, (long)nl[X_TOTAL].n_value, 0); ! 164: read(mf, &total, sizeof total); ! 165: lseek(mf, (long)nl[X_DEFICIT].n_value, 0); ! 166: read(mf, &deficit, sizeof deficit); ! 167: etime = 0; ! 168: for (i=0; i < DK_NDRIVE; i++) { ! 169: t = s.xfer[i]; ! 170: s.xfer[i] -= s1.xfer[i]; ! 171: s1.xfer[i] = t; ! 172: } ! 173: for (i=0; i < CPUSTATES; i++) { ! 174: t = s.time[i]; ! 175: s.time[i] -= s1.time[i]; ! 176: s1.time[i] = t; ! 177: etime += s.time[i]; ! 178: } ! 179: if(etime == 0.) ! 180: etime = 1.; ! 181: printf("%2d%2d%2d", total.t_rq, total.t_dw+total.t_pw, total.t_sw); ! 182: printf("%6d%5d", total.t_avm/2, total.t_free/2); ! 183: printf("%4d%3d%4d", ! 184: (rate.v_pgrec - (rate.v_xsfrec+rate.v_xifrec))/nintv, ! 185: (rate.v_xsfrec+rate.v_xifrec)/nintv, rate.v_pgpgin/2/nintv); ! 186: printf("%4d%4d%4d%4d", rate.v_pgpgout/2/nintv, ! 187: rate.v_dfree/2/nintv, deficit/2, rate.v_scan/nintv); ! 188: etime /= 60.; ! 189: for(i=0; i<4; i++) ! 190: stats(i); ! 191: printf("%4d%4d", (rate.v_intr/nintv) - hz, rate.v_syscall/nintv); ! 192: printf("%4d", rate.v_swtch/nintv); ! 193: for(i=0; i<CPUSTATES; i++) { ! 194: float f = stat1(i); ! 195: if (i == 0) { /* US+NI */ ! 196: i++; ! 197: f += stat1(i); ! 198: } ! 199: printf("%3.0f", f); ! 200: } ! 201: printf("\n"); ! 202: fflush(stdout); ! 203: contin: ! 204: nintv = 1; ! 205: --iter; ! 206: if(iter) ! 207: if(argc > 0) { ! 208: sleep(atoi(argv[0])); ! 209: if (--lines <= 0) ! 210: goto reprint; ! 211: goto loop; ! 212: } ! 213: } ! 214: ! 215: dotimes() ! 216: { ! 217: ! 218: lseek(mf, (long)nl[X_REC].n_value, 0); ! 219: read(mf, &s.rectime, sizeof s.rectime); ! 220: lseek(mf, (long)nl[X_PGIN].n_value, 0); ! 221: read(mf, &s.pgintime, sizeof s.pgintime); ! 222: lseek(mf, (long)nl[X_SUM].n_value, 0); ! 223: read(mf, &sum, sizeof sum); ! 224: printf("%d reclaims, %d total time (usec)\n", sum.v_pgrec, s.rectime); ! 225: printf("average: %d usec / reclaim\n", s.rectime/sum.v_pgrec); ! 226: printf("\n"); ! 227: printf("%d page ins, %d total time (msec)\n",sum.v_pgin, s.pgintime/10); ! 228: printf("average: %8.1f msec / page in\n", s.pgintime/(sum.v_pgin*10.0)); ! 229: } ! 230: ! 231: dosum() ! 232: { ! 233: ! 234: lseek(mf, (long)nl[X_SUM].n_value, 0); ! 235: read(mf, &sum, sizeof sum); ! 236: printf("%9d swap ins\n", sum.v_swpin); ! 237: printf("%9d swap outs\n", sum.v_swpout); ! 238: printf("%9d pages swapped in\n", sum.v_pswpin / CLSIZE); ! 239: printf("%9d pages swapped out\n", sum.v_pswpout / CLSIZE); ! 240: printf("%9d total address trans. faults taken\n", sum.v_faults); ! 241: printf("%9d page ins\n", sum.v_pgin); ! 242: printf("%9d page outs\n", sum.v_pgout); ! 243: printf("%9d pages paged in\n", sum.v_pgpgin); ! 244: printf("%9d pages paged out\n", sum.v_pgpgout); ! 245: printf("%9d sequential process pages freed\n", sum.v_seqfree); ! 246: printf("%9d total reclaims\n", sum.v_pgrec); ! 247: printf("%9d reclaims from free list\n", sum.v_pgfrec); ! 248: printf("%9d intransit blocking page faults\n", sum.v_intrans); ! 249: printf("%9d zero fill pages created\n", sum.v_nzfod / CLSIZE); ! 250: printf("%9d zero fill page faults\n", sum.v_zfod / CLSIZE); ! 251: printf("%9d executable fill pages created\n", sum.v_nexfod / CLSIZE); ! 252: printf("%9d executable fill page faults\n", sum.v_exfod / CLSIZE); ! 253: printf("%9d swap text pages found in free list\n", sum.v_xsfrec); ! 254: printf("%9d inode text pages found in free list\n", sum.v_xifrec); ! 255: printf("%9d file fill pages created\n", sum.v_nvrfod / CLSIZE); ! 256: printf("%9d file fill page faults\n", sum.v_vrfod / CLSIZE); ! 257: printf("%9d pages examined by the clock daemon\n", sum.v_scan); ! 258: printf("%9d revolutions of the clock hand\n", sum.v_rev); ! 259: printf("%9d pages freed by the clock daemon\n", sum.v_dfree / CLSIZE); ! 260: printf("%9d cpu context switches\n", sum.v_swtch); ! 261: printf("%9d device interrupts\n", sum.v_intr); ! 262: printf("%9d pseduo-dma dz interrupts\n", sum.v_pdma); ! 263: printf("%9d traps\n", sum.v_trap); ! 264: printf("%9d system calls\n", sum.v_syscall); ! 265: } ! 266: ! 267: ! 268: doforkst() ! 269: { ! 270: ! 271: lseek(mf, (long)nl[X_FORKSTAT].n_value, 0); ! 272: read(mf, &forkstat, sizeof forkstat); ! 273: printf("%d forks, %d pages, average=%.2f\n", ! 274: forkstat.cntfork, forkstat.sizfork, ! 275: (float) forkstat.sizfork / forkstat.cntfork); ! 276: printf("%d vforks, %d pages, average=%.2f\n", ! 277: forkstat.cntvfork, forkstat.sizvfork, ! 278: (float)forkstat.sizvfork / forkstat.cntvfork); ! 279: } ! 280: ! 281: stats(dn) ! 282: { ! 283: ! 284: if (dn >= DK_NDRIVE) { ! 285: printf(" 0"); ! 286: return; ! 287: } ! 288: printf("%3.0f", s.xfer[dn]/etime); ! 289: } ! 290: ! 291: double ! 292: stat1(row) ! 293: { ! 294: double t; ! 295: register i; ! 296: ! 297: t = 0; ! 298: for(i=0; i<CPUSTATES; i++) ! 299: t += s.time[i]; ! 300: if(t == 0.) ! 301: t = 1.; ! 302: return(s.time[row]*100./t); ! 303: } ! 304: ! 305: pct(top, bot) ! 306: { ! 307: ! 308: if (bot == 0) ! 309: return (0); ! 310: return ((top * 100) / bot); ! 311: } ! 312: ! 313: /* ! 314: * Read the drive names out of kmem. ! 315: * ARGH ARGH ARGH ARGH !!!!!!!!!!!! ! 316: */ ! 317: ! 318: #define steal(where, var) lseek(mf, where, 0); read(mf, &var, sizeof var); ! 319: read_names() ! 320: { ! 321: struct mb_device mdev; ! 322: register struct mb_device *mp; ! 323: struct mb_driver mdrv; ! 324: short two_char; ! 325: char *cp = (char *) &two_char; ! 326: ! 327: mp = (struct mb_device *) nl[X_MBDINIT].n_value; ! 328: if (mp) for (;;) { ! 329: steal(mp++, mdev); ! 330: if (mdev.md_driver == 0) ! 331: break; ! 332: if (mdev.md_dk < 0 || mdev.md_alive == 0) ! 333: continue; ! 334: steal(mdev.md_driver, mdrv); ! 335: steal(mdrv.mdr_dname, two_char); ! 336: sprintf(dr_name[mdev.md_dk], "%c%c", cp[0], cp[1]); ! 337: dr_unit[mdev.md_dk] = mdev.md_unit; ! 338: } ! 339: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.