1 |
|
|
/* $OpenBSD: vmstat.c,v 1.80 2015/08/20 22:32:42 deraadt 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 |
|
|
u_quad_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]; s.fld[i]-=s1.fld[i];} |
298 |
|
|
#define Y(fld) {s.fld; s.fld -= s1.fld;} |
299 |
|
|
#define Z(fld) {s.nchstats.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 |
|
|
bzero(&si->time, 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 |
|
|
bzero(&si->nchstats, 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 |
|
|
bzero(&si->uvmexp, 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 |
|
|
bzero(&si->Total, 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(u_quad_t)); |
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 |
|
|
u_quad_t *intrcnt; |
644 |
|
|
|
645 |
|
|
intrcnt = to->intrcnt; |
646 |
|
|
*to = *from; |
647 |
|
|
bcopy(from->intrcnt, to->intrcnt = intrcnt, nintr * sizeof (u_quad_t)); |
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 |
|
|
} |