share subr.c and string.c with pi/pc
[unix-history] / usr / src / usr.bin / systat / vmstat.c
CommitLineData
82c646ae 1#ifndef lint
e19c46c2 2static 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
56char *fread();
57long time();
58float cputime();
59char *asctime();
60struct tm *localtime();
61
62void finish();
63void docmd();
64struct utmp utmp;
65
66struct 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
122struct 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
154int ut;
155int kmem;
156int deficit;
157double avenrun[3];
158long c;
159char buf[26];
160time_t t;
161time_t bootime;
162double etime;
163int secs;
3bc5a770 164int delay = 5;
82c646ae
SL
165int hz;
166int phz;
167float hertz;
3bc5a770 168int nintr;
e19c46c2
KM
169long *intrloc;
170char **intrname;
82c646ae
SL
171
172char dr_name[DK_NDRIVE][10];
173enum state { BOOT, TIME, RUN, STOP } state = TIME;
174enum { NONE, SOME } dr_state[DK_NDRIVE];
175
176char cpuchar[CPUSTATES] = { '=' , '>', '-', ' ' };
177char cpuorder[CPUSTATES] = { CP_SYS, CP_USER, CP_NICE, CP_IDLE };
178
179main(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 */
476ucount()
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
488float
489cputime(indx)
490int 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
503void
504finish()
505{
506 mvcur(0, COLS-1, LINES-1, 0);
507 endwin();
508 exit(0);
509
510}
511
512waittty(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
525void
526docmd()
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
579layout()
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
646putrate(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
656putint(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
675putfloat(f, l, c, w, d, nz)
676float 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);
701read_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
743getinfo(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
782allocinfo(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
793copyinfo(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
804dinfo(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}