Commit | Line | Data |
---|---|---|
f42904bc DF |
1 | /* |
2 | * Copyright (c) 1983 Regents of the University of California. | |
3 | * All rights reserved. The Berkeley software License Agreement | |
4 | * specifies the terms and conditions for redistribution. | |
5 | */ | |
6 | ||
7 | #ifndef lint | |
8 | char copyright[] = | |
9 | "@(#) Copyright (c) 1983 Regents of the University of California.\n\ | |
10 | All rights reserved.\n"; | |
11 | #endif not lint | |
12 | ||
82c646ae | 13 | #ifndef lint |
f42904bc DF |
14 | static char sccsid[] = "@(#)vmstat.c 5.1 (Berkeley) %G%"; |
15 | #endif not lint | |
82c646ae SL |
16 | |
17 | /* | |
18 | * Cursed vmstat -- from Robert Elz. | |
19 | */ | |
20 | #include <curses.h> | |
21 | #include <signal.h> | |
22 | #include <nlist.h> | |
23 | /* this is STUPID! | |
24 | #include <sys/time.h> | |
25 | */ | |
26 | #include <ctype.h> | |
27 | #include <utmp.h> | |
28 | #include <sys/param.h> | |
29 | #include <sys/vm.h> | |
30 | #include <sys/dk.h> | |
31 | #include <sys/buf.h> | |
32 | #include <vaxuba/ubavar.h> | |
33 | #include <vaxmba/mbavar.h> | |
34 | #include <sys/stat.h> | |
35 | #include <sys/dir.h> | |
36 | #include <sys/user.h> | |
37 | #include <sys/proc.h> | |
38 | #include <vax/pte.h> | |
3bc5a770 KM |
39 | #include <sys/namei.h> |
40 | ||
41 | /* | |
42 | * These constants define where the major pieces are laid out | |
43 | */ | |
44 | #define PROCSROW 13 /* uses 2 rows and 20 cols */ | |
45 | #define PROCSCOL 0 | |
46 | #define NAMEIROW 20 /* uses 3 rows and 38 cols */ | |
47 | #define NAMEICOL 0 | |
48 | #define GRAPHROW 16 /* uses 3 rows and 51 cols */ | |
49 | #define GRAPHCOL 0 | |
50 | #define GENSTATROW 14 /* uses 8 rows and 11 cols */ | |
51 | #define GENSTATCOL 51 | |
52 | #define INTSROW 2 /* uses all rows to bottom and 17 cols */ | |
53 | #define INTSCOL 63 | |
54 | #define STATROW 0 /* uses 1 row and 68 cols */ | |
55 | #define STATCOL 2 | |
56 | #define PAGEROW 2 /* uses 11 rows and 26 cols */ | |
57 | #define PAGECOL 36 | |
58 | #define MEMROW 2 /* uses 4 rows and 31 cols */ | |
59 | #define MEMCOL 0 | |
60 | #define DISKROW 7 /* uses 5 rows and 35 cols */ | |
61 | #define DISKCOL 0 | |
82c646ae | 62 | |
269ebe33 KM |
63 | /* |
64 | * Maximum number of times that the clock may no longer advance. | |
65 | */ | |
66 | #define LOOPMAX 10 | |
67 | ||
82c646ae SL |
68 | #if DK_NDRIVE > 6 |
69 | #undef DK_NDRIVE | |
70 | #define DK_NDRIVE 6 | |
71 | #endif | |
72 | ||
73 | char *fread(); | |
74 | long time(); | |
75 | float cputime(); | |
76 | char *asctime(); | |
77 | struct tm *localtime(); | |
78 | ||
79 | void finish(); | |
80 | void docmd(); | |
81 | struct utmp utmp; | |
82 | ||
83 | struct nlist name[] = { | |
84 | { "_cp_time" }, | |
85 | #define X_CPTIME 0 | |
86 | { "_rate" }, | |
87 | #define X_RATE 1 | |
88 | { "_total" }, | |
89 | #define X_TOTAL 2 | |
90 | { "_avenrun" }, | |
91 | #define X_AVENRUN 3 | |
92 | { "_proc" }, | |
93 | #define X_PROC 4 | |
94 | { "_nproc" }, | |
95 | #define X_NPROC 5 | |
96 | { "_bootime" }, | |
97 | #define X_BOOTIME 6 | |
98 | { "_deficit" }, | |
99 | #define X_DEFICIT 7 | |
100 | { "_ubdinit" }, | |
101 | #define X_UBDINIT 8 | |
102 | { "_mbdinit" }, | |
103 | #define X_MBDINIT 9 | |
104 | { "_sum" }, | |
105 | #define X_SUM 10 | |
106 | { "_dk_busy" }, | |
107 | #define X_DK_BUSY 11 | |
108 | { "_dk_time" }, | |
109 | #define X_DK_TIME 12 | |
110 | { "_dk_xfer" }, | |
111 | #define X_DK_XFER 13 | |
112 | { "_dk_wds" }, | |
113 | #define X_DK_WDS 14 | |
114 | { "_tk_nin" }, | |
115 | #define X_TK_NIN 15 | |
116 | { "_tk_nout" }, | |
117 | #define X_TK_NOUT 16 | |
118 | { "_dk_seek" }, | |
119 | #define X_DK_SEEK 17 | |
120 | { "_dk_mspw" }, | |
121 | #define X_DK_MSPW 18 | |
122 | { "_hz" }, | |
123 | #define X_HZ 19 | |
124 | { "_phz" }, | |
125 | #define X_PHZ 20 | |
126 | { "_nchstats" }, | |
127 | #define X_NCHSTATS 21 | |
3bc5a770 KM |
128 | { "_intrnames" }, |
129 | #define X_INTRNAMES 22 | |
130 | { "_eintrnames" }, | |
131 | #define X_EINTRNAMES 23 | |
132 | { "_intrcnt" }, | |
133 | #define X_INTRCNT 24 | |
134 | { "_eintrcnt" }, | |
135 | #define X_EINTRCNT 25 | |
82c646ae SL |
136 | { 0 }, |
137 | }; | |
138 | ||
139 | struct Info { | |
140 | long time[CPUSTATES]; | |
141 | struct vmmeter Rate; | |
142 | struct vmtotal Total; | |
143 | struct vmmeter Sum; | |
144 | struct forkstat Forkstat; | |
145 | long dk_time[DK_NDRIVE]; | |
146 | long dk_wds[DK_NDRIVE]; | |
147 | long dk_seek[DK_NDRIVE]; | |
148 | long dk_xfer[DK_NDRIVE]; | |
149 | float dk_mspw[DK_NDRIVE]; | |
150 | int dk_busy; | |
151 | long tk_nin; | |
152 | long tk_nout; | |
153 | struct nchstats nchstats; | |
154 | long nchcount; | |
3bc5a770 | 155 | long *intrcnt; |
82c646ae SL |
156 | } s, s1, s2, z; |
157 | ||
158 | ||
159 | #define total s.Total | |
160 | #define sum s.Sum | |
161 | #define sumold s1.Sum | |
162 | #define rate s.Rate | |
163 | #define nchtotal s.nchstats | |
164 | #define oldnchtotal s1.nchstats | |
165 | #define oldrate s1.Rate | |
166 | #define X(fld) {t=s.fld[i]; s.fld[i]-=s1.fld[i]; if(state==TIME) s1.fld[i]=t;} | |
167 | #define Y(fld) {t = s.fld; s.fld -= s1.fld; if(state == TIME) s1.fld = t;} | |
168 | #define Z(fld) {t = s.nchstats.fld; s.nchstats.fld -= s1.nchstats.fld; \ | |
169 | if(state == TIME) s1.nchstats.fld = t;} | |
170 | ||
171 | int ut; | |
172 | int kmem; | |
173 | int deficit; | |
174 | double avenrun[3]; | |
175 | long c; | |
176 | char buf[26]; | |
177 | time_t t; | |
178 | time_t bootime; | |
179 | double etime; | |
180 | int secs; | |
3bc5a770 | 181 | int delay = 5; |
82c646ae SL |
182 | int hz; |
183 | int phz; | |
184 | float hertz; | |
3bc5a770 | 185 | int nintr; |
e19c46c2 KM |
186 | long *intrloc; |
187 | char **intrname; | |
82c646ae SL |
188 | |
189 | char dr_name[DK_NDRIVE][10]; | |
190 | enum state { BOOT, TIME, RUN, STOP } state = TIME; | |
191 | enum { NONE, SOME } dr_state[DK_NDRIVE]; | |
192 | ||
193 | char cpuchar[CPUSTATES] = { '=' , '>', '-', ' ' }; | |
194 | char cpuorder[CPUSTATES] = { CP_SYS, CP_USER, CP_NICE, CP_IDLE }; | |
195 | ||
196 | main(argc,argv) | |
197 | int argc; | |
198 | char **argv; | |
199 | { | |
200 | time_t now, lastime, starttime; | |
269ebe33 | 201 | int i, l, c, loopcnt; |
82c646ae SL |
202 | int psiz; |
203 | int interv; | |
204 | int hits; | |
205 | float f1, f2; | |
3bc5a770 | 206 | int inttotal, nextintsrow; |
e19c46c2 | 207 | char *intrnamebuf, *cp, *calloc(), *malloc(); |
82c646ae SL |
208 | |
209 | if (argc > 1) | |
210 | switch (c = argv[1][0] == '-' ? argv[1][1] : argv[1][0]) { | |
211 | ||
212 | case 't': | |
213 | state = TIME; | |
214 | break; | |
215 | ||
216 | case 'r': | |
217 | state = RUN; | |
218 | break; | |
219 | ||
220 | case 'b': | |
221 | state = BOOT; | |
222 | break; | |
223 | ||
224 | case '1': case '2': case '3': case '4': | |
225 | case '5': case '6': case '7': case '8': case '9': | |
226 | delay = c - '0'; | |
227 | break; | |
228 | ||
229 | } | |
230 | if ((kmem = open("/dev/kmem",0)) < 0) { | |
231 | fprintf(stderr, "No /dev/kmem \n"); | |
232 | exit(1); | |
233 | } | |
234 | ||
235 | if ((ut = open("/etc/utmp", 0)) < 0) { | |
236 | fprintf(stderr, "No utmp\n"); | |
237 | exit(1); | |
238 | } | |
239 | ||
240 | nlist("/vmunix",name); | |
241 | if (name[0].n_type == 0) { | |
242 | fprintf(stderr, "No namelist\n"); | |
243 | exit(1); | |
244 | } | |
245 | lseek(kmem, (long)name[X_HZ].n_value, 0); | |
246 | read(kmem, &hz, sizeof hz); | |
247 | lseek(kmem, (long)name[X_PHZ].n_value, 0); | |
248 | read(kmem, &phz, sizeof phz); | |
249 | hertz = phz ? phz : hz; | |
250 | lseek(kmem, (long)name[X_DK_MSPW].n_value, 0); | |
251 | read(kmem, s.dk_mspw, sizeof s.dk_mspw); | |
252 | for (i = 0; i < DK_NDRIVE; i++) | |
253 | if (s.dk_mspw[i] == 0.0) | |
254 | dr_state[i] = NONE; | |
255 | else | |
256 | dr_state[i] = SOME; | |
257 | read_names(); | |
258 | ||
3bc5a770 KM |
259 | nintr = (name[X_EINTRCNT].n_value - |
260 | name[X_INTRCNT].n_value) / sizeof(long); | |
261 | intrloc = (long *) calloc(nintr, sizeof(long)); | |
262 | intrname = (char **) calloc(nintr, sizeof(long)); | |
263 | intrnamebuf = malloc(name[X_EINTRNAMES].n_value - | |
264 | name[X_INTRNAMES].n_value); | |
265 | if (intrnamebuf == NULL || intrname == NULL || intrloc == NULL) { | |
266 | fprintf(stderr, "vsta: out of memory\n"); | |
267 | exit(1); | |
268 | } | |
269 | lseek(kmem, (long)name[X_INTRNAMES].n_value, 0); | |
270 | read(kmem, intrnamebuf, name[X_EINTRNAMES].n_value - | |
271 | name[X_INTRNAMES].n_value); | |
272 | for (cp = intrnamebuf, i = 0; i < nintr; i++) { | |
273 | intrname[i] = cp; | |
274 | cp += strlen(cp) + 1; | |
275 | } | |
276 | nextintsrow = INTSROW + 2; | |
277 | allocinfo(&s); | |
278 | allocinfo(&s1); | |
279 | allocinfo(&s2); | |
280 | allocinfo(&z); | |
82c646ae SL |
281 | |
282 | time(&lastime); | |
283 | starttime = lastime; | |
284 | getinfo(&s2, RUN); | |
3bc5a770 KM |
285 | switch (state) { |
286 | case RUN: | |
287 | copyinfo(&s2, &s1); | |
288 | break; | |
289 | case TIME: | |
290 | getinfo(&s1, TIME); | |
291 | break; | |
292 | case BOOT: | |
293 | copyinfo(&z, &s1); | |
294 | break; | |
295 | default: | |
296 | fprintf(stderr, "vsta: bad state %d\n", state); | |
297 | exit(3); | |
298 | break; | |
299 | } | |
82c646ae SL |
300 | lseek(kmem, (long)name[X_BOOTIME].n_value, 0); |
301 | read(kmem, &bootime, sizeof bootime); | |
3bc5a770 KM |
302 | |
303 | initscr(); | |
304 | signal(SIGINT, finish); | |
305 | noecho(); | |
306 | crmode(); | |
307 | layout(); | |
308 | ||
269ebe33 | 309 | for (loopcnt = 0; loopcnt < LOOPMAX; loopcnt++) { |
82c646ae SL |
310 | while (state == STOP) |
311 | waittty(delay*10); | |
312 | time(&now); | |
313 | strcpy(buf, ctime(&now)); | |
314 | buf[16] = '\0'; | |
315 | getinfo(&s, state); | |
316 | for (i = 0; i < DK_NDRIVE; i++) { | |
317 | X(dk_xfer); X(dk_seek); X(dk_wds); X(dk_time); | |
318 | } | |
319 | Y(tk_nin); Y(tk_nout); | |
320 | etime = 0; | |
e19c46c2 | 321 | for(i = 0; i < CPUSTATES; i++) { |
82c646ae SL |
322 | X(time); |
323 | etime += s.time[i]; | |
324 | } | |
325 | if (etime < 5.0) /* < 5 ticks - ignore this trash */ | |
326 | continue; | |
269ebe33 | 327 | loopcnt = 0; |
82c646ae | 328 | etime /= hertz; |
3bc5a770 KM |
329 | inttotal = 0; |
330 | for (i = 0; i < nintr; i++) { | |
331 | if (s.intrcnt[i] == 0) | |
332 | continue; | |
333 | if (intrloc[i] == 0) { | |
334 | if (nextintsrow == LINES) | |
335 | continue; | |
336 | intrloc[i] = nextintsrow++; | |
337 | mvprintw(intrloc[i], INTSCOL + 9, "%-8.8s", | |
338 | intrname[i]); | |
339 | } | |
340 | X(intrcnt); | |
341 | l = (int)((float)s.intrcnt[i]/etime + 0.5); | |
342 | inttotal += l; | |
343 | putint(l, intrloc[i], INTSCOL, 8); | |
344 | } | |
345 | putint(inttotal, INTSROW + 1, INTSCOL, 8); | |
82c646ae SL |
346 | Z(ncs_goodhits); Z(ncs_badhits); Z(ncs_miss); |
347 | Z(ncs_long); Z(ncs_pass2); Z(ncs_2passes); | |
348 | s.nchcount = nchtotal.ncs_goodhits + nchtotal.ncs_badhits + | |
349 | nchtotal.ncs_miss + nchtotal.ncs_long; | |
350 | if (state == TIME) | |
351 | s1.nchcount = s.nchcount; | |
352 | ||
353 | psiz = 0; | |
354 | f2 = 0.0; | |
e19c46c2 | 355 | for (c = 0; c < CPUSTATES; c++) { |
82c646ae SL |
356 | i = cpuorder[c]; |
357 | f1 = cputime(i); | |
358 | f2 += f1; | |
359 | l = (int) ((f2 + 1.0) / 2.0) - psiz; | |
e19c46c2 KM |
360 | if (c == 0) |
361 | putfloat(f1, GRAPHROW, GRAPHCOL + 1, 5, 1, 0); | |
362 | else | |
363 | putfloat(f1, GRAPHROW, GRAPHCOL + 12 * c, | |
364 | 5, 1, 0); | |
3bc5a770 | 365 | move(GRAPHROW + 2, psiz); |
82c646ae SL |
366 | psiz += l; |
367 | while (l-- > 0) | |
368 | addch(cpuchar[c]); | |
369 | } | |
3bc5a770 KM |
370 | |
371 | putint(ucount(), STATROW, STATCOL, 3); | |
372 | putfloat(avenrun[0], STATROW, STATCOL + 17, 6, 2, 0); | |
373 | putfloat(avenrun[1], STATROW, STATCOL + 23, 6, 2, 0); | |
374 | putfloat(avenrun[2], STATROW, STATCOL + 29, 6, 2, 0); | |
375 | mvaddstr(STATROW, STATCOL + 53, buf); | |
376 | putint(total.t_arm/2, MEMROW + 2, MEMCOL + 4, 5); | |
377 | putint(total.t_armtxt/2, MEMROW + 2, MEMCOL + 9, 5); | |
378 | putint(total.t_avm/2, MEMROW + 2, MEMCOL + 14, 5); | |
379 | putint(total.t_avmtxt/2, MEMROW + 2, MEMCOL + 19, 5); | |
380 | putint(total.t_rm/2, MEMROW + 3, MEMCOL + 4, 5); | |
381 | putint(total.t_rmtxt/2, MEMROW + 3, MEMCOL + 9, 5); | |
382 | putint(total.t_vm/2, MEMROW + 3, MEMCOL + 14, 5); | |
383 | putint(total.t_vmtxt/2, MEMROW + 3, MEMCOL + 19, 5); | |
384 | putint(total.t_free/2, MEMROW + 2, MEMCOL + 26, 5); | |
385 | putint(total.t_rq, PROCSROW + 1, PROCSCOL + 5, 3); | |
386 | putint(total.t_pw, PROCSROW + 1, PROCSCOL + 8, 3); | |
387 | putint(total.t_dw, PROCSROW + 1, PROCSCOL + 11, 3); | |
388 | putint(total.t_sl, PROCSROW + 1, PROCSCOL + 14, 3); | |
389 | putint(total.t_sw, PROCSROW + 1, PROCSCOL + 17, 3); | |
390 | putrate(rate.v_swtch, oldrate.v_swtch, | |
391 | GENSTATROW, GENSTATCOL, 7); | |
392 | putrate(rate.v_trap, oldrate.v_trap, | |
393 | GENSTATROW + 1, GENSTATCOL, 7); | |
394 | putrate(rate.v_syscall, oldrate.v_syscall, | |
395 | GENSTATROW + 2, GENSTATCOL, 7); | |
396 | putrate(rate.v_intr, oldrate.v_intr, | |
397 | GENSTATROW + 3, GENSTATCOL, 7); | |
398 | putrate(rate.v_pdma, oldrate.v_pdma, | |
399 | GENSTATROW + 4, GENSTATCOL, 7); | |
400 | putrate(rate.v_faults, oldrate.v_faults, | |
401 | GENSTATROW + 5, GENSTATCOL, 7); | |
402 | putrate(rate.v_scan, oldrate.v_scan, | |
403 | GENSTATROW + 6, GENSTATCOL, 7); | |
404 | putrate(rate.v_rev, oldrate.v_rev, | |
405 | GENSTATROW + 7, GENSTATCOL, 7); | |
406 | putrate(rate.v_pgin, oldrate.v_pgin, PAGEROW + 2, | |
407 | PAGECOL + 5, 5); | |
408 | putrate(rate.v_pgout, oldrate.v_pgout, PAGEROW + 2, | |
409 | PAGECOL + 10, 5); | |
410 | putrate(rate.v_swpin, oldrate.v_swpin, PAGEROW + 2, | |
411 | PAGECOL + 15, 5); | |
412 | putrate(rate.v_swpout, oldrate.v_swpout, PAGEROW + 2, | |
413 | PAGECOL + 20, 5); | |
414 | putrate(rate.v_pgpgin, oldrate.v_pgpgin, PAGEROW + 3, | |
415 | PAGECOL + 5, 5); | |
416 | putrate(rate.v_pgpgout, oldrate.v_pgpgout, PAGEROW + 3, | |
417 | PAGECOL + 10, 5); | |
418 | putrate(rate.v_pswpin, oldrate.v_pswpin, PAGEROW + 3, | |
419 | PAGECOL + 15, 5); | |
420 | putrate(rate.v_pswpout, oldrate.v_pswpout, PAGEROW + 3, | |
421 | PAGECOL + 20, 5); | |
422 | putrate(rate.v_pgrec, oldrate.v_pgrec, PAGEROW + 6, PAGECOL, 3); | |
423 | putrate(rate.v_intrans, oldrate.v_intrans, PAGEROW + 6, | |
424 | PAGECOL + 4, 2); | |
425 | putrate(rate.v_xsfrec, oldrate.v_xsfrec, PAGEROW + 6, | |
426 | PAGECOL + 7, 3); | |
427 | putrate(rate.v_xifrec, oldrate.v_xifrec, PAGEROW + 6, | |
428 | PAGECOL + 11, 3); | |
429 | putrate(rate.v_pgfrec, oldrate.v_pgfrec, PAGEROW + 6, | |
430 | PAGECOL + 15, 3); | |
431 | putrate(rate.v_dfree, oldrate.v_dfree, PAGEROW + 6, | |
432 | PAGECOL + 19, 3); | |
433 | putrate(rate.v_seqfree, oldrate.v_seqfree, PAGEROW + 6, | |
434 | PAGECOL + 23, 3); | |
435 | putrate(rate.v_zfod, oldrate.v_zfod, PAGEROW + 8, PAGECOL, 8); | |
436 | putrate(rate.v_nzfod, oldrate.v_nzfod, PAGEROW + 9, PAGECOL, 8); | |
437 | putrate(rate.v_exfod, oldrate.v_exfod, PAGEROW + 8, | |
438 | PAGECOL + 14, 8); | |
439 | putrate(rate.v_nexfod, oldrate.v_nexfod, PAGEROW + 9, | |
440 | PAGECOL + 14, 8); | |
82c646ae SL |
441 | putfloat ( |
442 | rate.v_nzfod == 0 ? | |
443 | 0.0 | |
444 | : state != RUN ? | |
445 | ( 100.0 * rate.v_zfod / rate.v_nzfod ) | |
446 | : rate.v_nzfod == oldrate.v_nzfod ? | |
447 | 0.0 | |
448 | : | |
449 | ( 100.0 * (rate.v_zfod-oldrate.v_zfod) | |
450 | / (rate.v_nzfod-oldrate.v_nzfod) ) | |
3bc5a770 KM |
451 | , PAGEROW + 10 |
452 | , PAGECOL | |
82c646ae SL |
453 | , 8 |
454 | , 2 | |
455 | , 1 | |
456 | ); | |
457 | putfloat ( | |
458 | rate.v_nexfod == 0 ? | |
459 | 0.0 | |
460 | : state != RUN ? | |
461 | ( 100.0 * rate.v_exfod / rate.v_nexfod ) | |
462 | : rate.v_nexfod == oldrate.v_nexfod ? | |
463 | 0.0 | |
464 | : | |
465 | ( 100.0 * (rate.v_exfod-oldrate.v_exfod) | |
466 | / (rate.v_nexfod-oldrate.v_nexfod) ) | |
3bc5a770 KM |
467 | , PAGEROW + 10 |
468 | , PAGECOL + 14 | |
82c646ae SL |
469 | , 8 |
470 | , 2 | |
471 | , 1 | |
472 | ); | |
473 | c = 1; | |
474 | for (i = 0; i < DK_NDRIVE; i++) | |
475 | if (dr_state[i] == SOME) | |
3bc5a770 | 476 | dinfo(i, c++); |
82c646ae | 477 | |
3bc5a770 KM |
478 | putint(s.nchcount, NAMEIROW + 2, NAMEICOL, 9); |
479 | putint(nchtotal.ncs_goodhits, NAMEIROW + 2, NAMEICOL + 9, 9); | |
82c646ae SL |
480 | #define nz(x) ((x) ? (x) : 1) |
481 | putfloat(nchtotal.ncs_goodhits * 100.0 / nz(s.nchcount), | |
3bc5a770 KM |
482 | NAMEIROW + 2, NAMEICOL + 19, 4, 0, 1); |
483 | putint(nchtotal.ncs_pass2, NAMEIROW + 2, NAMEICOL + 23, 9); | |
82c646ae | 484 | putfloat(nchtotal.ncs_pass2 * 100.0 / nz(s.nchcount), |
3bc5a770 | 485 | NAMEIROW + 2, NAMEICOL + 34, 4, 0, 1); |
82c646ae SL |
486 | #undef nz |
487 | move(LINES-1,0); | |
488 | refresh(); | |
489 | waittty(delay); | |
490 | } | |
269ebe33 KM |
491 | clear(); |
492 | mvprintw(2, 10, "THE SYSTEM CLOCK HAS DIED!"); | |
493 | refresh(); | |
494 | sleep(5); | |
495 | finish(); | |
82c646ae SL |
496 | } |
497 | ||
498 | /* calculate number of users on the system */ | |
499 | ucount() | |
500 | { | |
501 | register int nusers = 0; | |
502 | ||
503 | while (read(ut, &utmp, sizeof(utmp))) | |
504 | if (utmp.ut_name[0] != '\0') | |
505 | nusers++; | |
506 | ||
507 | lseek(ut, 0L, 0); | |
508 | return(nusers); | |
509 | } | |
510 | ||
511 | float | |
512 | cputime(indx) | |
513 | int indx; | |
514 | { | |
515 | double t; | |
516 | register i; | |
517 | ||
518 | t = 0; | |
e19c46c2 | 519 | for (i = 0; i < CPUSTATES; i++) |
82c646ae SL |
520 | t += s.time[i]; |
521 | if (t == 0.0) | |
522 | t = 1.0; | |
523 | return(s.time[indx] * 100.0 / t); | |
524 | } | |
525 | ||
526 | void | |
527 | finish() | |
528 | { | |
529 | mvcur(0, COLS-1, LINES-1, 0); | |
530 | endwin(); | |
531 | exit(0); | |
532 | ||
533 | } | |
534 | ||
535 | waittty(period) | |
536 | { | |
537 | int inbits = 1 << 0; | |
538 | struct timeval tv; | |
539 | ||
540 | tv.tv_usec = 0; | |
541 | tv.tv_sec = period; | |
542 | ||
543 | select(32, &inbits, 0, 0, &tv); | |
544 | if (inbits & (1 << 0)) | |
545 | docmd(); | |
546 | } | |
547 | ||
548 | void | |
549 | docmd() | |
550 | { | |
551 | int c; | |
552 | static enum state oldstate; | |
553 | ||
554 | c = getchar() & 0177; | |
555 | ||
556 | switch ( c ) { | |
557 | case '1': case '2': case '3': case '4': | |
558 | case '5': case '6': case '7': case '8': case '9': | |
559 | delay = c - '0'; | |
560 | state = TIME; | |
561 | break; | |
562 | case 'r': | |
3bc5a770 | 563 | copyinfo(&s2, &s1); |
82c646ae SL |
564 | state = RUN; |
565 | break; | |
566 | case 'b': | |
567 | state = BOOT; | |
3bc5a770 | 568 | copyinfo(&z, &s1); |
82c646ae SL |
569 | break; |
570 | case 't': | |
571 | state = TIME; | |
572 | break; | |
573 | case 'l': case 'l'&037: | |
574 | layout(); | |
575 | if (state == STOP) | |
576 | state = oldstate; | |
577 | break; | |
578 | case 'z': | |
579 | if (state == RUN) | |
580 | getinfo(&s1, RUN); | |
581 | else if (state == STOP) | |
582 | state = oldstate; | |
583 | break; | |
584 | case 'q': case 0177: | |
585 | finish(); | |
586 | /* NOTREACHED */ | |
587 | case ' ': case '0': | |
588 | if (state == STOP) { | |
589 | state = oldstate; | |
590 | break; | |
591 | } | |
592 | oldstate = state; | |
593 | state = STOP; | |
594 | break; | |
595 | ||
596 | default: | |
597 | if (state == STOP) | |
598 | state = oldstate; | |
599 | } | |
600 | } | |
601 | ||
602 | layout() | |
603 | { | |
604 | register i, j; | |
605 | ||
606 | clear(); | |
3bc5a770 KM |
607 | mvprintw(STATROW, STATCOL + 4, "users Load"); |
608 | mvprintw(MEMROW, MEMCOL, "Mem REAL VIRTUAL "); | |
609 | mvprintw(MEMROW + 1, MEMCOL, " Tot Text Tot Text"); | |
610 | mvprintw(MEMROW + 2, MEMCOL, "Act"); | |
611 | mvprintw(MEMROW + 3, MEMCOL, "All"); | |
612 | ||
613 | mvprintw(MEMROW + 1, MEMCOL + 27, "Free"); | |
614 | ||
615 | mvprintw(PAGEROW, PAGECOL, " PAGING SWAPING "); | |
616 | mvprintw(PAGEROW + 1, PAGECOL, " in out in out "); | |
617 | mvprintw(PAGEROW + 2, PAGECOL, "count"); | |
618 | mvprintw(PAGEROW + 3, PAGECOL, "pages"); | |
619 | ||
620 | mvprintw(INTSROW, INTSCOL, " Interrupts"); | |
621 | mvprintw(INTSROW + 1, INTSCOL + 9, "total"); | |
622 | ||
623 | mvprintw(GENSTATROW, GENSTATCOL + 8, "Csw"); | |
624 | mvprintw(GENSTATROW + 1, GENSTATCOL + 8, "Trp"); | |
625 | mvprintw(GENSTATROW + 2, GENSTATCOL + 8, "Sys"); | |
626 | mvprintw(GENSTATROW + 3, GENSTATCOL + 8, "Int"); | |
627 | mvprintw(GENSTATROW + 4, GENSTATCOL + 8, "Pdm"); | |
628 | mvprintw(GENSTATROW + 5, GENSTATCOL + 8, "Flt"); | |
629 | mvprintw(GENSTATROW + 6, GENSTATCOL + 8, "Scn"); | |
630 | mvprintw(GENSTATROW + 7, GENSTATCOL + 8, "Rev"); | |
631 | ||
632 | mvprintw(PAGEROW + 5, PAGECOL, "Rec It F/S F/F RFL Fre SFr"); | |
633 | ||
634 | mvprintw(PAGEROW + 8, PAGECOL + 9, " zf"); | |
635 | mvprintw(PAGEROW + 9, PAGECOL + 9, "nzf"); | |
636 | mvprintw(PAGEROW + 10, PAGECOL + 9, "%%zf"); | |
637 | mvprintw(PAGEROW + 8, PAGECOL + 23, " xf"); | |
638 | mvprintw(PAGEROW + 9, PAGECOL + 23, "nxf"); | |
639 | mvprintw(PAGEROW + 10, PAGECOL + 23, "%%xf"); | |
640 | ||
641 | mvprintw(GRAPHROW, GRAPHCOL, | |
e19c46c2 | 642 | " . %% Sys . %% User . %% Nice . %% Idle"); |
3bc5a770 KM |
643 | mvprintw(PROCSROW, PROCSCOL, "Procs r p d s w"); |
644 | mvprintw(GRAPHROW + 1, GRAPHCOL, | |
645 | "| | | | | | | | | | |"); | |
646 | ||
647 | mvprintw(NAMEIROW, NAMEICOL, "Namei Sys-cache Proc-cache"); | |
648 | mvprintw(NAMEIROW + 1, NAMEICOL, | |
649 | " Calls hits %% hits %%"); | |
650 | mvprintw(DISKROW, DISKCOL, "Discs"); | |
651 | mvprintw(DISKROW + 1, DISKCOL, "seeks"); | |
652 | mvprintw(DISKROW + 2, DISKCOL, "xfers"); | |
653 | mvprintw(DISKROW + 3, DISKCOL, " blks"); | |
654 | mvprintw(DISKROW + 4, DISKCOL, " msps"); | |
82c646ae SL |
655 | j = 0; |
656 | for (i = 0; i < DK_NDRIVE; i++) | |
657 | if (dr_state[i] == SOME) { | |
3bc5a770 KM |
658 | mvprintw(DISKROW, DISKCOL + 5 + 5 * j, |
659 | " %3.3s", dr_name[j]); | |
82c646ae SL |
660 | j++; |
661 | } | |
e19c46c2 KM |
662 | for (i = 0; i < nintr; i++) { |
663 | if (intrloc[i] == 0) | |
664 | continue; | |
665 | mvprintw(intrloc[i], INTSCOL + 9, "%-8.8s", intrname[i]); | |
666 | } | |
82c646ae SL |
667 | } |
668 | ||
669 | putrate(r, or, l, c, w) | |
670 | { | |
671 | if (state != TIME) { | |
672 | if (state == RUN) | |
673 | r -= or; | |
674 | putint((int)((float)r/etime + 0.5), l, c, w); | |
675 | } else | |
676 | putint(r, l, c, w); | |
677 | } | |
678 | ||
679 | putint(n, l, c, w) | |
680 | { | |
681 | char b[128]; | |
682 | ||
683 | move(l, c); | |
684 | if (n == 0) { | |
685 | while (w-- > 0) | |
686 | addch(' '); | |
687 | return; | |
688 | } | |
689 | sprintf(b, "%*d", w, n); | |
690 | if (strlen(b) > w) { | |
691 | while (w-- > 0) | |
692 | addch('*'); | |
693 | return; | |
694 | } | |
695 | addstr(b); | |
696 | } | |
697 | ||
698 | putfloat(f, l, c, w, d, nz) | |
699 | float f; | |
700 | { | |
701 | char b[128]; | |
702 | ||
703 | move(l, c); | |
704 | if (nz && f == 0.0) { | |
705 | while (w-- > 0) | |
706 | addch(' '); | |
707 | return; | |
708 | } | |
709 | sprintf(b, "%*.*f", w, d, f); | |
710 | if (strlen(b) > w) { | |
711 | while (w-- > 0) | |
712 | addch('*'); | |
713 | return; | |
714 | } | |
715 | addstr(b); | |
716 | } | |
717 | ||
718 | /* | |
719 | * Read the drive names out of kmem. | |
720 | * ARGH ARGH ARGH ARGH !!!!!!!!!!!! | |
721 | */ | |
722 | ||
723 | #define steal(where, var) lseek(kmem, where, 0); read(kmem, &var, sizeof var); | |
724 | read_names() | |
725 | { | |
726 | struct mba_device mdev; | |
727 | register struct mba_device *mp; | |
728 | struct mba_driver mdrv; | |
729 | short two_char; | |
730 | char *cp = (char *) &two_char; | |
731 | struct uba_device udev, *up; | |
732 | struct uba_driver udrv; | |
733 | ||
734 | mp = (struct mba_device *) name[X_MBDINIT].n_value; | |
735 | up = (struct uba_device *) name[X_UBDINIT].n_value; | |
736 | if (up == 0) | |
737 | { | |
738 | fprintf(stderr, "vsta: Disk init info not in namelist\n"); | |
739 | exit(1); | |
740 | } | |
741 | if (mp) | |
742 | while(1) | |
743 | { | |
744 | steal(mp++, mdev); | |
745 | if (mdev.mi_driver == 0) | |
746 | break; | |
747 | if (mdev.mi_dk < 0 || mdev.mi_alive == 0) | |
748 | continue; | |
749 | steal(mdev.mi_driver, mdrv); | |
750 | steal(mdrv.md_dname, two_char); | |
751 | sprintf(dr_name[mdev.mi_dk], "%c%c%d", cp[0], cp[1], mdev.mi_unit); | |
752 | } | |
753 | while(1) | |
754 | { | |
755 | steal(up++, udev); | |
756 | if (udev.ui_driver == 0) | |
757 | break; | |
758 | if (udev.ui_dk < 0 || udev.ui_alive == 0) | |
759 | continue; | |
760 | steal(udev.ui_driver, udrv); | |
761 | steal(udrv.ud_dname, two_char); | |
762 | sprintf(dr_name[udev.ui_dk], "%c%c%d", cp[0], cp[1], udev.ui_unit); | |
763 | } | |
764 | } | |
765 | ||
766 | getinfo(s, st) | |
767 | struct Info *s; | |
768 | enum state st; | |
769 | { | |
770 | lseek(kmem, (long)name[X_CPTIME].n_value,0); | |
771 | read(kmem, s->time, sizeof s->time); | |
772 | if (st != TIME) { | |
773 | lseek(kmem, (long)name[X_SUM].n_value, 0); | |
774 | read(kmem, &s->Rate, sizeof &s->Rate); | |
775 | } else { | |
776 | lseek(kmem, (long)name[X_RATE].n_value,0); | |
777 | read(kmem, &s->Rate, sizeof s->Rate); | |
778 | } | |
779 | lseek(kmem, (long)name[X_DEFICIT].n_value,0); | |
780 | read(kmem, deficit, sizeof deficit); | |
781 | lseek( kmem, (long)name[X_AVENRUN].n_value, 0 ); | |
782 | read( kmem, avenrun, sizeof(avenrun) ); | |
783 | lseek(kmem, (long)name[X_TOTAL].n_value,0); | |
784 | read(kmem, &s->Total, sizeof s->Total); | |
785 | lseek(kmem, (long)name[X_DK_BUSY].n_value, 0); | |
786 | read(kmem, &s->dk_busy, sizeof s->dk_busy); | |
787 | lseek(kmem, (long)name[X_DK_TIME].n_value, 0); | |
788 | read(kmem, s->dk_time, sizeof s->dk_time); | |
789 | lseek(kmem, (long)name[X_DK_XFER].n_value, 0); | |
790 | read(kmem, s->dk_xfer, sizeof s->dk_xfer); | |
791 | lseek(kmem, (long)name[X_DK_WDS].n_value, 0); | |
792 | read(kmem, s->dk_wds, sizeof s->dk_wds); | |
793 | lseek(kmem, (long)name[X_TK_NIN].n_value, 0); | |
794 | read(kmem, &s->tk_nin, sizeof s->tk_nin); | |
795 | lseek(kmem, (long)name[X_TK_NOUT].n_value, 0); | |
796 | read(kmem, &s->tk_nout, sizeof s->tk_nout); | |
797 | lseek(kmem, (long)name[X_DK_SEEK].n_value, 0); | |
798 | read(kmem, s->dk_seek, sizeof s->dk_seek); | |
799 | lseek(kmem, (long)name[X_NCHSTATS].n_value, 0); | |
800 | read(kmem, &s->nchstats, sizeof s->nchstats); | |
3bc5a770 KM |
801 | lseek(kmem, (long)name[X_INTRCNT].n_value, 0); |
802 | read(kmem, s->intrcnt, nintr * sizeof (long)); | |
803 | } | |
804 | ||
805 | allocinfo(s) | |
806 | struct Info *s; | |
807 | { | |
808 | ||
809 | s->intrcnt = (long *) malloc(nintr * sizeof(long)); | |
810 | if (s->intrcnt == NULL) { | |
811 | fprintf(stderr, "vsta: out of memory\n"); | |
812 | exit(2); | |
813 | } | |
814 | } | |
815 | ||
816 | copyinfo(from, to) | |
817 | struct Info *from, *to; | |
818 | { | |
819 | register int i, *fip = from->intrcnt, *tip = to->intrcnt; | |
820 | ||
821 | *to = *from; | |
822 | to->intrcnt = tip; | |
823 | for (i = 0; i < nintr; i++) | |
824 | *tip++ = *fip++; | |
82c646ae SL |
825 | } |
826 | ||
827 | dinfo(dn, c) | |
828 | { | |
829 | double words, atime, itime, xtime; | |
830 | ||
3bc5a770 | 831 | c = DISKCOL + c * 5; |
82c646ae SL |
832 | atime = s.dk_time[dn]; |
833 | atime /= 60.0; | |
834 | words = s.dk_wds[dn]*32.0; /* number of words transferred */ | |
835 | xtime = s.dk_mspw[dn]*words; /* transfer time */ | |
836 | itime = atime - xtime; /* time not transferring */ | |
837 | if (xtime < 0) | |
838 | itime += xtime, xtime = 0; | |
839 | if (itime < 0) | |
840 | xtime += itime, itime = 0; | |
3bc5a770 KM |
841 | putint((int)((float)s.dk_seek[dn]/etime+0.5), DISKROW + 1, c, 5); |
842 | putint((int)((float)s.dk_xfer[dn]/etime+0.5), DISKROW + 2, c, 5); | |
843 | putint((int)(words/etime/512.0 + 0.5), DISKROW + 3, c, 5); | |
82c646ae | 844 | if (s.dk_seek[dn]) |
3bc5a770 | 845 | putfloat(itime*1000.0/s.dk_seek[dn], DISKROW + 4, c, 5, 1, 1); |
82c646ae | 846 | else |
3bc5a770 | 847 | putint(0, DISKROW + 4, c, 5); |
82c646ae | 848 | } |