clean up option formatting
[unix-history] / usr / src / usr.bin / vmstat / vmstat.c
CommitLineData
f42904bc 1/*
dd6bac83 2 * Copyright (c) 1980, 1986, 1991 The Regents of the University of California.
01c8685d
KB
3 * All rights reserved.
4 *
32ce521f 5 * %sccs.include.redist.c%
f42904bc
DF
6 */
7
8#ifndef lint
9char copyright[] =
dd6bac83 10"@(#) Copyright (c) 1980, 1986, 1991 The Regents of the University of California.\n\
f42904bc 11 All rights reserved.\n";
01c8685d 12#endif /* not lint */
f42904bc 13
338c4a5d 14#ifndef lint
ecc9fa0b 15static char sccsid[] = "@(#)vmstat.c 5.29 (Berkeley) %G%";
01c8685d 16#endif /* not lint */
338c4a5d 17
7f02df2f 18#include <sys/param.h>
6f7a6346
MK
19#include <sys/time.h>
20#include <sys/proc.h>
5ff3748f 21#include <sys/user.h>
920a4346 22#include <sys/dkstat.h>
61d7d2b3 23#include <sys/buf.h>
4b894a2c 24#include <sys/namei.h>
0c429495 25#include <sys/malloc.h>
6f7a6346
MK
26#include <sys/signal.h>
27#include <sys/fcntl.h>
28#include <sys/ioctl.h>
dd6bac83 29#include <time.h>
f5506e0f 30#include <nlist.h>
dd6bac83
KB
31#include <kvm.h>
32#include <errno.h>
33#include <unistd.h>
0ef721f3 34#include <stdio.h>
dd6bac83 35#include <ctype.h>
0ef721f3
KB
36#include <stdlib.h>
37#include <string.h>
f5506e0f 38#include <paths.h>
7f02df2f 39
6f7a6346
MK
40#ifdef SPPWAIT
41#define NEWVM
42#endif
ecc9fa0b
MK
43#ifdef NEWVM
44#include <sys/vmmeter.h>
45#include <vm/vm.h>
46#include <vm/vm_statistics.h>
47#else
6f7a6346
MK
48#include <sys/vm.h>
49#include <sys/text.h>
6f7a6346
MK
50#endif
51
7f02df2f 52struct nlist nl[] = {
682f1dcb
BJ
53#define X_CPTIME 0
54 { "_cp_time" },
ecc9fa0b 55#define X_TOTAL 1
7f02df2f 56 { "_total" },
ecc9fa0b
MK
57#define X_SUM 2
58#define SUM "_cnt" /* XXX for now that's where it is */
59 { SUM },
60#define X_BOOTTIME 3
a43be079 61 { "_boottime" },
ecc9fa0b 62#define X_DKXFER 4
682f1dcb 63 { "_dk_xfer" },
ecc9fa0b 64#define X_HZ 5
61d7d2b3 65 { "_hz" },
ecc9fa0b 66#define X_PHZ 6
b3a37270 67 { "_phz" },
ecc9fa0b 68#define X_NCHSTATS 7
dfdfb4c8 69 { "_nchstats" },
ecc9fa0b 70#define X_INTRNAMES 8
4b894a2c 71 { "_intrnames" },
ecc9fa0b 72#define X_EINTRNAMES 9
4b894a2c 73 { "_eintrnames" },
ecc9fa0b 74#define X_INTRCNT 10
4b894a2c 75 { "_intrcnt" },
ecc9fa0b 76#define X_EINTRCNT 11
4b894a2c 77 { "_eintrcnt" },
ecc9fa0b 78#define X_DK_NDRIVE 12
a448353a 79 { "_dk_ndrive" },
ecc9fa0b 80#define X_KMEMSTAT 13
0c429495 81 { "_kmemstats" },
ecc9fa0b 82#define X_KMEMBUCKETS 14
0c429495 83 { "_bucket" },
6f7a6346 84#ifdef NEWVM
ecc9fa0b
MK
85#define X_VMSTAT 15
86 { "_vm_stat" },
6f7a6346
MK
87#define X_END 15
88#else
ecc9fa0b 89#define X_DEFICIT 15
6f7a6346 90 { "_deficit" },
ecc9fa0b 91#define X_FORKSTAT 16
6f7a6346 92 { "_forkstat" },
ecc9fa0b 93#define X_REC 17
6f7a6346 94 { "_rectime" },
ecc9fa0b 95#define X_PGIN 18
6f7a6346 96 { "_pgintime" },
ecc9fa0b 97#define X_XSTATS 19
6f7a6346 98 { "_xstats" },
ecc9fa0b 99#define X_END 19
6f7a6346 100#endif
dd6bac83
KB
101#ifdef hp300
102#define X_HPDINIT (X_END+1)
103 { "_hp_dinit" },
242684ee 104#endif
242684ee 105#ifdef tahoe
468dd322 106#define X_VBDINIT (X_END+1)
242684ee 107 { "_vbdinit" },
468dd322 108#define X_CKEYSTATS (X_END+2)
7aa7d88f 109 { "_ckeystats" },
468dd322 110#define X_DKEYSTATS (X_END+3)
7aa7d88f 111 { "_dkeystats" },
468dd322 112#endif
dd6bac83
KB
113#ifdef vax
114#define X_MBDINIT (X_END+1)
115 { "_mbdinit" },
116#define X_UBDINIT (X_END+2)
117 { "_ubdinit" },
338c4a5d
SL
118#endif
119 { "" },
7f02df2f
BJ
120};
121
dd6bac83
KB
122struct _disk {
123 long time[CPUSTATES];
124 long *xfer;
125} cur, last;
7f02df2f 126
ecc9fa0b
MK
127#ifdef NEWVM
128struct vm_statistics vm_stat, ostat;
129#endif
130struct vmmeter sum, osum;
6f7a6346
MK
131char *vmunix = _PATH_UNIX;
132char **dr_name;
133int *dr_select, dk_ndrive, ndrives;
134
135int winlines = 20;
920a4346 136
0ef721f3
KB
137#define FORKSTAT 0x01
138#define INTRSTAT 0x02
139#define MEMSTAT 0x04
140#define SUMSTAT 0x08
141#define TIMESTAT 0x10
142#define VMSTAT 0x20
143#define ZEROOUT 0x40
144
dd6bac83
KB
145#include "names.c" /* disk names -- machine dependent */
146
6f7a6346
MK
147void cpustats(), dkstats(), dointr(), domem(), dosum();
148void dovmstat(), kread(), usage(), zero();
149#ifndef NEWVM
150void dotimes(), doforkst();
151#endif
dd6bac83 152
7f02df2f 153main(argc, argv)
0ef721f3
KB
154 register int argc;
155 register char **argv;
7f02df2f 156{
0ef721f3
KB
157 extern int optind;
158 extern char *optarg;
dd6bac83
KB
159 register int c, todo;
160 u_int interval;
161 int reps;
162 char *kmem;
163
164 kmem = NULL;
165 interval = reps = todo = 0;
166 while ((c = getopt(argc, argv, "c:fiM:mN:stw:z")) != EOF) {
0ef721f3 167 switch (c) {
dd6bac83
KB
168 case 'c':
169 reps = atoi(optarg);
170 break;
6f7a6346 171#ifndef NEWVM
7f02df2f 172 case 'f':
0ef721f3
KB
173 todo |= FORKSTAT;
174 break;
6f7a6346 175#endif
0ef721f3
KB
176 case 'i':
177 todo |= INTRSTAT;
178 break;
dd6bac83 179 case 'M':
0ef721f3
KB
180 kmem = optarg;
181 break;
0c429495 182 case 'm':
0ef721f3
KB
183 todo |= MEMSTAT;
184 break;
dd6bac83
KB
185 case 'N':
186 vmunix = optarg;
187 break;
7f02df2f 188 case 's':
0ef721f3 189 todo |= SUMSTAT;
4b894a2c 190 break;
6f7a6346 191#ifndef NEWVM
0ef721f3
KB
192 case 't':
193 todo |= TIMESTAT;
194 break;
6f7a6346 195#endif
dd6bac83
KB
196 case 'w':
197 interval = atoi(optarg);
0ef721f3
KB
198 break;
199 case 'z':
200 todo |= ZEROOUT;
201 break;
202 case '?':
7f02df2f 203 default:
dd6bac83 204 usage();
7f02df2f
BJ
205 }
206 }
dd6bac83
KB
207 argc -= optind;
208 argv += optind;
0ef721f3 209
0ef721f3
KB
210 if (todo & ZEROOUT) {
211 if (todo & ~ZEROOUT || kmem)
212 usage();
dd6bac83 213 zero();
0ef721f3 214 exit(0);
a448353a 215 }
0ef721f3
KB
216
217 if (todo == 0)
218 todo = VMSTAT;
219
dd6bac83
KB
220 if (kvm_openfiles(vmunix, kmem, NULL) < 0) {
221 (void)fprintf(stderr,
222 "vmstat: kvm_openfiles: %s\n", kvm_geterr());
a448353a
SL
223 exit(1);
224 }
0ef721f3 225
6f7a6346
MK
226 if ((c = kvm_nlist(nl)) != 0) {
227 if (c > 0) {
228 (void)fprintf(stderr,
229 "vmstat: undefined symbols in %s:", vmunix);
230 for (c = 0; c < sizeof(nl)/sizeof(nl[0]); c++)
231 if (nl[c].n_type == 0)
232 printf(" %s", nl[c].n_name);
233 (void)fputc('\n', stderr);
234 } else
235 (void)fprintf(stderr, "vmstat: kvm_nlist: %s\n",
236 kvm_geterr());
a448353a
SL
237 exit(1);
238 }
0ef721f3 239
dd6bac83
KB
240 if (todo & VMSTAT) {
241 char **getdrivedata();
6f7a6346 242 struct winsize winsize;
dd6bac83
KB
243
244 argv = getdrivedata(argv);
6f7a6346
MK
245 winsize.ws_row = 0;
246 (void) ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&winsize);
247 if (winsize.ws_row > 0)
248 winlines = winsize.ws_row;
249
dd6bac83
KB
250 }
251
252#define BACKWARD_COMPATIBILITY
253#ifdef BACKWARD_COMPATIBILITY
254 if (*argv) {
255 interval = atoi(*argv);
256 if (*++argv)
257 reps = atoi(*argv);
258 }
259#endif
260
5a168b67
KB
261 if (interval) {
262 if (!reps)
263 reps = -1;
264 } else
265 if (reps)
266 interval = 1;
267
6f7a6346 268#ifndef NEWVM
0ef721f3
KB
269 if (todo & FORKSTAT)
270 doforkst();
6f7a6346 271#endif
0ef721f3
KB
272 if (todo & MEMSTAT)
273 domem();
274 if (todo & SUMSTAT)
275 dosum();
6f7a6346 276#ifndef NEWVM
0ef721f3
KB
277 if (todo & TIMESTAT)
278 dotimes();
6f7a6346 279#endif
0ef721f3
KB
280 if (todo & INTRSTAT)
281 dointr();
dd6bac83
KB
282 if (todo & VMSTAT)
283 dovmstat(interval, reps);
0ef721f3
KB
284 exit(0);
285}
286
dd6bac83
KB
287char **
288getdrivedata(argv)
0ef721f3
KB
289 char **argv;
290{
291 register int i;
292 register char **cp;
0ef721f3
KB
293 char buf[30];
294
dd6bac83 295 kread(X_DK_NDRIVE, &dk_ndrive, sizeof(dk_ndrive));
0ef721f3 296 if (dk_ndrive <= 0) {
dd6bac83 297 (void)fprintf(stderr, "vmstat: dk_ndrive %d\n", dk_ndrive);
0ef721f3 298 exit(1);
4b894a2c 299 }
dd6bac83
KB
300 dr_select = calloc((size_t)dk_ndrive, sizeof(int));
301 dr_name = calloc((size_t)dk_ndrive, sizeof(char *));
0ef721f3
KB
302 for (i = 0; i < dk_ndrive; i++)
303 dr_name[i] = NULL;
dd6bac83
KB
304 cur.xfer = calloc((size_t)dk_ndrive, sizeof(long));
305 last.xfer = calloc((size_t)dk_ndrive, sizeof(long));
0ef721f3 306 read_names();
dd6bac83 307 for (i = 0; i < dk_ndrive; i++)
0ef721f3 308 if (dr_name[i] == NULL) {
dd6bac83 309 (void)sprintf(buf, "??%d", i);
0ef721f3
KB
310 dr_name[i] = strdup(buf);
311 }
0ef721f3 312
a448353a 313 /*
dd6bac83
KB
314 * Choose drives to be displayed. Priority goes to (in order) drives
315 * supplied as arguments, default drives. If everything isn't filled
316 * in and there are drives not taken care of, display the first few
317 * that fit.
a448353a 318 */
dd6bac83
KB
319#define BACKWARD_COMPATIBILITY
320 for (ndrives = 0; *argv; ++argv) {
321#ifdef BACKWARD_COMPATIBILITY
322 if (isdigit(**argv))
323 break;
324#endif
a448353a 325 for (i = 0; i < dk_ndrive; i++) {
dd6bac83 326 if (strcmp(dr_name[i], *argv))
a448353a
SL
327 continue;
328 dr_select[i] = 1;
dd6bac83 329 ++ndrives;
0ef721f3 330 break;
a448353a 331 }
a448353a
SL
332 }
333 for (i = 0; i < dk_ndrive && ndrives < 4; i++) {
334 if (dr_select[i])
335 continue;
336 for (cp = defdrives; *cp; cp++)
337 if (strcmp(dr_name[i], *cp) == 0) {
338 dr_select[i] = 1;
dd6bac83 339 ++ndrives;
a448353a
SL
340 break;
341 }
342 }
343 for (i = 0; i < dk_ndrive && ndrives < 4; i++) {
344 if (dr_select[i])
345 continue;
346 dr_select[i] = 1;
dd6bac83 347 ++ndrives;
a448353a 348 }
dd6bac83 349 return(argv);
0ef721f3
KB
350}
351
352long
353getuptime()
354{
dd6bac83
KB
355 static time_t now, boottime;
356 time_t uptime;
0ef721f3
KB
357
358 if (boottime == 0)
dd6bac83
KB
359 kread(X_BOOTTIME, &boottime, sizeof(boottime));
360 (void)time(&now);
0ef721f3
KB
361 uptime = now - boottime;
362 if (uptime <= 0 || uptime > 60*60*24*365*10) {
dd6bac83 363 (void)fprintf(stderr,
0ef721f3
KB
364 "vmstat: time makes no sense; namelist must be wrong.\n");
365 exit(1);
366 }
dd6bac83 367 return(uptime);
0ef721f3
KB
368}
369
ecc9fa0b 370int hz, hdrcnt;
5a168b67 371
dd6bac83
KB
372void
373dovmstat(interval, reps)
374 u_int interval;
375 int reps;
0ef721f3 376{
dd6bac83 377 struct vmtotal total;
dd6bac83 378 time_t uptime;
6f7a6346 379 void needhdr();
ecc9fa0b
MK
380#ifndef NEWVM
381 int deficit;
382#endif
dd6bac83
KB
383
384 uptime = getuptime();
6f7a6346 385 (void)signal(SIGCONT, needhdr);
dd6bac83 386
dd6bac83 387 if (nl[X_PHZ].n_type != 0 && nl[X_PHZ].n_value != 0)
5a168b67
KB
388 kread(X_PHZ, &hz, sizeof(hz));
389 if (!hz)
390 kread(X_HZ, &hz, sizeof(hz));
dd6bac83
KB
391
392 for (hdrcnt = 1;;) {
6f7a6346 393 if (!--hdrcnt)
dd6bac83 394 printhdr();
dd6bac83
KB
395 kread(X_CPTIME, cur.time, sizeof(cur.time));
396 kread(X_DKXFER, cur.xfer, sizeof(*cur.xfer * dk_ndrive));
dd6bac83 397 kread(X_SUM, &sum, sizeof(sum));
ecc9fa0b
MK
398 kread(X_TOTAL, &total, sizeof(total));
399#ifdef NEWVM
400 kread(X_VMSTAT, &vm_stat, sizeof(vm_stat));
401#else
dd6bac83 402 kread(X_DEFICIT, &deficit, sizeof(deficit));
6f7a6346 403#endif
ecc9fa0b 404 (void)printf("%2d %1d %1d ",
dd6bac83 405 total.t_rq, total.t_dw + total.t_pw, total.t_sw);
0ef721f3 406#define pgtok(a) ((a)*NBPG >> 10)
ecc9fa0b 407 (void)printf("%5ld %5ld ",
dd6bac83 408 pgtok(total.t_avm), pgtok(total.t_free));
ecc9fa0b
MK
409#ifdef NEWVM
410 (void)printf("%4lu ",
411 (vm_stat.faults - ostat.faults) / uptime);
412 (void)printf("%3lu ",
413 (vm_stat.reactivations - ostat.reactivations) / uptime);
414 (void)printf("%3lu ",
415 (vm_stat.pageins - ostat.pageins) / uptime);
416 (void)printf("%3lu %3lu ",
417 (vm_stat.pageouts - ostat.pageouts) / uptime, 0);
418#else
419 (void)printf("%3lu %2lu ",
420 (sum.v_pgrec - (sum.v_xsfrec+sum.v_xifrec) -
421 (osum.v_pgrec - (osum.v_xsfrec+osum.v_xifrec))) / uptime,
422 (sum.v_xsfrec + sum.v_xifrec -
423 osum.v_xsfrec - osum.v_xifrec) / uptime);
424 (void)printf("%3lu ",
425 pgtok(sum.v_pgpgin - osum.v_pgpgin) / uptime);
426 (void)printf("%3lu %3lu ",
427 pgtok(sum.v_pgpgout - osum.v_pgpgout) / uptime,
428 pgtok(sum.v_dfree - osum.v_dfree) / uptime);
429 (void)printf("%3d ", pgtok(deficit));
430#endif
431 (void)printf("%3lu ", (sum.v_scan - osum.v_scan) / uptime);
5a168b67 432 dkstats();
ecc9fa0b
MK
433 (void)printf("%4lu %4lu %3lu ",
434 (sum.v_intr - osum.v_intr) / uptime,
435 (sum.v_syscall - osum.v_syscall) / uptime,
436 (sum.v_swtch - osum.v_swtch ) / uptime);
5a168b67 437 cpustats();
dd6bac83
KB
438 (void)printf("\n");
439 (void)fflush(stdout);
440 uptime = 1;
5a168b67 441 if (reps >= 0 && --reps <= 0)
dd6bac83 442 break;
ecc9fa0b
MK
443 osum = sum;
444 ostat = vm_stat;
5a168b67 445 (void)sleep(interval);
7f02df2f
BJ
446 }
447}
448
4b894a2c
KM
449printhdr()
450{
dd6bac83
KB
451 register int i;
452
ecc9fa0b 453 (void)printf(" procs memory page%*s", 20, "");
dd6bac83 454 if (ndrives > 1)
ecc9fa0b 455 (void)printf("disks %*s faults cpu\n",
dd6bac83
KB
456 ndrives * 3 - 6, "");
457 else
ecc9fa0b
MK
458 (void)printf("%*s faults cpu\n", ndrives * 3, "");
459#ifndef NEWVM
dd6bac83 460 (void)printf(" r b w avm fre re at pi po fr de sr ");
ecc9fa0b
MK
461#else
462 (void)printf(" r b w avm fre flt re pi po fr sr ");
463#endif
a448353a
SL
464 for (i = 0; i < dk_ndrive; i++)
465 if (dr_select[i])
dd6bac83 466 (void)printf("%c%c ", dr_name[i][0],
0ef721f3 467 dr_name[i][strlen(dr_name[i]) - 1]);
ecc9fa0b 468 (void)printf(" in sy cs us sy id\n");
6f7a6346 469 hdrcnt = winlines - 2;
4b894a2c
KM
470}
471
6f7a6346
MK
472/*
473 * Force a header to be prepended to the next output.
474 */
475void
476needhdr()
477{
478
479 hdrcnt = 1;
480}
481
482#ifndef NEWVM
dd6bac83 483void
7f02df2f
BJ
484dotimes()
485{
dd6bac83
KB
486 u_int pgintime, rectime;
487
488 kread(X_REC, &rectime, sizeof(rectime));
489 kread(X_PGIN, &pgintime, sizeof(pgintime));
490 kread(X_SUM, &sum, sizeof(sum));
491 (void)printf("%u reclaims, %u total time (usec)\n",
492 sum.v_pgrec, rectime);
493 (void)printf("average: %u usec / reclaim\n", rectime / sum.v_pgrec);
494 (void)printf("\n");
495 (void)printf("%u page ins, %u total time (msec)\n",
496 sum.v_pgin, pgintime / 10);
497 (void)printf("average: %8.1f msec / page in\n",
498 pgintime / (sum.v_pgin * 10.0));
0ef721f3 499}
6f7a6346 500#endif
0ef721f3
KB
501
502pct(top, bot)
503 long top, bot;
504{
0ef721f3 505 if (bot == 0)
dd6bac83
KB
506 return(0);
507 return((top * 100) / bot);
7f02df2f 508}
7f02df2f 509
0ef721f3
KB
510#define PCT(top, bot) pct((long)(top), (long)(bot))
511
70b78b6e 512#if defined(tahoe)
0ef721f3 513#include <machine/cpu.h>
70b78b6e
SL
514#endif
515
dd6bac83 516void
7f02df2f
BJ
517dosum()
518{
a448353a 519 struct nchstats nchstats;
6f7a6346 520#ifndef NEWVM
7aa7d88f 521 struct xstats xstats;
6f7a6346 522#endif
dfdfb4c8 523 long nchtotal;
7aa7d88f
SL
524#if defined(tahoe)
525 struct keystats keystats;
526#endif
7f02df2f 527
dd6bac83 528 kread(X_SUM, &sum, sizeof(sum));
ecc9fa0b
MK
529#ifdef NEWVM
530 kread(X_VMSTAT, &vm_stat, sizeof(vm_stat));
531#else
dd6bac83
KB
532 (void)printf("%9u swap ins\n", sum.v_swpin);
533 (void)printf("%9u swap outs\n", sum.v_swpout);
534 (void)printf("%9u pages swapped in\n", sum.v_pswpin / CLSIZE);
535 (void)printf("%9u pages swapped out\n", sum.v_pswpout / CLSIZE);
536 (void)printf("%9u total address trans. faults taken\n", sum.v_faults);
537 (void)printf("%9u page ins\n", sum.v_pgin);
538 (void)printf("%9u page outs\n", sum.v_pgout);
539 (void)printf("%9u pages paged in\n", sum.v_pgpgin);
540 (void)printf("%9u pages paged out\n", sum.v_pgpgout);
541 (void)printf("%9u sequential process pages freed\n", sum.v_seqfree);
542 (void)printf("%9u total reclaims (%d%% fast)\n", sum.v_pgrec,
0ef721f3 543 PCT(sum.v_fastpgrec, sum.v_pgrec));
dd6bac83
KB
544 (void)printf("%9u reclaims from free list\n", sum.v_pgfrec);
545 (void)printf("%9u intransit blocking page faults\n", sum.v_intrans);
546 (void)printf("%9u zero fill pages created\n", sum.v_nzfod / CLSIZE);
547 (void)printf("%9u zero fill page faults\n", sum.v_zfod / CLSIZE);
548 (void)printf("%9u executable fill pages created\n",
0ef721f3 549 sum.v_nexfod / CLSIZE);
dd6bac83 550 (void)printf("%9u executable fill page faults\n",
0ef721f3 551 sum.v_exfod / CLSIZE);
dd6bac83 552 (void)printf("%9u swap text pages found in free list\n",
0ef721f3 553 sum.v_xsfrec);
dd6bac83 554 (void)printf("%9u inode text pages found in free list\n",
0ef721f3 555 sum.v_xifrec);
dd6bac83
KB
556 (void)printf("%9u file fill pages created\n", sum.v_nvrfod / CLSIZE);
557 (void)printf("%9u file fill page faults\n", sum.v_vrfod / CLSIZE);
558 (void)printf("%9u pages examined by the clock daemon\n", sum.v_scan);
559 (void)printf("%9u revolutions of the clock hand\n", sum.v_rev);
560 (void)printf("%9u pages freed by the clock daemon\n",
0ef721f3 561 sum.v_dfree / CLSIZE);
ecc9fa0b 562#endif
dd6bac83
KB
563 (void)printf("%9u cpu context switches\n", sum.v_swtch);
564 (void)printf("%9u device interrupts\n", sum.v_intr);
565 (void)printf("%9u software interrupts\n", sum.v_soft);
a448353a 566#ifdef vax
dd6bac83 567 (void)printf("%9u pseudo-dma dz interrupts\n", sum.v_pdma);
a448353a 568#endif
dd6bac83
KB
569 (void)printf("%9u traps\n", sum.v_trap);
570 (void)printf("%9u system calls\n", sum.v_syscall);
ecc9fa0b
MK
571#ifdef NEWVM
572 (void)printf("%9u bytes per page\n", vm_stat.pagesize);
573 (void)printf("%9u pages free\n", vm_stat.free_count);
574 (void)printf("%9u pages active\n", vm_stat.active_count);
575 (void)printf("%9u pages inactive\n", vm_stat.inactive_count);
576 (void)printf("%9u pages wired down\n", vm_stat.wire_count);
577 (void)printf("%9u zero-fill pages\n", vm_stat.zero_fill_count);
578 (void)printf("%9u pages reactivated\n", vm_stat.reactivations);
579 (void)printf("%9u pageins\n", vm_stat.pageins);
580 (void)printf("%9u pageouts\n", vm_stat.pageouts);
581 (void)printf("%9u VM faults\n", vm_stat.faults);
582 (void)printf("%9u copy-on-write faults\n", vm_stat.cow_faults);
583 (void)printf("%9u VM object cache lookups\n", vm_stat.lookups);
584 (void)printf("%9u VM object hits\n", vm_stat.hits);
585#endif
586
dd6bac83 587 kread(X_NCHSTATS, &nchstats, sizeof(nchstats));
3aea8979
KM
588 nchtotal = nchstats.ncs_goodhits + nchstats.ncs_neghits +
589 nchstats.ncs_badhits + nchstats.ncs_falsehits +
590 nchstats.ncs_miss + nchstats.ncs_long;
dd6bac83
KB
591 (void)printf("%9ld total name lookups\n", nchtotal);
592 (void)printf(
0ef721f3
KB
593 "%9s cache hits (%d%% pos + %d%% neg) system %d%% per-process\n",
594 "", PCT(nchstats.ncs_goodhits, nchtotal),
595 PCT(nchstats.ncs_neghits, nchtotal),
596 PCT(nchstats.ncs_pass2, nchtotal));
dd6bac83 597 (void)printf("%9s deletions %d%%, falsehits %d%%, toolong %d%%\n", "",
0ef721f3
KB
598 PCT(nchstats.ncs_badhits, nchtotal),
599 PCT(nchstats.ncs_falsehits, nchtotal),
600 PCT(nchstats.ncs_long, nchtotal));
6f7a6346 601#ifndef NEWVM
dd6bac83
KB
602 kread(X_XSTATS, &xstats, sizeof(xstats));
603 (void)printf("%9lu total calls to xalloc (cache hits %d%%)\n",
0ef721f3 604 xstats.alloc, PCT(xstats.alloc_cachehit, xstats.alloc));
dd6bac83 605 (void)printf("%9s sticky %lu flushed %lu unused %lu\n", "",
b6b10463 606 xstats.alloc_inuse, xstats.alloc_cacheflush, xstats.alloc_unused);
dd6bac83
KB
607 (void)printf("%9lu total calls to xfree", xstats.free);
608 (void)printf(" (sticky %lu cached %lu swapped %lu)\n",
b6b10463 609 xstats.free_inuse, xstats.free_cache, xstats.free_cacheswap);
6f7a6346 610#endif
7aa7d88f 611#if defined(tahoe)
dd6bac83
KB
612 kread(X_CKEYSTATS, &keystats, sizeof(keystats));
613 (void)printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n",
7aa7d88f 614 keystats.ks_allocs, "code cache keys allocated",
0ef721f3
KB
615 PCT(keystats.ks_allocfree, keystats.ks_allocs),
616 PCT(keystats.ks_norefs, keystats.ks_allocs),
617 PCT(keystats.ks_taken, keystats.ks_allocs),
618 PCT(keystats.ks_shared, keystats.ks_allocs));
dd6bac83
KB
619 kread(X_DKEYSTATS, &keystats, sizeof(keystats));
620 (void)printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n",
7aa7d88f 621 keystats.ks_allocs, "data cache keys allocated",
0ef721f3
KB
622 PCT(keystats.ks_allocfree, keystats.ks_allocs),
623 PCT(keystats.ks_norefs, keystats.ks_allocs),
624 PCT(keystats.ks_taken, keystats.ks_allocs),
625 PCT(keystats.ks_shared, keystats.ks_allocs));
7aa7d88f 626#endif
7f02df2f
BJ
627}
628
6f7a6346 629#ifndef NEWVM
dd6bac83 630void
7f02df2f
BJ
631doforkst()
632{
dd6bac83 633 struct forkstat fks;
7f02df2f 634
dd6bac83
KB
635 kread(X_FORKSTAT, &fks, sizeof(struct forkstat));
636 (void)printf("%d forks, %d pages, average %.2f\n",
637 fks.cntfork, fks.sizfork, (double)fks.sizfork / fks.cntfork);
638 (void)printf("%d vforks, %d pages, average %.2f\n",
639 fks.cntvfork, fks.sizvfork, (double)fks.sizvfork / fks.cntvfork);
7f02df2f 640}
6f7a6346 641#endif
7f02df2f 642
dd6bac83 643void
5a168b67 644dkstats()
7f02df2f 645{
5a168b67
KB
646 register int dn, state;
647 double etime;
648 long tmp;
649
650 for (dn = 0; dn < dk_ndrive; ++dn) {
651 tmp = cur.xfer[dn];
652 cur.xfer[dn] -= last.xfer[dn];
653 last.xfer[dn] = tmp;
654 }
655 etime = 0;
656 for (state = 0; state < CPUSTATES; ++state) {
657 tmp = cur.time[state];
658 cur.time[state] -= last.time[state];
659 last.time[state] = tmp;
660 etime += cur.time[state];
661 }
662 if (etime == 0)
663 etime = 1;
664 etime /= hz;
665 for (dn = 0; dn < dk_ndrive; ++dn) {
666 if (!dr_select[dn])
667 continue;
ecc9fa0b 668 (void)printf("%2.0f ", cur.xfer[dn] / etime);
5a168b67 669 }
7f02df2f
BJ
670}
671
5a168b67
KB
672void
673cpustats()
7f02df2f 674{
5a168b67
KB
675 register int state;
676 double pct, total;
677
678 total = 0;
679 for (state = 0; state < CPUSTATES; ++state)
680 total += cur.time[state];
681 if (total)
682 pct = 100 / total;
683 else
684 pct = 0;
ecc9fa0b 685 (void)printf("%2.0f ", /* user + nice */
5a168b67 686 (cur.time[0] + cur.time[1]) * pct);
ecc9fa0b
MK
687 (void)printf("%2.0f ", cur.time[2] * pct); /* system */
688 (void)printf("%2.0f", cur.time[3] * pct); /* idle */
7f02df2f
BJ
689}
690
dd6bac83 691void
0ef721f3 692dointr()
4b894a2c 693{
dd6bac83 694 register long *intrcnt, inttotal, uptime;
0ef721f3 695 register int nintr, inamlen;
0ef721f3
KB
696 register char *intrname;
697
dd6bac83 698 uptime = getuptime();
0ef721f3
KB
699 nintr = nl[X_EINTRCNT].n_value - nl[X_INTRCNT].n_value;
700 inamlen = nl[X_EINTRNAMES].n_value - nl[X_INTRNAMES].n_value;
dd6bac83 701 intrcnt = malloc((size_t)nintr);
0ef721f3 702 intrname = malloc((size_t)inamlen);
4b894a2c 703 if (intrcnt == NULL || intrname == NULL) {
dd6bac83
KB
704 (void)fprintf(stderr, "vmstat: %s.\n", strerror(errno));
705 exit(1);
4b894a2c 706 }
dd6bac83 707 kread(X_INTRCNT, intrcnt, (size_t)nintr);
0ef721f3 708 kread(X_INTRNAMES, intrname, (size_t)inamlen);
dd6bac83 709 (void)printf("interrupt total rate\n");
4b894a2c 710 inttotal = 0;
0ef721f3
KB
711 nintr /= sizeof(long);
712 while (--nintr >= 0) {
4b894a2c 713 if (*intrcnt)
dd6bac83 714 (void)printf("%-12s %8ld %8ld\n", intrname,
0ef721f3 715 *intrcnt, *intrcnt / uptime);
4b894a2c
KM
716 intrname += strlen(intrname) + 1;
717 inttotal += *intrcnt++;
718 }
dd6bac83 719 (void)printf("Total %8ld %8ld\n", inttotal, inttotal / uptime);
4b894a2c
KM
720}
721
0c429495 722/*
b004c5f6 723 * These names are defined in <sys/malloc.h>.
0c429495 724 */
b004c5f6 725char *kmemnames[] = INITKMEMNAMES;
0c429495 726
dd6bac83 727void
0c429495
KM
728domem()
729{
0c429495
KM
730 register struct kmembuckets *kp;
731 register struct kmemstats *ks;
0ef721f3 732 register int i;
6f7a6346
MK
733 int size;
734 long totuse = 0, totfree = 0, totreq = 0;
0ef721f3
KB
735 struct kmemstats kmemstats[M_LAST];
736 struct kmembuckets buckets[MINBUCKET + 16];
0c429495 737
dd6bac83
KB
738 kread(X_KMEMBUCKETS, buckets, sizeof(buckets));
739 (void)printf("Memory statistics by bucket size\n");
740 (void)printf(
0ef721f3 741 " Size In Use Free Requests HighWater Couldfree\n");
0c429495
KM
742 for (i = MINBUCKET, kp = &buckets[i]; i < MINBUCKET + 16; i++, kp++) {
743 if (kp->kb_calls == 0)
744 continue;
6f7a6346 745 size = 1 << i;
ecc9fa0b 746 (void)printf("%8d %8ld %6ld %10ld %7ld %10ld\n", size,
0c429495
KM
747 kp->kb_total - kp->kb_totalfree,
748 kp->kb_totalfree, kp->kb_calls,
749 kp->kb_highwat, kp->kb_couldfree);
6f7a6346
MK
750 totfree += size * kp->kb_totalfree;
751 totuse += size * (kp->kb_total - kp->kb_totalfree);
0c429495 752 }
6f7a6346 753
dd6bac83
KB
754 kread(X_KMEMSTAT, kmemstats, sizeof(kmemstats));
755 (void)printf("\nMemory statistics by type\n");
756 (void)printf(
757" Type In Use MemUse HighUse Limit Requests TypeLimit KernLimit\n");
0c429495
KM
758 for (i = 0, ks = &kmemstats[0]; i < M_LAST; i++, ks++) {
759 if (ks->ks_calls == 0)
760 continue;
ecc9fa0b 761 (void)printf("%10s %6ld %7ldK %8ldK %5ldK %8ld %6u %9u\n",
dd6bac83
KB
762 kmemnames[i] ? kmemnames[i] : "undefined",
763 ks->ks_inuse, (ks->ks_memuse + 1023) / 1024,
764 (ks->ks_maxused + 1023) / 1024,
765 (ks->ks_limit + 1023) / 1024, ks->ks_calls,
766 ks->ks_limblocks, ks->ks_mapblocks);
6f7a6346
MK
767 totuse += ks->ks_memuse;
768 totreq += ks->ks_calls;
0c429495 769 }
6f7a6346
MK
770 (void)printf("\nMemory Totals: In Use Free Requests\n");
771 (void)printf(" %7ldK %6ldK %8ld\n",
772 (totuse + 1023) / 1024, (totfree + 1023) / 1024, totreq);
0c429495
KM
773}
774
dd6bac83
KB
775void
776zero()
61d7d2b3 777{
c7f8f234 778 static struct nlist znl[] = {
dd6bac83
KB
779#undef X_SUM
780#define X_SUM 0
ecc9fa0b 781 { SUM },
dd6bac83
KB
782 { "" },
783 };
784 int fd;
785 char *kmem;
786
787 if (geteuid()) {
788 (void)fprintf(stderr, "vmstat: %s\n", strerror(EPERM));
61d7d2b3
MT
789 exit(1);
790 }
dd6bac83
KB
791 /*
792 * Zeroing the statistics is fundamentally different
793 * (and really belongs in a separate program).
794 */
795 if (nlist(vmunix, znl) || nl[0].n_type == 0) {
796 (void)fprintf(stderr, "vmstat: %s: symbol %s not found\n",
797 vmunix, nl[0].n_name);
798 exit(1);
61d7d2b3 799 }
dd6bac83
KB
800
801 kmem = _PATH_KMEM;
802 if ((fd = open(kmem, O_RDWR)) < 0) {
803 (void)fprintf(stderr,
804 "vmstat: %s: %s\n", kmem, strerror(errno));
805 exit(1);
806 }
807 if (lseek(fd, (long)nl[0].n_value, L_SET) == -1 ||
808 write(fd, &sum, sizeof(sum)) != sizeof(sum)) {
809 (void)fprintf(stderr,
810 "vmstat: %s: %s\n", kmem, strerror(errno));
811 exit(1);
61d7d2b3
MT
812 }
813}
242684ee
SL
814
815/*
dd6bac83 816 * kread reads something from the kernel, given its nlist index.
242684ee 817 */
dd6bac83
KB
818void
819kread(nlx, addr, size)
820 int nlx;
821 void *addr;
822 size_t size;
242684ee 823{
dd6bac83
KB
824 char *sym;
825
826 if (nl[nlx].n_type == 0 || nl[nlx].n_value == 0) {
827 sym = nl[nlx].n_name;
828 if (*sym == '_')
829 ++sym;
830 (void)fprintf(stderr,
831 "vmstat: %s: symbol %s not defined\n", vmunix, sym);
242684ee
SL
832 exit(1);
833 }
dd6bac83
KB
834 if (kvm_read((void *)nl[nlx].n_value, addr, size) != size) {
835 sym = nl[nlx].n_name;
836 if (*sym == '_')
837 ++sym;
838 (void)fprintf(stderr, "vmstat: %s: %s\n", sym, kvm_geterr());
839 exit(1);
242684ee
SL
840 }
841}
468dd322 842
dd6bac83
KB
843void
844usage()
468dd322 845{
dd6bac83 846 (void)fprintf(stderr,
6f7a6346 847#ifndef NEWVM
dd6bac83
KB
848 "usage: vmstat [-fimst] [-c count] [-M core] \
849[-N system] [-w wait] [disks]\n vmstat -z\n");
6f7a6346
MK
850#else
851 "usage: vmstat [-ims] [-c count] [-M core] \
852[-N system] [-w wait] [disks]\n vmstat -z\n");
853#endif
dd6bac83 854 exit(1);
468dd322 855}