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