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