keep npartitions independent of byte order
[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
69c023f1 8static char sccsid[] = "@(#)vmstat.c 5.7 (Berkeley) %G%";
f42904bc 9#endif not lint
82c646ae
SL
10
11/*
12 * Cursed vmstat -- from Robert Elz.
13 */
1cadf944
SL
14
15#include "systat.h"
16
82c646ae
SL
17#include <ctype.h>
18#include <utmp.h>
1cadf944 19
82c646ae 20#include <sys/vm.h>
82c646ae 21#include <sys/buf.h>
82c646ae
SL
22#include <sys/stat.h>
23#include <sys/dir.h>
24#include <sys/user.h>
25#include <sys/proc.h>
3bc5a770
KM
26#include <sys/namei.h>
27
8d7d38c3 28#include <machine/pte.h>
82c646ae 29
1cadf944
SL
30static int ut;
31
32WINDOW *
33openkre()
34{
35
36 ut = open("/etc/utmp", O_RDONLY);
37 if (ut < 0)
38 error("No utmp");
39 return (stdscr);
40}
41
42closekre(w)
43 WINDOW *w;
44{
45
46 (void) close(ut);
47 if (w == NULL)
48 return;
49 wclear(w);
50 wrefresh(w);
51}
269ebe33 52
1cadf944
SL
53long time();
54float cputime();
1cadf944 55struct utmp utmp;
82c646ae 56
1cadf944 57static struct nlist name[] = {
82c646ae 58 { "_cp_time" },
1cadf944 59#define X_CPTIME 0
82c646ae 60 { "_rate" },
1cadf944 61#define X_RATE 1
82c646ae 62 { "_total" },
1cadf944 63#define X_TOTAL 2
82c646ae 64 { "_proc" },
1cadf944 65#define X_PROC 3
82c646ae 66 { "_nproc" },
1cadf944 67#define X_NPROC 4
82c646ae 68 { "_sum" },
1cadf944 69#define X_SUM 5
82c646ae 70 { "_dk_busy" },
1cadf944 71#define X_DK_BUSY 6
82c646ae 72 { "_dk_time" },
1cadf944 73#define X_DK_TIME 7
82c646ae 74 { "_dk_xfer" },
1cadf944 75#define X_DK_XFER 8
82c646ae 76 { "_dk_wds" },
1cadf944 77#define X_DK_WDS 9
82c646ae 78 { "_tk_nin" },
1cadf944 79#define X_TK_NIN 10
82c646ae 80 { "_tk_nout" },
1cadf944 81#define X_TK_NOUT 11
82c646ae 82 { "_dk_seek" },
1cadf944 83#define X_DK_SEEK 12
82c646ae 84 { "_nchstats" },
1cadf944 85#define X_NCHSTATS 13
3bc5a770 86 { "_intrnames" },
1cadf944 87#define X_INTRNAMES 14
3bc5a770 88 { "_eintrnames" },
1cadf944 89#define X_EINTRNAMES 15
3bc5a770 90 { "_intrcnt" },
1cadf944 91#define X_INTRCNT 16
3bc5a770 92 { "_eintrcnt" },
1cadf944 93#define X_EINTRCNT 17
6ae1408e 94 { "" },
82c646ae
SL
95};
96
1cadf944
SL
97static struct Info {
98 long time[CPUSTATES];
99 struct vmmeter Rate;
100 struct vmtotal Total;
101 struct vmmeter Sum;
102 struct forkstat Forkstat;
6ae1408e
SL
103 long *dk_time;
104 long *dk_wds;
105 long *dk_seek;
106 long *dk_xfer;
82c646ae
SL
107 int dk_busy;
108 long tk_nin;
109 long tk_nout;
110 struct nchstats nchstats;
111 long nchcount;
3bc5a770 112 long *intrcnt;
82c646ae
SL
113} s, s1, s2, z;
114
82c646ae
SL
115#define total s.Total
116#define sum s.Sum
117#define sumold s1.Sum
118#define rate s.Rate
119#define nchtotal s.nchstats
120#define oldnchtotal s1.nchstats
121#define oldrate s1.Rate
82c646ae 122
1cadf944
SL
123static char buf[26];
124static time_t t;
125static double etime;
126static float hertz;
127static int nintr;
128static long *intrloc;
129static char **intrname;
130static int nextintsrow;
82c646ae 131
1cadf944 132static enum state { BOOT, TIME, RUN } state = TIME;
82c646ae 133
1cadf944
SL
134/*
135 * These constants define where the major pieces are laid out
136 */
137#define PROCSROW 13 /* uses 2 rows and 20 cols */
138#define PROCSCOL 0
139#define NAMEIROW 20 /* uses 3 rows and 38 cols */
140#define NAMEICOL 0
141#define GRAPHROW 16 /* uses 3 rows and 51 cols */
142#define GRAPHCOL 0
143#define GENSTATROW 14 /* uses 8 rows and 11 cols */
144#define GENSTATCOL 51
145#define INTSROW 2 /* uses all rows to bottom and 17 cols */
146#define INTSCOL 63
147#define STATROW 0 /* uses 1 row and 68 cols */
148#define STATCOL 2
149#define PAGEROW 2 /* uses 11 rows and 26 cols */
150#define PAGECOL 36
151#define MEMROW 2 /* uses 4 rows and 31 cols */
152#define MEMCOL 0
153#define DISKROW 7 /* uses 5 rows and 35 cols */
154#define DISKCOL 0
82c646ae 155
1cadf944
SL
156initkre()
157{
158 char *intrnamebuf, *cp;
159 int i;
c0b7e584 160 static int once = 0;
82c646ae 161
82c646ae 162 if (name[0].n_type == 0) {
1cadf944
SL
163 nlist("/vmunix",name);
164 if (name[0].n_type == 0) {
165 error("No namelist");
c0b7e584 166 return(0);
1cadf944 167 }
82c646ae 168 }
82c646ae 169 hertz = phz ? phz : hz;
c0b7e584
JB
170 if (! dkinit())
171 return(0);
172 if (dk_ndrive && !once) {
6ae1408e
SL
173#define allocate(e, t) \
174 s./**/e = (t *)calloc(dk_ndrive, sizeof (t)); \
175 s1./**/e = (t *)calloc(dk_ndrive, sizeof (t)); \
176 s2./**/e = (t *)calloc(dk_ndrive, sizeof (t)); \
177 z./**/e = (t *)calloc(dk_ndrive, sizeof (t));
178 allocate(dk_time, long);
179 allocate(dk_wds, long);
180 allocate(dk_seek, long);
181 allocate(dk_xfer, long);
c0b7e584 182 once = 1;
6ae1408e 183#undef allocate
1cadf944 184 }
1cadf944
SL
185 if (nintr == 0) {
186 nintr = (name[X_EINTRCNT].n_value -
187 name[X_INTRCNT].n_value) / sizeof (long);
188 intrloc = (long *) calloc(nintr, sizeof (long));
189 intrname = (char **) calloc(nintr, sizeof (long));
190 intrnamebuf = malloc(name[X_EINTRNAMES].n_value -
191 name[X_INTRNAMES].n_value);
192 if (intrnamebuf == 0 || intrname == 0 || intrloc == 0) {
193 error("Out of memory\n");
c0b7e584
JB
194 if (intrnamebuf)
195 free(intrnamebuf);
196 if (intrname)
197 free(intrname);
198 if (intrloc)
199 free(intrloc);
200 nintr = 0;
201 return(0);
82c646ae 202 }
1cadf944
SL
203 lseek(kmem, (long)name[X_INTRNAMES].n_value, L_SET);
204 read(kmem, intrnamebuf, name[X_EINTRNAMES].n_value -
205 name[X_INTRNAMES].n_value);
206 for (cp = intrnamebuf, i = 0; i < nintr; i++) {
207 intrname[i] = cp;
208 cp += strlen(cp) + 1;
3bc5a770 209 }
1cadf944
SL
210 nextintsrow = INTSROW + 2;
211 allocinfo(&s);
212 allocinfo(&s1);
213 allocinfo(&s2);
214 allocinfo(&z);
82c646ae 215 }
1cadf944
SL
216 getinfo(&s2, RUN);
217 copyinfo(&s2, &s1);
c0b7e584 218 return(1);
82c646ae
SL
219}
220
1cadf944 221fetchkre()
82c646ae 222{
1cadf944 223 time_t now;
82c646ae 224
1cadf944
SL
225 time(&now);
226 strcpy(buf, ctime(&now));
227 buf[16] = '\0';
228 getinfo(&s, state);
82c646ae
SL
229}
230
6ae1408e
SL
231#define MAXDRIVES 6 /* max # to display */
232
1cadf944 233labelkre()
82c646ae
SL
234{
235 register i, j;
236
237 clear();
3bc5a770 238 mvprintw(STATROW, STATCOL + 4, "users Load");
69c023f1
SL
239 mvprintw(MEMROW, MEMCOL, "Mem REAL VIRTUAL");
240 mvprintw(MEMROW + 1, MEMCOL, " Tot Text Tot Text");
3bc5a770
KM
241 mvprintw(MEMROW + 2, MEMCOL, "Act");
242 mvprintw(MEMROW + 3, MEMCOL, "All");
243
69c023f1 244 mvprintw(MEMROW + 1, MEMCOL + 28, "Free");
3bc5a770
KM
245
246 mvprintw(PAGEROW, PAGECOL, " PAGING SWAPING ");
247 mvprintw(PAGEROW + 1, PAGECOL, " in out in out ");
248 mvprintw(PAGEROW + 2, PAGECOL, "count");
249 mvprintw(PAGEROW + 3, PAGECOL, "pages");
250
251 mvprintw(INTSROW, INTSCOL, " Interrupts");
252 mvprintw(INTSROW + 1, INTSCOL + 9, "total");
253
254 mvprintw(GENSTATROW, GENSTATCOL + 8, "Csw");
255 mvprintw(GENSTATROW + 1, GENSTATCOL + 8, "Trp");
256 mvprintw(GENSTATROW + 2, GENSTATCOL + 8, "Sys");
257 mvprintw(GENSTATROW + 3, GENSTATCOL + 8, "Int");
258 mvprintw(GENSTATROW + 4, GENSTATCOL + 8, "Pdm");
259 mvprintw(GENSTATROW + 5, GENSTATCOL + 8, "Flt");
260 mvprintw(GENSTATROW + 6, GENSTATCOL + 8, "Scn");
261 mvprintw(GENSTATROW + 7, GENSTATCOL + 8, "Rev");
262
263 mvprintw(PAGEROW + 5, PAGECOL, "Rec It F/S F/F RFL Fre SFr");
264
265 mvprintw(PAGEROW + 8, PAGECOL + 9, " zf");
266 mvprintw(PAGEROW + 9, PAGECOL + 9, "nzf");
267 mvprintw(PAGEROW + 10, PAGECOL + 9, "%%zf");
268 mvprintw(PAGEROW + 8, PAGECOL + 23, " xf");
269 mvprintw(PAGEROW + 9, PAGECOL + 23, "nxf");
270 mvprintw(PAGEROW + 10, PAGECOL + 23, "%%xf");
271
272 mvprintw(GRAPHROW, GRAPHCOL,
e19c46c2 273 " . %% Sys . %% User . %% Nice . %% Idle");
3bc5a770
KM
274 mvprintw(PROCSROW, PROCSCOL, "Procs r p d s w");
275 mvprintw(GRAPHROW + 1, GRAPHCOL,
276 "| | | | | | | | | | |");
277
278 mvprintw(NAMEIROW, NAMEICOL, "Namei Sys-cache Proc-cache");
279 mvprintw(NAMEIROW + 1, NAMEICOL,
280 " Calls hits %% hits %%");
281 mvprintw(DISKROW, DISKCOL, "Discs");
282 mvprintw(DISKROW + 1, DISKCOL, "seeks");
283 mvprintw(DISKROW + 2, DISKCOL, "xfers");
284 mvprintw(DISKROW + 3, DISKCOL, " blks");
285 mvprintw(DISKROW + 4, DISKCOL, " msps");
82c646ae 286 j = 0;
6ae1408e
SL
287 for (i = 0; i < dk_ndrive && j < MAXDRIVES; i++)
288 if (dk_select[i]) {
3bc5a770
KM
289 mvprintw(DISKROW, DISKCOL + 5 + 5 * j,
290 " %3.3s", dr_name[j]);
82c646ae
SL
291 j++;
292 }
e19c46c2
KM
293 for (i = 0; i < nintr; i++) {
294 if (intrloc[i] == 0)
295 continue;
296 mvprintw(intrloc[i], INTSCOL + 9, "%-8.8s", intrname[i]);
297 }
82c646ae
SL
298}
299
1cadf944
SL
300#define X(fld) {t=s.fld[i]; s.fld[i]-=s1.fld[i]; if(state==TIME) s1.fld[i]=t;}
301#define Y(fld) {t = s.fld; s.fld -= s1.fld; if(state == TIME) s1.fld = t;}
302#define Z(fld) {t = s.nchstats.fld; s.nchstats.fld -= s1.nchstats.fld; \
303 if(state == TIME) s1.nchstats.fld = t;}
69c023f1 304#define MAXFAIL 5
1cadf944
SL
305
306static char cpuchar[CPUSTATES] = { '=' , '>', '-', ' ' };
307static char cpuorder[CPUSTATES] = { CP_SYS, CP_USER, CP_NICE, CP_IDLE };
308
309showkre()
310{
311 float f1, f2;
c0b7e584 312 int psiz, inttotal;
1cadf944 313 int i, l, c;
69c023f1 314 static int failcnt = 0;
1cadf944 315
6ae1408e 316 for (i = 0; i < dk_ndrive; i++) {
1cadf944
SL
317 X(dk_xfer); X(dk_seek); X(dk_wds); X(dk_time);
318 }
319 Y(tk_nin); Y(tk_nout);
320 etime = 0;
321 for(i = 0; i < CPUSTATES; i++) {
322 X(time);
323 etime += s.time[i];
324 }
69c023f1
SL
325 if (etime < 5.0) { /* < 5 ticks - ignore this trash */
326 if (failcnt++ >= MAXFAIL) {
327 clear();
328 mvprintw(2, 10, "The alternate system clock has died!");
329 mvprintw(3, 10, "Reverting to ``pigs'' display.");
330 move(CMDLINE, 0);
331 refresh();
332 failcnt = 0;
333 sleep(5);
334 command("pigs");
335 }
1cadf944 336 return;
69c023f1
SL
337 }
338 failcnt = 0;
1cadf944
SL
339 etime /= hertz;
340 inttotal = 0;
341 for (i = 0; i < nintr; i++) {
342 if (s.intrcnt[i] == 0)
343 continue;
344 if (intrloc[i] == 0) {
345 if (nextintsrow == LINES)
346 continue;
347 intrloc[i] = nextintsrow++;
348 mvprintw(intrloc[i], INTSCOL + 9, "%-8.8s",
349 intrname[i]);
350 }
351 X(intrcnt);
352 l = (int)((float)s.intrcnt[i]/etime + 0.5);
353 inttotal += l;
354 putint(l, intrloc[i], INTSCOL, 8);
355 }
356 putint(inttotal, INTSROW + 1, INTSCOL, 8);
357 Z(ncs_goodhits); Z(ncs_badhits); Z(ncs_miss);
358 Z(ncs_long); Z(ncs_pass2); Z(ncs_2passes);
359 s.nchcount = nchtotal.ncs_goodhits + nchtotal.ncs_badhits +
360 nchtotal.ncs_miss + nchtotal.ncs_long;
361 if (state == TIME)
362 s1.nchcount = s.nchcount;
363
364 psiz = 0;
365 f2 = 0.0;
366 for (c = 0; c < CPUSTATES; c++) {
367 i = cpuorder[c];
368 f1 = cputime(i);
369 f2 += f1;
370 l = (int) ((f2 + 1.0) / 2.0) - psiz;
371 if (c == 0)
372 putfloat(f1, GRAPHROW, GRAPHCOL + 1, 5, 1, 0);
373 else
374 putfloat(f1, GRAPHROW, GRAPHCOL + 12 * c,
375 5, 1, 0);
376 move(GRAPHROW + 2, psiz);
377 psiz += l;
378 while (l-- > 0)
379 addch(cpuchar[c]);
380 }
381
382 putint(ucount(), STATROW, STATCOL, 3);
383 putfloat(avenrun[0], STATROW, STATCOL + 17, 6, 2, 0);
384 putfloat(avenrun[1], STATROW, STATCOL + 23, 6, 2, 0);
385 putfloat(avenrun[2], STATROW, STATCOL + 29, 6, 2, 0);
386 mvaddstr(STATROW, STATCOL + 53, buf);
387 putint(total.t_arm/2, MEMROW + 2, MEMCOL + 4, 5);
388 putint(total.t_armtxt/2, MEMROW + 2, MEMCOL + 9, 5);
69c023f1
SL
389 putint(total.t_avm/2, MEMROW + 2, MEMCOL + 14, 6);
390 putint(total.t_avmtxt/2, MEMROW + 2, MEMCOL + 20, 5);
1cadf944
SL
391 putint(total.t_rm/2, MEMROW + 3, MEMCOL + 4, 5);
392 putint(total.t_rmtxt/2, MEMROW + 3, MEMCOL + 9, 5);
69c023f1
SL
393 putint(total.t_vm/2, MEMROW + 3, MEMCOL + 14, 6);
394 putint(total.t_vmtxt/2, MEMROW + 3, MEMCOL + 20, 5);
395 putint(total.t_free/2, MEMROW + 2, MEMCOL + 27, 5);
1cadf944
SL
396 putint(total.t_rq, PROCSROW + 1, PROCSCOL + 5, 3);
397 putint(total.t_pw, PROCSROW + 1, PROCSCOL + 8, 3);
398 putint(total.t_dw, PROCSROW + 1, PROCSCOL + 11, 3);
399 putint(total.t_sl, PROCSROW + 1, PROCSCOL + 14, 3);
400 putint(total.t_sw, PROCSROW + 1, PROCSCOL + 17, 3);
401 putrate(rate.v_swtch, oldrate.v_swtch,
402 GENSTATROW, GENSTATCOL, 7);
403 putrate(rate.v_trap, oldrate.v_trap,
404 GENSTATROW + 1, GENSTATCOL, 7);
405 putrate(rate.v_syscall, oldrate.v_syscall,
406 GENSTATROW + 2, GENSTATCOL, 7);
407 putrate(rate.v_intr, oldrate.v_intr,
408 GENSTATROW + 3, GENSTATCOL, 7);
409 putrate(rate.v_pdma, oldrate.v_pdma,
410 GENSTATROW + 4, GENSTATCOL, 7);
411 putrate(rate.v_faults, oldrate.v_faults,
412 GENSTATROW + 5, GENSTATCOL, 7);
413 putrate(rate.v_scan, oldrate.v_scan,
414 GENSTATROW + 6, GENSTATCOL, 7);
415 putrate(rate.v_rev, oldrate.v_rev,
416 GENSTATROW + 7, GENSTATCOL, 7);
417 putrate(rate.v_pgin, oldrate.v_pgin, PAGEROW + 2,
418 PAGECOL + 5, 5);
419 putrate(rate.v_pgout, oldrate.v_pgout, PAGEROW + 2,
420 PAGECOL + 10, 5);
421 putrate(rate.v_swpin, oldrate.v_swpin, PAGEROW + 2,
422 PAGECOL + 15, 5);
423 putrate(rate.v_swpout, oldrate.v_swpout, PAGEROW + 2,
424 PAGECOL + 20, 5);
425 putrate(rate.v_pgpgin, oldrate.v_pgpgin, PAGEROW + 3,
426 PAGECOL + 5, 5);
427 putrate(rate.v_pgpgout, oldrate.v_pgpgout, PAGEROW + 3,
428 PAGECOL + 10, 5);
429 putrate(rate.v_pswpin, oldrate.v_pswpin, PAGEROW + 3,
430 PAGECOL + 15, 5);
431 putrate(rate.v_pswpout, oldrate.v_pswpout, PAGEROW + 3,
432 PAGECOL + 20, 5);
433 putrate(rate.v_pgrec, oldrate.v_pgrec, PAGEROW + 6, PAGECOL, 3);
434 putrate(rate.v_intrans, oldrate.v_intrans, PAGEROW + 6,
435 PAGECOL + 4, 2);
436 putrate(rate.v_xsfrec, oldrate.v_xsfrec, PAGEROW + 6,
437 PAGECOL + 7, 3);
438 putrate(rate.v_xifrec, oldrate.v_xifrec, PAGEROW + 6,
439 PAGECOL + 11, 3);
440 putrate(rate.v_pgfrec, oldrate.v_pgfrec, PAGEROW + 6,
441 PAGECOL + 15, 3);
442 putrate(rate.v_dfree, oldrate.v_dfree, PAGEROW + 6,
443 PAGECOL + 19, 3);
444 putrate(rate.v_seqfree, oldrate.v_seqfree, PAGEROW + 6,
445 PAGECOL + 23, 3);
446 putrate(rate.v_zfod, oldrate.v_zfod, PAGEROW + 8, PAGECOL, 8);
447 putrate(rate.v_nzfod, oldrate.v_nzfod, PAGEROW + 9, PAGECOL, 8);
448 putrate(rate.v_exfod, oldrate.v_exfod, PAGEROW + 8,
449 PAGECOL + 14, 8);
450 putrate(rate.v_nexfod, oldrate.v_nexfod, PAGEROW + 9,
451 PAGECOL + 14, 8);
452 putfloat (
453 rate.v_nzfod == 0 ?
454 0.0
455 : state != RUN ?
456 ( 100.0 * rate.v_zfod / rate.v_nzfod )
457 : rate.v_nzfod == oldrate.v_nzfod ?
458 0.0
459 :
460 ( 100.0 * (rate.v_zfod-oldrate.v_zfod)
461 / (rate.v_nzfod-oldrate.v_nzfod) )
462 , PAGEROW + 10
463 , PAGECOL
464 , 8
465 , 2
466 , 1
467 );
468 putfloat (
469 rate.v_nexfod == 0 ?
470 0.0
471 : state != RUN ?
472 ( 100.0 * rate.v_exfod / rate.v_nexfod )
473 : rate.v_nexfod == oldrate.v_nexfod ?
474 0.0
475 :
476 ( 100.0 * (rate.v_exfod-oldrate.v_exfod)
477 / (rate.v_nexfod-oldrate.v_nexfod) )
478 , PAGEROW + 10
479 , PAGECOL + 14
480 , 8
481 , 2
482 , 1
483 );
6ae1408e
SL
484 c = 0;
485 for (i = 0; i < dk_ndrive && c < MAXDRIVES; i++)
486 if (dk_select[i])
487 dinfo(i, ++c);
1cadf944
SL
488
489 putint(s.nchcount, NAMEIROW + 2, NAMEICOL, 9);
490 putint(nchtotal.ncs_goodhits, NAMEIROW + 2, NAMEICOL + 9, 9);
491#define nz(x) ((x) ? (x) : 1)
492 putfloat(nchtotal.ncs_goodhits * 100.0 / nz(s.nchcount),
493 NAMEIROW + 2, NAMEICOL + 19, 4, 0, 1);
494 putint(nchtotal.ncs_pass2, NAMEIROW + 2, NAMEICOL + 23, 9);
495 putfloat(nchtotal.ncs_pass2 * 100.0 / nz(s.nchcount),
496 NAMEIROW + 2, NAMEICOL + 34, 4, 0, 1);
497#undef nz
498}
499
500cmdkre(cmd, args)
501 char *cmd, *args;
502{
1cadf944
SL
503
504 if (prefix(cmd, "run")) {
505 copyinfo(&s2, &s1);
506 state = RUN;
507 return (1);
508 }
509 if (prefix(cmd, "boot")) {
510 state = BOOT;
511 copyinfo(&z, &s1);
512 return (1);
513 }
514 if (prefix(cmd, "time")) {
515 state = TIME;
516 return (1);
517 }
518 if (prefix(cmd, "zero")) {
519 if (state == RUN)
520 getinfo(&s1, RUN);
521 return (1);
522 }
6ae1408e 523 return (dkcmd(cmd, args));
1cadf944
SL
524}
525
526/* calculate number of users on the system */
527static
528ucount()
529{
530 register int nusers = 0;
531
532 if (ut < 0)
533 return (0);
534 while (read(ut, &utmp, sizeof(utmp)))
535 if (utmp.ut_name[0] != '\0')
536 nusers++;
537
538 lseek(ut, 0L, L_SET);
539 return (nusers);
540}
541
542static float
543cputime(indx)
544 int indx;
545{
546 double t;
547 register i;
548
549 t = 0;
550 for (i = 0; i < CPUSTATES; i++)
551 t += s.time[i];
552 if (t == 0.0)
553 t = 1.0;
554 return (s.time[indx] * 100.0 / t);
555}
556
557static
82c646ae
SL
558putrate(r, or, l, c, w)
559{
1cadf944 560
82c646ae
SL
561 if (state != TIME) {
562 if (state == RUN)
563 r -= or;
564 putint((int)((float)r/etime + 0.5), l, c, w);
565 } else
566 putint(r, l, c, w);
567}
568
1cadf944 569static
82c646ae
SL
570putint(n, l, c, w)
571{
572 char b[128];
573
574 move(l, c);
575 if (n == 0) {
576 while (w-- > 0)
577 addch(' ');
578 return;
579 }
580 sprintf(b, "%*d", w, n);
581 if (strlen(b) > w) {
582 while (w-- > 0)
583 addch('*');
584 return;
585 }
586 addstr(b);
587}
588
1cadf944 589static
82c646ae 590putfloat(f, l, c, w, d, nz)
1cadf944 591 float f;
82c646ae
SL
592{
593 char b[128];
594
595 move(l, c);
596 if (nz && f == 0.0) {
597 while (w-- > 0)
598 addch(' ');
599 return;
600 }
601 sprintf(b, "%*.*f", w, d, f);
602 if (strlen(b) > w) {
603 while (w-- > 0)
604 addch('*');
605 return;
606 }
607 addstr(b);
608}
609
1cadf944 610static
82c646ae
SL
611getinfo(s, st)
612 struct Info *s;
613 enum state st;
614{
1cadf944
SL
615
616 lseek(kmem, (long)name[X_CPTIME].n_value,L_SET);
82c646ae
SL
617 read(kmem, s->time, sizeof s->time);
618 if (st != TIME) {
1cadf944 619 lseek(kmem, (long)name[X_SUM].n_value, L_SET);
6ae1408e 620 read(kmem, &s->Rate, sizeof s->Rate);
82c646ae 621 } else {
1cadf944 622 lseek(kmem, (long)name[X_RATE].n_value,L_SET);
82c646ae
SL
623 read(kmem, &s->Rate, sizeof s->Rate);
624 }
1cadf944 625 lseek(kmem, (long)name[X_TOTAL].n_value, L_SET);
82c646ae 626 read(kmem, &s->Total, sizeof s->Total);
6ae1408e 627 s->dk_busy = getw(name[X_DK_BUSY].n_value);
1cadf944 628 lseek(kmem, (long)name[X_DK_TIME].n_value, L_SET);
6ae1408e 629 read(kmem, s->dk_time, dk_ndrive * sizeof (long));
1cadf944 630 lseek(kmem, (long)name[X_DK_XFER].n_value, L_SET);
6ae1408e 631 read(kmem, s->dk_xfer, dk_ndrive * sizeof (long));
1cadf944 632 lseek(kmem, (long)name[X_DK_WDS].n_value, L_SET);
6ae1408e 633 read(kmem, s->dk_wds, dk_ndrive * sizeof (long));
1cadf944 634 lseek(kmem, (long)name[X_DK_SEEK].n_value, L_SET);
6ae1408e
SL
635 read(kmem, s->dk_seek, dk_ndrive * sizeof (long));
636 s->tk_nin = getw(name[X_TK_NIN].n_value);
637 s->tk_nout = getw(name[X_TK_NOUT].n_value);
1cadf944 638 lseek(kmem, (long)name[X_NCHSTATS].n_value, L_SET);
82c646ae 639 read(kmem, &s->nchstats, sizeof s->nchstats);
1cadf944 640 lseek(kmem, (long)name[X_INTRCNT].n_value, L_SET);
3bc5a770
KM
641 read(kmem, s->intrcnt, nintr * sizeof (long));
642}
643
1cadf944 644static
3bc5a770
KM
645allocinfo(s)
646 struct Info *s;
647{
648
649 s->intrcnt = (long *) malloc(nintr * sizeof(long));
650 if (s->intrcnt == NULL) {
c0b7e584 651 fprintf(stderr, "systat: out of memory\n");
3bc5a770
KM
652 exit(2);
653 }
654}
655
1cadf944 656static
3bc5a770 657copyinfo(from, to)
6ae1408e 658 register struct Info *from, *to;
3bc5a770 659{
6ae1408e 660 long *time, *wds, *seek, *xfer;
c0b7e584 661 long *intrcnt;
3bc5a770 662
6ae1408e
SL
663 time = to->dk_time; wds = to->dk_wds; seek = to->dk_seek;
664 xfer = to->dk_xfer; intrcnt = to->intrcnt;
3bc5a770 665 *to = *from;
6ae1408e
SL
666 bcopy(from->dk_time, to->dk_time = time, dk_ndrive * sizeof (long));
667 bcopy(from->dk_wds, to->dk_wds = wds, dk_ndrive * sizeof (long));
668 bcopy(from->dk_seek, to->dk_seek = seek, dk_ndrive * sizeof (long));
669 bcopy(from->dk_xfer, to->dk_xfer = xfer, dk_ndrive * sizeof (long));
670 bcopy(from->intrcnt, to->intrcnt = intrcnt, nintr * sizeof (int));
82c646ae
SL
671}
672
1cadf944 673static
82c646ae
SL
674dinfo(dn, c)
675{
676 double words, atime, itime, xtime;
677
3bc5a770 678 c = DISKCOL + c * 5;
82c646ae 679 atime = s.dk_time[dn];
61969faa 680 atime /= hertz;
82c646ae 681 words = s.dk_wds[dn]*32.0; /* number of words transferred */
1cadf944 682 xtime = dk_mspw[dn]*words; /* transfer time */
82c646ae
SL
683 itime = atime - xtime; /* time not transferring */
684 if (xtime < 0)
685 itime += xtime, xtime = 0;
686 if (itime < 0)
687 xtime += itime, itime = 0;
3bc5a770
KM
688 putint((int)((float)s.dk_seek[dn]/etime+0.5), DISKROW + 1, c, 5);
689 putint((int)((float)s.dk_xfer[dn]/etime+0.5), DISKROW + 2, c, 5);
690 putint((int)(words/etime/512.0 + 0.5), DISKROW + 3, c, 5);
82c646ae 691 if (s.dk_seek[dn])
3bc5a770 692 putfloat(itime*1000.0/s.dk_seek[dn], DISKROW + 4, c, 5, 1, 1);
82c646ae 693 else
3bc5a770 694 putint(0, DISKROW + 4, c, 5);
82c646ae 695}