|
|
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.