install with -s
[unix-history] / usr / src / usr.bin / systat / vmstat.c
CommitLineData
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
8char 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
14static 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
73char *fread();
74long time();
75float cputime();
76char *asctime();
77struct tm *localtime();
78
79void finish();
80void docmd();
81struct utmp utmp;
82
83struct 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
139struct 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
171int ut;
172int kmem;
173int deficit;
174double avenrun[3];
175long c;
176char buf[26];
177time_t t;
178time_t bootime;
179double etime;
180int secs;
3bc5a770 181int delay = 5;
82c646ae
SL
182int hz;
183int phz;
184float hertz;
3bc5a770 185int nintr;
e19c46c2
KM
186long *intrloc;
187char **intrname;
82c646ae
SL
188
189char dr_name[DK_NDRIVE][10];
190enum state { BOOT, TIME, RUN, STOP } state = TIME;
191enum { NONE, SOME } dr_state[DK_NDRIVE];
192
193char cpuchar[CPUSTATES] = { '=' , '>', '-', ' ' };
194char cpuorder[CPUSTATES] = { CP_SYS, CP_USER, CP_NICE, CP_IDLE };
195
196main(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 */
499ucount()
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
511float
512cputime(indx)
513int 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
526void
527finish()
528{
529 mvcur(0, COLS-1, LINES-1, 0);
530 endwin();
531 exit(0);
532
533}
534
535waittty(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
548void
549docmd()
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
602layout()
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
669putrate(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
679putint(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
698putfloat(f, l, c, w, d, nz)
699float 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);
724read_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
766getinfo(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
805allocinfo(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
816copyinfo(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
827dinfo(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}