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