GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/systat/vmstat.c Lines: 0 323 0.0 %
Date: 2017-11-07 Branches: 0 135 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: vmstat.c,v 1.82 2016/12/18 23:36:32 krw Exp $	*/
2
/*	$NetBSD: vmstat.c,v 1.5 1996/05/10 23:16:40 thorpej Exp $	*/
3
4
/*-
5
 * Copyright (c) 1983, 1989, 1992, 1993
6
 *	The Regents of the University of California.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. Neither the name of the University nor the names of its contributors
17
 *    may be used to endorse or promote products derived from this software
18
 *    without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * SUCH DAMAGE.
31
 */
32
33
/*
34
 * Cursed vmstat -- from Robert Elz.
35
 */
36
37
#include <sys/param.h>	/* MAXCOMLEN */
38
#include <sys/types.h>
39
#include <sys/namei.h>
40
#include <sys/proc.h>
41
#include <sys/sched.h>
42
#include <sys/stat.h>
43
#include <sys/sysctl.h>
44
#include <sys/time.h>
45
#include <sys/vmmeter.h>
46
47
#include <ctype.h>
48
#include <errno.h>
49
#include <err.h>
50
#include <paths.h>
51
#include <signal.h>
52
#include <stdlib.h>
53
#include <string.h>
54
#include <unistd.h>
55
56
#include "systat.h"
57
#include "dkstats.h"
58
59
#define MAXIMUM(a, b)	(((a) > (b)) ? (a) : (b))
60
61
static struct Info {
62
	long	time[CPUSTATES];
63
	struct	uvmexp uvmexp;
64
	struct	vmtotal Total;
65
	struct	nchstats nchstats;
66
	long	nchcount;
67
	uint64_t *intrcnt;
68
} s, s1, s2, s3, z;
69
70
extern struct _disk	cur;
71
72
#define	cnt s.Cnt
73
#define oldcnt s1.Cnt
74
#define	total s.Total
75
#define	nchtotal s.nchstats
76
#define	oldnchtotal s1.nchstats
77
78
static	enum state { BOOT, TIME, RUN } state = TIME;
79
80
static void allocinfo(struct Info *);
81
static void copyinfo(struct Info *, struct Info *);
82
static float cputime(int);
83
static void dinfo(int, int);
84
static void getinfo(struct Info *);
85
void putint(int, int, int, int);
86
void putintmk(int, int, int, int);
87
void putuint64(u_int64_t, int, int, int);
88
void putfloat(double, int, int, int, int, int);
89
int ucount(void);
90
91
void print_vm(void);
92
int read_vm(void);
93
int select_vm(void);
94
int vm_keyboard_callback(int);
95
96
static	time_t t;
97
static	double etime;
98
static	float hertz;
99
static	int nintr;
100
static	long *intrloc;
101
static	char **intrname;
102
static	int nextintsrow;
103
104
WINDOW *
105
openkre(void)
106
{
107
	return (subwin(stdscr, LINES-1-1, 0, 1, 0));
108
}
109
110
void
111
closekre(WINDOW *w)
112
{
113
114
	if (w == NULL)
115
		return;
116
	wclear(w);
117
	wrefresh(w);
118
	delwin(w);
119
}
120
121
/*
122
 * These constants define where the major pieces are laid out
123
 */
124
#define STATROW		 0	/* uses 1 row and 68 cols */
125
#define STATCOL		 2
126
#define MEMROW		 2	/* uses 4 rows and 34 cols */
127
#define MEMCOL		 0
128
#define PAGEROW		 2	/* uses 4 rows and 26 cols */
129
#define PAGECOL		37
130
#define INTSROW		 2	/* uses all rows to bottom and 17 cols */
131
#define INTSCOL		63
132
#define PROCSROW	 7	/* uses 2 rows and 20 cols */
133
#define PROCSCOL	 0
134
#define GENSTATROW	 7	/* uses 2 rows and 35 cols */
135
#define GENSTATCOL	16
136
#define VMSTATROW	 7	/* uses 18 rows and 12 cols */
137
#define VMSTATCOL	48
138
#define GRAPHROW	10	/* uses 3 rows and 51 cols */
139
#define GRAPHCOL	 0
140
#define NAMEIROW	14	/* uses 3 rows and 49 cols */
141
#define NAMEICOL	 0
142
#define DISKROW		18	/* uses 5 rows and 50 cols (for 9 drives) */
143
#define DISKCOL		 0
144
145
#define	DRIVESPACE	45	/* max space for drives */
146
147
148
field_def *view_vm_0[] = {
149
	NULL
150
};
151
152
/* Define view managers */
153
struct view_manager vmstat_mgr = {
154
	"VMstat", select_vm, read_vm, NULL, print_header,
155
	print_vm, vm_keyboard_callback, NULL, NULL
156
};
157
158
field_view views_vm[] = {
159
	{view_vm_0, "vmstat", '7', &vmstat_mgr},
160
	{NULL, NULL, 0, NULL}
161
};
162
163
int
164
initvmstat(void)
165
{
166
	field_view *v;
167
	int mib[4], i;
168
	size_t size;
169
170
	hertz = stathz;
171
	if (!dkinit(1))
172
		return(0);
173
174
	mib[0] = CTL_KERN;
175
	mib[1] = KERN_INTRCNT;
176
	mib[2] = KERN_INTRCNT_NUM;
177
	size = sizeof(nintr);
178
	if (sysctl(mib, 3, &nintr, &size, NULL, 0) < 0)
179
		return (-1);
180
181
	intrloc = calloc(nintr, sizeof(long));
182
	intrname = calloc(nintr, sizeof(char *));
183
184
	for (i = 0; i < nintr; i++) {
185
		char name[128];
186
187
		mib[0] = CTL_KERN;
188
		mib[1] = KERN_INTRCNT;
189
		mib[2] = KERN_INTRCNT_NAME;
190
		mib[3] = i;
191
		size = sizeof(name);
192
		if (sysctl(mib, 4, name, &size, NULL, 0) < 0)
193
			return (-1);
194
195
		intrname[i] = strdup(name);
196
		if (intrname[i] == NULL)
197
			return (-1);
198
	}
199
200
	nextintsrow = INTSROW + 2;
201
	allocinfo(&s);
202
	allocinfo(&s1);
203
	allocinfo(&s2);
204
	allocinfo(&s3);
205
	allocinfo(&z);
206
207
	getinfo(&s2);
208
	copyinfo(&z, &s1);
209
210
	for (v = views_vm; v->name != NULL; v++)
211
		add_view(v);
212
213
	return(1);
214
}
215
216
void
217
fetchkre(void)
218
{
219
	getinfo(&s3);
220
}
221
222
void
223
labelkre(void)
224
{
225
	int i, j, l;
226
227
	mvprintw(MEMROW, MEMCOL,     "            memory totals (in KB)");
228
	mvprintw(MEMROW + 1, MEMCOL, "           real   virtual     free");
229
	mvprintw(MEMROW + 2, MEMCOL, "Active");
230
	mvprintw(MEMROW + 3, MEMCOL, "All");
231
232
	mvprintw(PAGEROW, PAGECOL, "        PAGING   SWAPPING ");
233
	mvprintw(PAGEROW + 1, PAGECOL, "        in  out   in  out ");
234
	mvprintw(PAGEROW + 2, PAGECOL, "ops");
235
	mvprintw(PAGEROW + 3, PAGECOL, "pages");
236
237
	mvprintw(INTSROW, INTSCOL + 3, " Interrupts");
238
	mvprintw(INTSROW + 1, INTSCOL + 9, "total");
239
240
	mvprintw(LINES - 3, INTSCOL + 9, "IPKTS");
241
	mvprintw(LINES - 2, INTSCOL + 9, "OPKTS");
242
243
	mvprintw(VMSTATROW + 0, VMSTATCOL + 10, "forks");
244
	mvprintw(VMSTATROW + 1, VMSTATCOL + 10, "fkppw");
245
	mvprintw(VMSTATROW + 2, VMSTATCOL + 10, "fksvm");
246
	mvprintw(VMSTATROW + 3, VMSTATCOL + 10, "pwait");
247
	mvprintw(VMSTATROW + 4, VMSTATCOL + 10, "relck");
248
	mvprintw(VMSTATROW + 5, VMSTATCOL + 10, "rlkok");
249
	mvprintw(VMSTATROW + 6, VMSTATCOL + 10, "noram");
250
	mvprintw(VMSTATROW + 7, VMSTATCOL + 10, "ndcpy");
251
	mvprintw(VMSTATROW + 8, VMSTATCOL + 10, "fltcp");
252
	mvprintw(VMSTATROW + 9, VMSTATCOL + 10, "zfod");
253
	mvprintw(VMSTATROW + 10, VMSTATCOL + 10, "cow");
254
	mvprintw(VMSTATROW + 11, VMSTATCOL + 10, "fmin");
255
	mvprintw(VMSTATROW + 12, VMSTATCOL + 10, "ftarg");
256
	mvprintw(VMSTATROW + 13, VMSTATCOL + 10, "itarg");
257
	mvprintw(VMSTATROW + 14, VMSTATCOL + 10, "wired");
258
	mvprintw(VMSTATROW + 15, VMSTATCOL + 10, "pdfre");
259
	if (LINES - 1 > VMSTATROW + 16)
260
		mvprintw(VMSTATROW + 16, VMSTATCOL + 10, "pdscn");
261
	if (LINES - 1 > VMSTATROW + 17)
262
		mvprintw(VMSTATROW + 17, VMSTATCOL + 10, "pzidle");
263
	if (LINES - 1 > VMSTATROW + 18)
264
		mvprintw(VMSTATROW + 18, VMSTATCOL + 10, "kmapent");
265
266
	mvprintw(GENSTATROW, GENSTATCOL, "   Csw   Trp   Sys   Int   Sof  Flt");
267
268
	mvprintw(GRAPHROW, GRAPHCOL,
269
	    "    . %%Int    . %%Sys    . %%Usr    . %%Nic    . %%Idle");
270
	mvprintw(PROCSROW, PROCSCOL, "Proc:r  d  s  w");
271
	mvprintw(GRAPHROW + 1, GRAPHCOL,
272
	    "|    |    |    |    |    |    |    |    |    |    |");
273
274
	mvprintw(NAMEIROW, NAMEICOL,
275
	    "Namei         Sys-cache    Proc-cache    No-cache");
276
	mvprintw(NAMEIROW + 1, NAMEICOL,
277
	    "    Calls     hits    %%    hits     %%    miss   %%");
278
	mvprintw(DISKROW, DISKCOL, "Disks");
279
	mvprintw(DISKROW + 1, DISKCOL, "seeks");
280
	mvprintw(DISKROW + 2, DISKCOL, "xfers");
281
	mvprintw(DISKROW + 3, DISKCOL, "speed");
282
	mvprintw(DISKROW + 4, DISKCOL, "  sec");
283
	for (i = 0, j = 0; i < cur.dk_ndrive && j < DRIVESPACE; i++)
284
		if (cur.dk_select[i] && (j + strlen(dr_name[i])) < DRIVESPACE) {
285
			l = MAXIMUM(5, strlen(dr_name[i]));
286
			mvprintw(DISKROW, DISKCOL + 5 + j,
287
			    " %*s", l, dr_name[i]);
288
			j += 1 + l;
289
		}
290
	for (i = 0; i < nintr; i++) {
291
		if (intrloc[i] == 0)
292
			continue;
293
		mvprintw(intrloc[i], INTSCOL + 9, "%-8.8s", intrname[i]);
294
	}
295
}
296
297
#define X(fld)	{s.fld[i]-=s1.fld[i];}
298
#define Y(fld)	{s.fld -= s1.fld;}
299
#define Z(fld)	{s.nchstats.fld -= s1.nchstats.fld;}
300
#define PUTRATE(fld, l, c, w) \
301
	do { \
302
		Y(fld); \
303
		putint((int)((float)s.fld/etime + 0.5), l, c, w); \
304
	} while (0)
305
#define MAXFAIL 5
306
307
static	char cpuchar[CPUSTATES] = { '|', '=', '>', '-', ' ' };
308
static	char cpuorder[CPUSTATES] = { CP_INTR, CP_SYS, CP_USER, CP_NICE, CP_IDLE };
309
310
void
311
showkre(void)
312
{
313
	float f1, f2;
314
	int psiz;
315
	u_int64_t inttotal, intcnt;
316
	int i, l, c;
317
	static int failcnt = 0, first_run = 0;
318
319
	if (state == TIME) {
320
		if (!first_run) {
321
			first_run = 1;
322
			return;
323
		}
324
	}
325
	etime = 0;
326
	for (i = 0; i < CPUSTATES; i++) {
327
		X(time);
328
		etime += s.time[i];
329
	}
330
	if (etime < 5.0) {	/* < 5 ticks - ignore this trash */
331
		if (failcnt++ >= MAXFAIL) {
332
			error("The alternate system clock has died!");
333
			failcnt = 0;
334
		}
335
		return;
336
	}
337
	failcnt = 0;
338
	etime /= hertz;
339
	inttotal = 0;
340
	for (i = 0; i < nintr; i++) {
341
		if (s.intrcnt[i] == 0)
342
			continue;
343
		if (intrloc[i] == 0) {
344
			if (nextintsrow == LINES)
345
				continue;
346
			intrloc[i] = nextintsrow++;
347
			mvprintw(intrloc[i], INTSCOL + 9, "%-8.8s",
348
			    intrname[i]);
349
		}
350
		t = intcnt = s.intrcnt[i];
351
		s.intrcnt[i] -= s1.intrcnt[i];
352
		intcnt = (u_int64_t)((float)s.intrcnt[i]/etime + 0.5);
353
		inttotal += intcnt;
354
		putuint64(intcnt, intrloc[i], INTSCOL, 8);
355
	}
356
	putuint64(inttotal, INTSROW + 1, INTSCOL, 8);
357
	Z(ncs_goodhits); Z(ncs_badhits); Z(ncs_miss);
358
	Z(ncs_long); Z(ncs_pass2); Z(ncs_2passes);
359
	s.nchcount = nchtotal.ncs_goodhits + nchtotal.ncs_badhits +
360
	    nchtotal.ncs_miss + nchtotal.ncs_long;
361
362
	putint(sum.ifc_ip, LINES - 3, INTSCOL, 8);
363
	putint(sum.ifc_op, LINES - 2, INTSCOL, 8);
364
365
	psiz = 0;
366
	f2 = 0.0;
367
368
	for (c = 0; c < CPUSTATES; c++) {
369
		i = cpuorder[c];
370
		f1 = cputime(i);
371
		f2 += f1;
372
		l = (int) ((f2 + 1.0) / 2.0) - psiz;
373
		putfloat(f1, GRAPHROW, GRAPHCOL + 1 + (10 * c), 5, 1, 0);
374
		move(GRAPHROW + 2, psiz);
375
		psiz += l;
376
		while (l-- > 0)
377
			addch(cpuchar[c]);
378
	}
379
380
#define pgtokb(pg)	((pg) * (s.uvmexp.pagesize / 1024))
381
382
	putint(pgtokb(s.uvmexp.active), MEMROW + 2, MEMCOL + 7, 8);
383
	putint(pgtokb(s.uvmexp.active + s.uvmexp.swpginuse),    /* XXX */
384
	    MEMROW + 2, MEMCOL + 17, 8);
385
	putint(pgtokb(s.uvmexp.npages - s.uvmexp.free), MEMROW + 3, MEMCOL + 7, 8);
386
	putint(pgtokb(s.uvmexp.npages - s.uvmexp.free + s.uvmexp.swpginuse),
387
	    MEMROW + 3, MEMCOL + 17, 8);
388
	putint(pgtokb(s.uvmexp.free), MEMROW + 2, MEMCOL + 26, 8);
389
	putint(pgtokb(s.uvmexp.free + s.uvmexp.swpages - s.uvmexp.swpginuse),
390
	    MEMROW + 3, MEMCOL + 26, 8);
391
	putint(total.t_rq - 1, PROCSROW + 1, PROCSCOL + 3, 3);
392
393
	putint(total.t_dw, PROCSROW + 1, PROCSCOL + 6, 3);
394
	putint(total.t_sl, PROCSROW + 1, PROCSCOL + 9, 3);
395
	putint(total.t_sw, PROCSROW + 1, PROCSCOL + 12, 3);
396
	PUTRATE(uvmexp.forks, VMSTATROW + 0, VMSTATCOL + 3, 6);
397
	PUTRATE(uvmexp.forks_ppwait, VMSTATROW + 1, VMSTATCOL + 3, 6);
398
	PUTRATE(uvmexp.forks_sharevm, VMSTATROW + 2, VMSTATCOL + 3, 6);
399
	PUTRATE(uvmexp.fltpgwait, VMSTATROW + 3, VMSTATCOL + 4, 5);
400
	PUTRATE(uvmexp.fltrelck, VMSTATROW + 4, VMSTATCOL + 3, 6);
401
	PUTRATE(uvmexp.fltrelckok, VMSTATROW + 5, VMSTATCOL + 3, 6);
402
	PUTRATE(uvmexp.fltnoram, VMSTATROW + 6, VMSTATCOL + 3, 6);
403
	PUTRATE(uvmexp.fltamcopy, VMSTATROW + 7, VMSTATCOL + 3, 6);
404
	PUTRATE(uvmexp.flt_prcopy, VMSTATROW + 8, VMSTATCOL + 3, 6);
405
	PUTRATE(uvmexp.flt_przero, VMSTATROW + 9, VMSTATCOL + 3, 6);
406
	PUTRATE(uvmexp.flt_acow, VMSTATROW + 10, VMSTATCOL, 9);
407
	putint(s.uvmexp.freemin, VMSTATROW + 11, VMSTATCOL, 9);
408
	putint(s.uvmexp.freetarg, VMSTATROW + 12, VMSTATCOL, 9);
409
	putint(s.uvmexp.inactarg, VMSTATROW + 13, VMSTATCOL, 9);
410
	putint(s.uvmexp.wired, VMSTATROW + 14, VMSTATCOL, 9);
411
	PUTRATE(uvmexp.pdfreed, VMSTATROW + 15, VMSTATCOL, 9);
412
	if (LINES - 1 > VMSTATROW + 16)
413
		PUTRATE(uvmexp.pdscans, VMSTATROW + 16, VMSTATCOL, 9);
414
	if (LINES - 1 > VMSTATROW + 17)
415
		PUTRATE(uvmexp.zeropages, VMSTATROW + 17, VMSTATCOL, 9);
416
	if (LINES - 1 > VMSTATROW + 18)
417
		putint(s.uvmexp.kmapent, VMSTATROW + 18, VMSTATCOL, 9);
418
419
	PUTRATE(uvmexp.pageins, PAGEROW + 2, PAGECOL + 5, 5);
420
	PUTRATE(uvmexp.pdpageouts, PAGEROW + 2, PAGECOL + 10, 5);
421
	PUTRATE(uvmexp.pgswapin, PAGEROW + 3, PAGECOL + 5, 5);
422
	PUTRATE(uvmexp.pgswapout, PAGEROW + 3, PAGECOL + 10, 5);
423
424
	PUTRATE(uvmexp.swtch, GENSTATROW + 1, GENSTATCOL, 6);
425
	PUTRATE(uvmexp.traps, GENSTATROW + 1, GENSTATCOL + 6, 6);
426
	PUTRATE(uvmexp.syscalls, GENSTATROW + 1, GENSTATCOL + 12, 6);
427
	PUTRATE(uvmexp.intrs, GENSTATROW + 1, GENSTATCOL + 18, 6);
428
	PUTRATE(uvmexp.softs, GENSTATROW + 1, GENSTATCOL + 24, 6);
429
	PUTRATE(uvmexp.faults, GENSTATROW + 1, GENSTATCOL + 30, 5);
430
	mvprintw(DISKROW, DISKCOL + 5, "                              ");
431
	for (i = 0, c = 0; i < cur.dk_ndrive && c < DRIVESPACE; i++)
432
		if (cur.dk_select[i] && (c + strlen(dr_name[i])) < DRIVESPACE) {
433
			l = MAXIMUM(5, strlen(dr_name[i]));
434
			mvprintw(DISKROW, DISKCOL + 5 + c,
435
			    " %*s", l, dr_name[i]);
436
			c += 1 + l;
437
			dinfo(i, c);
438
		}
439
	/* and pad the DRIVESPACE */
440
	l = DRIVESPACE - c;
441
	for (i = 0; i < 5; i++)
442
		mvprintw(DISKROW + i, DISKCOL + 5 + c, "%*s", l, "");
443
444
	putint(s.nchcount, NAMEIROW + 2, NAMEICOL, 9);
445
	putint(nchtotal.ncs_goodhits, NAMEIROW + 2, NAMEICOL + 10, 8);
446
#define nz(x)	((x) ? (x) : 1)
447
	putfloat(nchtotal.ncs_goodhits * 100.0 / nz(s.nchcount),
448
	    NAMEIROW + 2, NAMEICOL + 19, 4, 0, 1);
449
	putint(nchtotal.ncs_pass2, NAMEIROW + 2, NAMEICOL + 24, 7);
450
	putfloat(nchtotal.ncs_pass2 * 100.0 / nz(s.nchcount),
451
	    NAMEIROW + 2, NAMEICOL + 33, 4, 0, 1);
452
	putint(nchtotal.ncs_miss + nchtotal.ncs_long - nchtotal.ncs_pass2,
453
	   NAMEIROW + 2, NAMEICOL + 38, 7);
454
	putfloat((nchtotal.ncs_miss + nchtotal.ncs_long - nchtotal.ncs_pass2) *
455
	    100.0 / nz(s.nchcount), NAMEIROW + 2, NAMEICOL + 45, 4, 0, 1);
456
#undef nz
457
458
}
459
460
int
461
vm_keyboard_callback(int ch)
462
{
463
	switch(ch) {
464
	case 'r':
465
		copyinfo(&s2, &s1);
466
		state = RUN;
467
		break;
468
	case 'b':
469
		state = BOOT;
470
		copyinfo(&z, &s1);
471
		break;
472
	case 't':
473
		state = TIME;
474
		break;
475
	case 'z':
476
		if (state == RUN)
477
			getinfo(&s1);
478
		break;
479
	}
480
	return (keyboard_callback(ch));
481
}
482
483
484
static float
485
cputime(int indx)
486
{
487
	double tm;
488
	int i;
489
490
	tm = 0;
491
	for (i = 0; i < CPUSTATES; i++)
492
		tm += s.time[i];
493
	if (tm == 0.0)
494
		tm = 1.0;
495
	return (s.time[indx] * 100.0 / tm);
496
}
497
498
void
499
putint(int n, int l, int c, int w)
500
{
501
	char b[128];
502
503
	move(l, c);
504
	if (n == 0) {
505
		while (w-- > 0)
506
			addch(' ');
507
		return;
508
	}
509
	snprintf(b, sizeof b, "%*d", w, n);
510
	if (strlen(b) > w) {
511
		while (w-- > 0)
512
			addch('*');
513
		return;
514
	}
515
	addstr(b);
516
}
517
518
void
519
putintmk(int n, int l, int c, int w)
520
{
521
	char b[128];
522
523
	move(l, c);
524
	if (n == 0) {
525
		while (w-- > 0)
526
			addch(' ');
527
		return;
528
	}
529
	if (n > 9999 * 1024)
530
		snprintf(b, sizeof b, "%*dG", w - 1, n / 1024 / 1024);
531
	else if (n > 9999)
532
		snprintf(b, sizeof b, "%*dM", w - 1, n / 1024);
533
	else
534
		snprintf(b, sizeof b, "%*dK", w - 1, n);
535
	if (strlen(b) > w) {
536
		while (w-- > 0)
537
			addch('*');
538
		return;
539
	}
540
	addstr(b);
541
}
542
543
void
544
putuint64(u_int64_t n, int l, int c, int w)
545
{
546
	char b[128];
547
548
	move(l, c);
549
	if (n == 0) {
550
		while (w-- > 0)
551
			addch(' ');
552
		return;
553
	}
554
	snprintf(b, sizeof b, "%*llu", w, n);
555
	if (strlen(b) > w) {
556
		while (w-- > 0)
557
			addch('*');
558
		return;
559
	}
560
	addstr(b);
561
}
562
563
void
564
putfloat(double f, int l, int c, int w, int d, int nz)
565
{
566
	char b[128];
567
568
	move(l, c);
569
	if (nz && f == 0.0) {
570
		while (--w >= 0)
571
			addch(' ');
572
		return;
573
	}
574
	snprintf(b, sizeof b, "%*.*f", w, d, f);
575
	if (strlen(b) > w) {
576
		while (--w >= 0)
577
			addch('*');
578
		return;
579
	}
580
	addstr(b);
581
}
582
583
static void
584
getinfo(struct Info *si)
585
{
586
	static int cp_time_mib[] = { CTL_KERN, KERN_CPTIME };
587
	static int nchstats_mib[2] = { CTL_KERN, KERN_NCHSTATS };
588
	static int uvmexp_mib[2] = { CTL_VM, VM_UVMEXP };
589
	static int vmtotal_mib[2] = { CTL_VM, VM_METER };
590
	int mib[4], i;
591
	size_t size;
592
593
	dkreadstats();
594
595
	for (i = 0; i < nintr; i++) {
596
		mib[0] = CTL_KERN;
597
		mib[1] = KERN_INTRCNT;
598
		mib[2] = KERN_INTRCNT_CNT;
599
		mib[3] = i;
600
		size = sizeof(si->intrcnt[i]);
601
		if (sysctl(mib, 4, &si->intrcnt[i], &size, NULL, 0) < 0) {
602
			si->intrcnt[i] = 0;
603
		}
604
	}
605
606
	size = sizeof(si->time);
607
	if (sysctl(cp_time_mib, 2, &si->time, &size, NULL, 0) < 0) {
608
		error("Can't get KERN_CPTIME: %s\n", strerror(errno));
609
		memset(&si->time, 0, sizeof(si->time));
610
	}
611
612
	size = sizeof(si->nchstats);
613
	if (sysctl(nchstats_mib, 2, &si->nchstats, &size, NULL, 0) < 0) {
614
		error("Can't get KERN_NCHSTATS: %s\n", strerror(errno));
615
		memset(&si->nchstats, 0, sizeof(si->nchstats));
616
	}
617
618
	size = sizeof(si->uvmexp);
619
	if (sysctl(uvmexp_mib, 2, &si->uvmexp, &size, NULL, 0) < 0) {
620
		error("Can't get VM_UVMEXP: %s\n", strerror(errno));
621
		memset(&si->uvmexp, 0, sizeof(si->uvmexp));
622
	}
623
624
	size = sizeof(si->Total);
625
	if (sysctl(vmtotal_mib, 2, &si->Total, &size, NULL, 0) < 0) {
626
		error("Can't get VM_METER: %s\n", strerror(errno));
627
		memset(&si->Total, 0, sizeof(si->Total));
628
	}
629
}
630
631
static void
632
allocinfo(struct Info *si)
633
{
634
	memset(si, 0, sizeof(*si));
635
	si->intrcnt = calloc(nintr, sizeof(*si->intrcnt));
636
	if (si->intrcnt == NULL)
637
		errx(2, "out of memory");
638
}
639
640
static void
641
copyinfo(struct Info *from, struct Info *to)
642
{
643
	uint64_t *intrcnt;
644
645
	intrcnt = to->intrcnt;
646
	*to = *from;
647
	memcpy(to->intrcnt = intrcnt, from->intrcnt, nintr * sizeof(*intrcnt));
648
}
649
650
static void
651
dinfo(int dn, int c)
652
{
653
	double words, atime;
654
655
	c += DISKCOL;
656
657
	/* time busy in disk activity */
658
	atime = (double)cur.dk_time[dn].tv_sec +
659
	    ((double)cur.dk_time[dn].tv_usec / (double)1000000);
660
661
	/* # of K transferred */
662
	words = (cur.dk_rbytes[dn] + cur.dk_wbytes[dn]) / 1024.0;
663
664
	putint((int)((float)cur.dk_seek[dn]/etime+0.5), DISKROW + 1, c, 5);
665
	putint((int)((float)(cur.dk_rxfer[dn] + cur.dk_wxfer[dn])/etime+0.5),
666
	    DISKROW + 2, c, 5);
667
	putintmk((int)(words/etime + 0.5), DISKROW + 3, c, 5);
668
	putfloat(atime/etime, DISKROW + 4, c, 5, 1, 1);
669
}
670
671
672
673
int
674
select_vm(void)
675
{
676
	num_disp = 0;
677
	return (0);
678
}
679
680
int
681
read_vm(void)
682
{
683
	if (state == TIME)
684
		copyinfo(&s3, &s1);
685
	fetchkre();
686
	fetchifstat();
687
	if (state == TIME)
688
		dkswap();
689
	num_disp = 0;
690
	return 0;
691
}
692
693
694
void
695
print_vm(void)
696
{
697
	copyinfo(&s3, &s);
698
	labelkre();
699
	showkre();
700
}