date and time created 90/06/01 18:19:33 by bostic
[unix-history] / usr / src / usr.bin / vmstat / vmstat.c
CommitLineData
f42904bc 1/*
01c8685d
KB
2 * Copyright (c) 1980 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
f42904bc
DF
16 */
17
18#ifndef lint
19char copyright[] =
01c8685d 20"@(#) Copyright (c) 1980 The Regents of the University of California.\n\
f42904bc 21 All rights reserved.\n";
01c8685d 22#endif /* not lint */
f42904bc 23
338c4a5d 24#ifndef lint
fa230d07 25static char sccsid[] = "@(#)vmstat.c 5.19 (Berkeley) %G%";
01c8685d 26#endif /* not lint */
338c4a5d 27
7f02df2f 28#include <sys/param.h>
a448353a 29#include <sys/file.h>
7f02df2f 30#include <sys/vm.h>
920a4346 31#include <sys/dkstat.h>
61d7d2b3 32#include <sys/buf.h>
4b894a2c 33#include <sys/namei.h>
242684ee 34#include <sys/text.h>
0c429495 35#include <sys/malloc.h>
f5506e0f
KB
36#include <stdio.h>
37#include <ctype.h>
38#include <nlist.h>
39#include <paths.h>
7f02df2f
BJ
40
41struct nlist nl[] = {
682f1dcb
BJ
42#define X_CPTIME 0
43 { "_cp_time" },
44#define X_RATE 1
7f02df2f 45 { "_rate" },
682f1dcb 46#define X_TOTAL 2
7f02df2f 47 { "_total" },
682f1dcb 48#define X_DEFICIT 3
7f02df2f 49 { "_deficit" },
682f1dcb 50#define X_FORKSTAT 4
7f02df2f 51 { "_forkstat" },
682f1dcb 52#define X_SUM 5
7f02df2f 53 { "_sum" },
682f1dcb 54#define X_FIRSTFREE 6
7f02df2f 55 { "_firstfree" },
682f1dcb 56#define X_MAXFREE 7
7f02df2f 57 { "_maxfree" },
a43be079
SL
58#define X_BOOTTIME 8
59 { "_boottime" },
682f1dcb
BJ
60#define X_DKXFER 9
61 { "_dk_xfer" },
338c4a5d 62#define X_REC 10
7f02df2f 63 { "_rectime" },
338c4a5d 64#define X_PGIN 11
7f02df2f 65 { "_pgintime" },
338c4a5d 66#define X_HZ 12
61d7d2b3 67 { "_hz" },
a448353a 68#define X_PHZ 13
b3a37270 69 { "_phz" },
dfdfb4c8
KM
70#define X_NCHSTATS 14
71 { "_nchstats" },
4b894a2c
KM
72#define X_INTRNAMES 15
73 { "_intrnames" },
74#define X_EINTRNAMES 16
75 { "_eintrnames" },
76#define X_INTRCNT 17
77 { "_intrcnt" },
78#define X_EINTRCNT 18
79 { "_eintrcnt" },
a448353a
SL
80#define X_DK_NDRIVE 19
81 { "_dk_ndrive" },
b6b10463
SL
82#define X_XSTATS 20
83 { "_xstats" },
0c429495
KM
84#define X_KMEMSTAT 21
85 { "_kmemstats" },
86#define X_KMEMBUCKETS 22
87 { "_bucket" },
338c4a5d 88#ifdef vax
242684ee 89#define X_MBDINIT (X_XSTATS+1)
338c4a5d 90 { "_mbdinit" },
242684ee 91#define X_UBDINIT (X_XSTATS+2)
338c4a5d 92 { "_ubdinit" },
242684ee 93#endif
242684ee
SL
94#ifdef tahoe
95#define X_VBDINIT (X_XSTATS+1)
96 { "_vbdinit" },
7aa7d88f
SL
97#define X_CKEYSTATS (X_XSTATS+2)
98 { "_ckeystats" },
99#define X_DKEYSTATS (X_XSTATS+3)
100 { "_dkeystats" },
338c4a5d
SL
101#endif
102 { "" },
7f02df2f
BJ
103};
104
a448353a
SL
105char **dr_name;
106int *dr_select;
107int dk_ndrive;
108int ndrives = 0;
109#ifdef vax
110char *defdrives[] = { "hp0", "hp1", "hp2", 0 };
111#else
112char *defdrives[] = { 0 };
113#endif
7f02df2f
BJ
114double stat1();
115int firstfree, maxfree;
61d7d2b3 116int hz;
b3a37270
SL
117int phz;
118int HZ;
a448353a 119
a448353a 120struct {
7f02df2f 121 int busy;
682f1dcb 122 long time[CPUSTATES];
a448353a 123 long *xfer;
7f02df2f
BJ
124 struct vmmeter Rate;
125 struct vmtotal Total;
126 struct vmmeter Sum;
127 struct forkstat Forkstat;
7f02df2f
BJ
128 unsigned rectime;
129 unsigned pgintime;
7f02df2f
BJ
130} s, s1, z;
131#define rate s.Rate
132#define total s.Total
133#define sum s.Sum
134#define forkstat s.Forkstat
135
338c4a5d 136struct vmmeter osum;
7f02df2f
BJ
137int deficit;
138double etime;
139int mf;
4b894a2c
KM
140time_t now, boottime;
141int printhdr();
196ccf10 142int lines = 1;
7f02df2f 143
920a4346
SL
144#define INTS(x) ((x) - (hz + phz))
145
7f02df2f 146main(argc, argv)
338c4a5d
SL
147 int argc;
148 char **argv;
7f02df2f 149{
7f02df2f 150 extern char *ctime();
920a4346 151 register i;
4b894a2c 152 int iter, nintv, iflag = 0;
7f02df2f 153 long t;
920a4346 154 char *arg, **cp, buf[BUFSIZ];
7f02df2f 155
f5506e0f 156 nlist(_PATH_UNIX, nl);
7f02df2f 157 if(nl[0].n_type == 0) {
f5506e0f 158 fprintf(stderr, "vmstat: no %s namelist\n", _PATH_UNIX);
7f02df2f
BJ
159 exit(1);
160 }
f5506e0f 161 mf = open(_PATH_KMEM, 0);
7f02df2f 162 if(mf < 0) {
f5506e0f 163 fprintf(stderr, "vmstat: cannot open %s\n", _PATH_KMEM);
7f02df2f
BJ
164 exit(1);
165 }
166 iter = 0;
167 argc--, argv++;
168 while (argc>0 && argv[0][0]=='-') {
169 char *cp = *argv++;
170 argc--;
171 while (*++cp) switch (*cp) {
172
7f02df2f
BJ
173 case 't':
174 dotimes();
175 exit(0);
338c4a5d 176
7f02df2f
BJ
177 case 'z':
178 close(mf);
f5506e0f 179 mf = open(_PATH_KMEM, 2);
a448353a 180 lseek(mf, (long)nl[X_SUM].n_value, L_SET);
7f02df2f
BJ
181 write(mf, &z.Sum, sizeof z.Sum);
182 exit(0);
183
184 case 'f':
185 doforkst();
186 exit(0);
187
0c429495
KM
188 case 'm':
189 domem();
190 exit(0);
191
7f02df2f
BJ
192 case 's':
193 dosum();
194 exit(0);
195
4b894a2c
KM
196 case 'i':
197 iflag++;
198 break;
199
7f02df2f 200 default:
a448353a 201 fprintf(stderr,
0c429495 202 "usage: vmstat [ -fsim ] [ interval ] [ count]\n");
7f02df2f
BJ
203 exit(1);
204 }
205 }
a448353a 206 lseek(mf, (long)nl[X_FIRSTFREE].n_value, L_SET);
7f02df2f 207 read(mf, &firstfree, sizeof firstfree);
a448353a 208 lseek(mf, (long)nl[X_MAXFREE].n_value, L_SET);
7f02df2f 209 read(mf, &maxfree, sizeof maxfree);
a448353a 210 lseek(mf, (long)nl[X_BOOTTIME].n_value, L_SET);
a43be079 211 read(mf, &boottime, sizeof boottime);
a448353a 212 lseek(mf, (long)nl[X_HZ].n_value, L_SET);
61d7d2b3 213 read(mf, &hz, sizeof hz);
a448353a
SL
214 if (nl[X_PHZ].n_value != 0) {
215 lseek(mf, (long)nl[X_PHZ].n_value, L_SET);
216 read(mf, &phz, sizeof phz);
217 }
b3a37270 218 HZ = phz ? phz : hz;
9a122ff6 219 if (nl[X_DK_NDRIVE].n_value == 0) {
920a4346 220 fprintf(stderr, "dk_ndrive undefined in system\n");
a448353a
SL
221 exit(1);
222 }
223 lseek(mf, nl[X_DK_NDRIVE].n_value, L_SET);
224 read(mf, &dk_ndrive, sizeof (dk_ndrive));
225 if (dk_ndrive <= 0) {
920a4346 226 fprintf(stderr, "dk_ndrive %d\n", dk_ndrive);
a448353a
SL
227 exit(1);
228 }
229 dr_select = (int *)calloc(dk_ndrive, sizeof (int));
230 dr_name = (char **)calloc(dk_ndrive, sizeof (char *));
231#define allocate(e, t) \
232 s./**/e = (t *)calloc(dk_ndrive, sizeof (t)); \
233 s1./**/e = (t *)calloc(dk_ndrive, sizeof (t));
234 allocate(xfer, long);
235 for (arg = buf, i = 0; i < dk_ndrive; i++) {
236 dr_name[i] = arg;
237 sprintf(dr_name[i], "dk%d", i);
238 arg += strlen(dr_name[i]) + 1;
61d7d2b3
MT
239 }
240 read_names();
7f02df2f 241 time(&now);
a43be079 242 nintv = now - boottime;
7f02df2f 243 if (nintv <= 0 || nintv > 60*60*24*365*10) {
920a4346
SL
244 fprintf(stderr,
245 "Time makes no sense... namelist must be wrong.\n");
7f02df2f
BJ
246 exit(1);
247 }
4b894a2c
KM
248 if (iflag) {
249 dointr(nintv);
250 exit(0);
251 }
a448353a
SL
252 /*
253 * Choose drives to be displayed. Priority
254 * goes to (in order) drives supplied as arguments,
255 * default drives. If everything isn't filled
256 * in and there are drives not taken care of,
257 * display the first few that fit.
258 */
259 ndrives = 0;
260 while (argc > 0 && !isdigit(argv[0][0])) {
261 for (i = 0; i < dk_ndrive; i++) {
262 if (strcmp(dr_name[i], argv[0]))
263 continue;
264 dr_select[i] = 1;
265 ndrives++;
266 }
267 argc--, argv++;
268 }
269 for (i = 0; i < dk_ndrive && ndrives < 4; i++) {
270 if (dr_select[i])
271 continue;
272 for (cp = defdrives; *cp; cp++)
273 if (strcmp(dr_name[i], *cp) == 0) {
274 dr_select[i] = 1;
275 ndrives++;
276 break;
277 }
278 }
279 for (i = 0; i < dk_ndrive && ndrives < 4; i++) {
280 if (dr_select[i])
281 continue;
282 dr_select[i] = 1;
283 ndrives++;
284 }
285 if (argc > 1)
286 iter = atoi(argv[1]);
4b894a2c 287 signal(SIGCONT, printhdr);
7f02df2f 288loop:
196ccf10
SL
289 if (--lines == 0)
290 printhdr();
a448353a 291 lseek(mf, (long)nl[X_CPTIME].n_value, L_SET);
682f1dcb 292 read(mf, s.time, sizeof s.time);
a448353a
SL
293 lseek(mf, (long)nl[X_DKXFER].n_value, L_SET);
294 read(mf, s.xfer, dk_ndrive * sizeof (long));
295 if (nintv != 1)
296 lseek(mf, (long)nl[X_SUM].n_value, L_SET);
297 else
298 lseek(mf, (long)nl[X_RATE].n_value, L_SET);
299 read(mf, &rate, sizeof rate);
300 lseek(mf, (long)nl[X_TOTAL].n_value, L_SET);
7f02df2f 301 read(mf, &total, sizeof total);
338c4a5d 302 osum = sum;
a448353a 303 lseek(mf, (long)nl[X_SUM].n_value, L_SET);
338c4a5d 304 read(mf, &sum, sizeof sum);
a448353a 305 lseek(mf, (long)nl[X_DEFICIT].n_value, L_SET);
7f02df2f 306 read(mf, &deficit, sizeof deficit);
682f1dcb 307 etime = 0;
a448353a 308 for (i=0; i < dk_ndrive; i++) {
682f1dcb
BJ
309 t = s.xfer[i];
310 s.xfer[i] -= s1.xfer[i];
311 s1.xfer[i] = t;
7f02df2f
BJ
312 }
313 for (i=0; i < CPUSTATES; i++) {
682f1dcb
BJ
314 t = s.time[i];
315 s.time[i] -= s1.time[i];
316 s1.time[i] = t;
317 etime += s.time[i];
7f02df2f 318 }
7f02df2f
BJ
319 if(etime == 0.)
320 etime = 1.;
61d7d2b3 321 printf("%2d%2d%2d", total.t_rq, total.t_dw+total.t_pw, total.t_sw);
338c4a5d 322#define pgtok(a) ((a)*NBPG/1024)
920a4346 323 printf("%6d%6d", pgtok(total.t_avm), pgtok(total.t_free));
b3a37270
SL
324 printf("%4d%3d", (rate.v_pgrec - (rate.v_xsfrec+rate.v_xifrec))/nintv,
325 (rate.v_xsfrec+rate.v_xifrec)/nintv);
338c4a5d
SL
326 printf("%4d", pgtok(rate.v_pgpgin)/nintv);
327 printf("%4d%4d%4d%4d", pgtok(rate.v_pgpgout)/nintv,
328 pgtok(rate.v_dfree)/nintv, pgtok(deficit), rate.v_scan/nintv);
a448353a
SL
329 etime /= (float)HZ;
330 for (i = 0; i < dk_ndrive; i++)
331 if (dr_select[i])
332 stats(i);
b3a37270
SL
333 printf("%4d%4d%4d", INTS(rate.v_intr/nintv), rate.v_syscall/nintv,
334 rate.v_swtch/nintv);
7f02df2f
BJ
335 for(i=0; i<CPUSTATES; i++) {
336 float f = stat1(i);
337 if (i == 0) { /* US+NI */
338 i++;
339 f += stat1(i);
340 }
341 printf("%3.0f", f);
342 }
343 printf("\n");
344 fflush(stdout);
7f02df2f 345 nintv = 1;
196ccf10 346 if (--iter &&argc > 0) {
7f02df2f 347 sleep(atoi(argv[0]));
7f02df2f
BJ
348 goto loop;
349 }
350}
351
4b894a2c
KM
352printhdr()
353{
a448353a
SL
354 register int i, j;
355
920a4346 356 printf(" procs memory page ");
a448353a
SL
357 i = (ndrives * 3 - 6) / 2;
358 if (i < 0)
359 i = 0;
360 for (j = 0; j < i; j++)
361 putchar(' ');
362 printf("faults");
363 i = ndrives * 3 - 6 - i;
364 for (j = 0; j < i; j++)
365 putchar(' ');
366 printf(" cpu\n");
920a4346 367 printf(" r b w avm fre re at pi po fr de sr ");
a448353a
SL
368 for (i = 0; i < dk_ndrive; i++)
369 if (dr_select[i])
370 printf("%c%c ", dr_name[i][0], dr_name[i][2]);
371 printf(" in sy cs us sy id\n");
196ccf10 372 lines = 19;
4b894a2c
KM
373}
374
7f02df2f
BJ
375dotimes()
376{
377
a448353a 378 lseek(mf, (long)nl[X_REC].n_value, L_SET);
7f02df2f 379 read(mf, &s.rectime, sizeof s.rectime);
a448353a 380 lseek(mf, (long)nl[X_PGIN].n_value, L_SET);
7f02df2f 381 read(mf, &s.pgintime, sizeof s.pgintime);
a448353a 382 lseek(mf, (long)nl[X_SUM].n_value, L_SET);
7f02df2f
BJ
383 read(mf, &sum, sizeof sum);
384 printf("%d reclaims, %d total time (usec)\n", sum.v_pgrec, s.rectime);
385 printf("average: %d usec / reclaim\n", s.rectime/sum.v_pgrec);
386 printf("\n");
387 printf("%d page ins, %d total time (msec)\n",sum.v_pgin, s.pgintime/10);
388 printf("average: %8.1f msec / page in\n", s.pgintime/(sum.v_pgin*10.0));
389}
7f02df2f 390
70b78b6e
SL
391#if defined(tahoe)
392#include <tahoe/cpu.h>
393#endif
394
7f02df2f
BJ
395dosum()
396{
a448353a 397 struct nchstats nchstats;
7aa7d88f 398 struct xstats xstats;
dfdfb4c8 399 long nchtotal;
7aa7d88f
SL
400#if defined(tahoe)
401 struct keystats keystats;
402#endif
7f02df2f 403
a448353a 404 lseek(mf, (long)nl[X_SUM].n_value, L_SET);
7f02df2f
BJ
405 read(mf, &sum, sizeof sum);
406 printf("%9d swap ins\n", sum.v_swpin);
407 printf("%9d swap outs\n", sum.v_swpout);
408 printf("%9d pages swapped in\n", sum.v_pswpin / CLSIZE);
409 printf("%9d pages swapped out\n", sum.v_pswpout / CLSIZE);
410 printf("%9d total address trans. faults taken\n", sum.v_faults);
411 printf("%9d page ins\n", sum.v_pgin);
412 printf("%9d page outs\n", sum.v_pgout);
513dfff1
BJ
413 printf("%9d pages paged in\n", sum.v_pgpgin);
414 printf("%9d pages paged out\n", sum.v_pgpgout);
415 printf("%9d sequential process pages freed\n", sum.v_seqfree);
e23f616a 416 printf("%9d total reclaims (%d%% fast)\n", sum.v_pgrec,
920a4346 417 pct(sum.v_fastpgrec, sum.v_pgrec));
7f02df2f
BJ
418 printf("%9d reclaims from free list\n", sum.v_pgfrec);
419 printf("%9d intransit blocking page faults\n", sum.v_intrans);
420 printf("%9d zero fill pages created\n", sum.v_nzfod / CLSIZE);
421 printf("%9d zero fill page faults\n", sum.v_zfod / CLSIZE);
422 printf("%9d executable fill pages created\n", sum.v_nexfod / CLSIZE);
423 printf("%9d executable fill page faults\n", sum.v_exfod / CLSIZE);
424 printf("%9d swap text pages found in free list\n", sum.v_xsfrec);
425 printf("%9d inode text pages found in free list\n", sum.v_xifrec);
426 printf("%9d file fill pages created\n", sum.v_nvrfod / CLSIZE);
427 printf("%9d file fill page faults\n", sum.v_vrfod / CLSIZE);
428 printf("%9d pages examined by the clock daemon\n", sum.v_scan);
429 printf("%9d revolutions of the clock hand\n", sum.v_rev);
430 printf("%9d pages freed by the clock daemon\n", sum.v_dfree / CLSIZE);
431 printf("%9d cpu context switches\n", sum.v_swtch);
432 printf("%9d device interrupts\n", sum.v_intr);
4b894a2c 433 printf("%9d software interrupts\n", sum.v_soft);
a448353a 434#ifdef vax
3d61d7ac 435 printf("%9d pseudo-dma dz interrupts\n", sum.v_pdma);
a448353a 436#endif
7f02df2f
BJ
437 printf("%9d traps\n", sum.v_trap);
438 printf("%9d system calls\n", sum.v_syscall);
dfdfb4c8 439 lseek(mf, (long)nl[X_NCHSTATS].n_value, 0);
a448353a 440 read(mf, &nchstats, sizeof nchstats);
3aea8979
KM
441 nchtotal = nchstats.ncs_goodhits + nchstats.ncs_neghits +
442 nchstats.ncs_badhits + nchstats.ncs_falsehits +
443 nchstats.ncs_miss + nchstats.ncs_long;
444 printf("%9d total name lookups\n", nchtotal);
445 printf("%9s cache hits (%d%% pos + %d%% neg) system %d%% per-process\n",
446 "", pct(nchstats.ncs_goodhits, nchtotal),
447 pct(nchstats.ncs_neghits, nchtotal),
920a4346 448 pct(nchstats.ncs_pass2, nchtotal));
3aea8979
KM
449 printf("%9s deletions %d%%, falsehits %d%%, toolong %d%%\n", "",
450 pct(nchstats.ncs_badhits, nchtotal),
451 pct(nchstats.ncs_falsehits, nchtotal),
452 pct(nchstats.ncs_long, nchtotal));
b6b10463
SL
453 lseek(mf, (long)nl[X_XSTATS].n_value, 0);
454 read(mf, &xstats, sizeof xstats);
455 printf("%9d total calls to xalloc (cache hits %d%%)\n",
920a4346 456 xstats.alloc, pct(xstats.alloc_cachehit, xstats.alloc));
b6b10463
SL
457 printf("%9s sticky %d flushed %d unused %d\n", "",
458 xstats.alloc_inuse, xstats.alloc_cacheflush, xstats.alloc_unused);
459 printf("%9d total calls to xfree", xstats.free);
460 printf(" (sticky %d cached %d swapped %d)\n",
461 xstats.free_inuse, xstats.free_cache, xstats.free_cacheswap);
7aa7d88f
SL
462#if defined(tahoe)
463 lseek(mf, (long)nl[X_CKEYSTATS].n_value, 0);
464 read(mf, &keystats, sizeof keystats);
465 printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n",
466 keystats.ks_allocs, "code cache keys allocated",
0c429495 467 pct(keystats.ks_allocfree, keystats.ks_allocs),
920a4346
SL
468 pct(keystats.ks_norefs, keystats.ks_allocs),
469 pct(keystats.ks_taken, keystats.ks_allocs),
470 pct(keystats.ks_shared, keystats.ks_allocs));
7aa7d88f
SL
471 lseek(mf, (long)nl[X_DKEYSTATS].n_value, 0);
472 read(mf, &keystats, sizeof keystats);
473 printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n",
474 keystats.ks_allocs, "data cache keys allocated",
0c429495 475 pct(keystats.ks_allocfree, keystats.ks_allocs),
920a4346
SL
476 pct(keystats.ks_norefs, keystats.ks_allocs),
477 pct(keystats.ks_taken, keystats.ks_allocs),
478 pct(keystats.ks_shared, keystats.ks_allocs));
7aa7d88f 479#endif
7f02df2f
BJ
480}
481
7f02df2f
BJ
482doforkst()
483{
484
a448353a 485 lseek(mf, (long)nl[X_FORKSTAT].n_value, L_SET);
7f02df2f
BJ
486 read(mf, &forkstat, sizeof forkstat);
487 printf("%d forks, %d pages, average=%.2f\n",
488 forkstat.cntfork, forkstat.sizfork,
489 (float) forkstat.sizfork / forkstat.cntfork);
490 printf("%d vforks, %d pages, average=%.2f\n",
491 forkstat.cntvfork, forkstat.sizvfork,
492 (float)forkstat.sizvfork / forkstat.cntvfork);
493}
494
495stats(dn)
496{
497
a448353a 498 if (dn >= dk_ndrive) {
7f02df2f
BJ
499 printf(" 0");
500 return;
501 }
682f1dcb 502 printf("%3.0f", s.xfer[dn]/etime);
7f02df2f
BJ
503}
504
505double
506stat1(row)
507{
682f1dcb
BJ
508 double t;
509 register i;
7f02df2f
BJ
510
511 t = 0;
512 for(i=0; i<CPUSTATES; i++)
682f1dcb
BJ
513 t += s.time[i];
514 if(t == 0.)
515 t = 1.;
516 return(s.time[row]*100./t);
7f02df2f
BJ
517}
518
519pct(top, bot)
520{
521
522 if (bot == 0)
523 return (0);
524 return ((top * 100) / bot);
525}
61d7d2b3 526
4b894a2c
KM
527dointr(nintv)
528{
529 int nintr, inttotal;
530 long *intrcnt;
531 char *intrname, *malloc();
532
533 nintr = (nl[X_EINTRCNT].n_value - nl[X_INTRCNT].n_value) / sizeof(long);
534 intrcnt = (long *) malloc(nl[X_EINTRCNT].n_value -
535 nl[X_INTRCNT].n_value);
536 intrname = malloc(nl[X_EINTRNAMES].n_value - nl[X_INTRNAMES].n_value);
537 if (intrcnt == NULL || intrname == NULL) {
538 fprintf(stderr, "vmstat: out of memory\n");
539 exit(9);
540 }
a448353a 541 lseek(mf, (long)nl[X_INTRCNT].n_value, L_SET);
4b894a2c 542 read(mf, intrcnt, nintr * sizeof (long));
a448353a 543 lseek(mf, (long)nl[X_INTRNAMES].n_value, L_SET);
4b894a2c
KM
544 read(mf, intrname, nl[X_EINTRNAMES].n_value - nl[X_INTRNAMES].n_value);
545 printf("interrupt total rate\n");
546 inttotal = 0;
547 while (nintr--) {
548 if (*intrcnt)
549 printf("%-12s %8ld %8ld\n", intrname,
550 *intrcnt, *intrcnt / nintv);
551 intrname += strlen(intrname) + 1;
552 inttotal += *intrcnt++;
553 }
554 printf("Total %8ld %8ld\n", inttotal, inttotal / nintv);
555}
556
0c429495
KM
557/*
558 * These names must be kept in sync with
559 * the types defined in <sys/malloc.h>.
560 */
561char *kmemnames[] = {
e268bd95
MT
562 "free", /* 0 M_FREE */
563 "mbuf", /* 1 M_MBUF */
564 "devbuf", /* 2 M_DEVBUF */
565 "socket", /* 3 M_SOCKET */
566 "pcb", /* 4 M_PCB */
567 "routetbl", /* 5 M_RTABLE */
568 "hosttbl", /* 6 M_HTABLE */
569 "fragtbl", /* 7 M_FTABLE */
570 "zombie", /* 8 M_ZOMBIE */
571 "ifaddr", /* 9 M_IFADDR */
572 "soopts", /* 10 M_SOOPTS */
573 "soname", /* 11 M_SONAME */
574 "namei", /* 12 M_NAMEI */
575 "gprof", /* 13 M_GPROF */
576 "ioctlops", /* 14 M_IOCTLOPS */
577 "superblk", /* 15 M_SUPERBLK */
578 "cred", /* 16 M_CRED */
579 "pgrp", /* 17 M_PGRP */
580 "session", /* 18 M_SESSION */
d8a6e15a 581 "iov", /* 19 M_IOV */
b567dcea
KM
582 "mount", /* 20 M_MOUNT */
583 "fhandle", /* 21 M_FHANDLE */
584 "NFS req", /* 22 M_NFSREQ */
585 "NFS mount", /* 23 M_NFSMNT */
9f8ba8ea
KM
586 "vnodes", /* 24 M_VNODE */
587 "namecache", /* 25 M_CACHE */
fa230d07
KM
588 "UFS quota", /* 26 M_DQUOT */
589 "UFS mount", /* 27 M_UFSMNT */
590 0,
e268bd95
MT
591 0, 0, 0, 0, 0,
592 0, 0, 0, 0, 0,
593 0, 0, 0, 0, 0,
594 0, 0, 0, 0, 0,
e268bd95 595 "temp", /* 49 M_TEMP */
0c429495
KM
596};
597
598domem()
599{
600 struct kmemstats kmemstats[M_LAST];
601 struct kmembuckets buckets[MINBUCKET + 16];
602 register struct kmembuckets *kp;
603 register struct kmemstats *ks;
604 int i;
605
606 lseek(mf, (long)nl[X_KMEMBUCKETS].n_value, L_SET);
607 read(mf, buckets, sizeof buckets);
608 printf("Memory statistics by bucket size\n");
609 printf(" Size In Use Free Requests HighWater Couldfree\n");
610 for (i = MINBUCKET, kp = &buckets[i]; i < MINBUCKET + 16; i++, kp++) {
611 if (kp->kb_calls == 0)
612 continue;
613 printf("%8d%9d%7d%11d%8d%11d\n", 1 << i,
614 kp->kb_total - kp->kb_totalfree,
615 kp->kb_totalfree, kp->kb_calls,
616 kp->kb_highwat, kp->kb_couldfree);
617
618 }
619 lseek(mf, (long)nl[X_KMEMSTAT].n_value, L_SET);
620 read(mf, kmemstats, sizeof kmemstats);
621 printf("Memory statistics by type\n");
622 printf(" Type In Use MemUse HighUse Limit Requests %s\n",
623 "TypeLimit KernLimit");
624 for (i = 0, ks = &kmemstats[0]; i < M_LAST; i++, ks++) {
625 if (ks->ks_calls == 0)
626 continue;
627 printf("%10s%7d%8dK%9dK%6dK%9d%7d%10d\n",
628 kmemnames[i] ? kmemnames[i] : "undefined",
629 ks->ks_inuse, (ks->ks_memuse + 1023) / 1024,
630 (ks->ks_maxused + 1023) / 1024,
631 (ks->ks_limit + 1023) / 1024, ks->ks_calls,
632 ks->ks_limblocks, ks->ks_mapblocks);
633 }
634}
635
a448353a
SL
636#define steal(where, var) \
637 lseek(mf, where, L_SET); read(mf, &var, sizeof var);
61d7d2b3
MT
638/*
639 * Read the drive names out of kmem.
61d7d2b3 640 */
338c4a5d 641#ifdef vax
a448353a
SL
642#include <vaxuba/ubavar.h>
643#include <vaxmba/mbavar.h>
644
61d7d2b3
MT
645read_names()
646{
647 struct mba_device mdev;
648 register struct mba_device *mp;
649 struct mba_driver mdrv;
650 short two_char;
651 char *cp = (char *) &two_char;
652 struct uba_device udev, *up;
653 struct uba_driver udrv;
654
655 mp = (struct mba_device *) nl[X_MBDINIT].n_value;
656 up = (struct uba_device *) nl[X_UBDINIT].n_value;
93ca0bfe 657 if (up == 0) {
338c4a5d 658 fprintf(stderr, "vmstat: Disk init info not in namelist\n");
61d7d2b3
MT
659 exit(1);
660 }
93ca0bfe 661 if (mp) for (;;) {
61d7d2b3
MT
662 steal(mp++, mdev);
663 if (mdev.mi_driver == 0)
664 break;
665 if (mdev.mi_dk < 0 || mdev.mi_alive == 0)
666 continue;
667 steal(mdev.mi_driver, mdrv);
668 steal(mdrv.md_dname, two_char);
a448353a
SL
669 sprintf(dr_name[mdev.mi_dk], "%c%c%d",
670 cp[0], cp[1], mdev.mi_unit);
61d7d2b3 671 }
93ca0bfe 672 for (;;) {
61d7d2b3
MT
673 steal(up++, udev);
674 if (udev.ui_driver == 0)
675 break;
676 if (udev.ui_dk < 0 || udev.ui_alive == 0)
677 continue;
678 steal(udev.ui_driver, udrv);
679 steal(udrv.ud_dname, two_char);
a448353a
SL
680 sprintf(dr_name[udev.ui_dk], "%c%c%d",
681 cp[0], cp[1], udev.ui_unit);
61d7d2b3
MT
682 }
683}
338c4a5d 684#endif
242684ee 685
242684ee
SL
686#ifdef tahoe
687#include <tahoevba/vbavar.h>
688
689/*
690 * Read the drive names out of kmem.
691 */
692read_names()
693{
694 struct vba_device udev, *up;
695 struct vba_driver udrv;
696 short two_char;
697 char *cp = (char *)&two_char;
698
699 up = (struct vba_device *) nl[X_VBDINIT].n_value;
700 if (up == 0) {
701 fprintf(stderr, "vmstat: Disk init info not in namelist\n");
702 exit(1);
703 }
704 for (;;) {
705 steal(up++, udev);
706 if (udev.ui_driver == 0)
707 break;
708 if (udev.ui_dk < 0 || udev.ui_alive == 0)
709 continue;
710 steal(udev.ui_driver, udrv);
711 steal(udrv.ud_dname, two_char);
712 sprintf(dr_name[udev.ui_dk], "%c%c%d",
713 cp[0], cp[1], udev.ui_unit);
714 }
715}
716#endif