1: /*
   2:  * Copyright (c) 1980 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[] = "@(#)iostat.c	5.2 (Berkeley) 12/11/85";
   9: #endif not lint
  10: 
  11: /*
  12:  * iostat
  13:  */
  14: #include "systat.h"
  15: #include <sys/buf.h>
  16: 
  17: WINDOW *
  18: openiostat()
  19: {
  20: 
  21:     return (subwin(stdscr, LINES-1-5, 0, 5, 0));
  22: }
  23: 
  24: closeiostat(w)
  25:         WINDOW *w;
  26: {
  27: 
  28:         if (w == NULL)
  29:                 return;
  30:         wclear(w);
  31:         wrefresh(w);
  32:     delwin(w);
  33: }
  34: 
  35: static struct nlist nlst[] = {
  36: #define X_DK_BUSY       0
  37:         { "_dk_busy" },
  38: #define X_DK_TIME       1
  39:         { "_dk_time" },
  40: #define X_DK_XFER       2
  41:         { "_dk_xfer" },
  42: #define X_DK_WDS        3
  43:         { "_dk_wds" },
  44: #define X_DK_SEEK       4
  45:         { "_dk_seek" },
  46: #define X_CP_TIME       5
  47:         { "_cp_time" },
  48: #ifdef vax
  49: #define X_MBDINIT       6
  50:         { "_mbdinit" },
  51: #define X_UBDINIT       7
  52:         { "_ubdinit" },
  53: #endif
  54:         { "" },
  55: };
  56: 
  57: static struct {
  58:         int     dk_busy;
  59:         long    cp_time[CPUSTATES];
  60:         long    *dk_time;
  61:         long    *dk_wds;
  62:         long    *dk_seek;
  63:         long    *dk_xfer;
  64: } s, s1;
  65: 
  66: static  int linesperregion;
  67: static  double etime;
  68: static  int numbers = 0;                /* default display bar graphs */
  69: static  int msps = 0;                   /* default ms/seek shown */
  70: 
  71: initiostat()
  72: {
  73: 
  74:         if (nlst[X_DK_BUSY].n_type == 0) {
  75:                 nlist("/vmunix", nlst);
  76:                 if (nlst[X_DK_BUSY].n_type == 0) {
  77:                         error("Disk init information isn't in namelist");
  78:                         return(0);
  79:                 }
  80:         }
  81:     if (! dkinit())
  82:         return(0);
  83:     if (dk_ndrive) {
  84: #define allocate(e, t) \
  85:     s./**/e = (t *)calloc(dk_ndrive, sizeof (t)); \
  86:     s1./**/e = (t *)calloc(dk_ndrive, sizeof (t));
  87:         allocate(dk_time, long);
  88:         allocate(dk_wds, long);
  89:         allocate(dk_seek, long);
  90:         allocate(dk_xfer, long);
  91: #undef allocate
  92:     }
  93:     return(1);
  94: }
  95: 
  96: fetchiostat()
  97: {
  98: 
  99:         if (nlst[X_DK_BUSY].n_type == 0)
 100:                 return;
 101:     s.dk_busy = getw(nlst[X_DK_BUSY].n_value);
 102:         lseek(kmem, (long)nlst[X_DK_TIME].n_value, L_SET);
 103:         read(kmem, s.dk_time, dk_ndrive * sizeof (long));
 104:         lseek(kmem, (long)nlst[X_DK_XFER].n_value, L_SET);
 105:         read(kmem, s.dk_xfer, dk_ndrive * sizeof (long));
 106:         lseek(kmem, (long)nlst[X_DK_WDS].n_value, L_SET);
 107:         read(kmem, s.dk_wds, dk_ndrive * sizeof (long));
 108:         lseek(kmem, (long)nlst[X_DK_SEEK].n_value, L_SET);
 109:         read(kmem, s.dk_seek, dk_ndrive * sizeof (long));
 110:         lseek(kmem, (long)nlst[X_CP_TIME].n_value, L_SET);
 111:         read(kmem, s.cp_time, sizeof s.cp_time);
 112: }
 113: 
 114: #define INSET   10
 115: 
 116: labeliostat()
 117: {
 118:         int row;
 119: 
 120:         if (nlst[X_DK_BUSY].n_type == 0) {
 121:                 error("No dk_busy defined.");
 122:                 return;
 123:         }
 124:         row = 0;
 125:         wmove(wnd, row, 0); wclrtobot(wnd);
 126:         mvwaddstr(wnd, row++, INSET,
 127:             "/0   /10  /20  /30  /40  /50  /60  /70  /80  /90  /100");
 128:         mvwaddstr(wnd, row++, 0, "cpu  user|");
 129:         mvwaddstr(wnd, row++, 0, "     nice|");
 130:         mvwaddstr(wnd, row++, 0, "   system|");
 131:         mvwaddstr(wnd, row++, 0, "     idle|");
 132:         if (numbers)
 133:                 row = numlabels(row + 1);
 134:         else
 135:                 row = barlabels(row + 1);
 136: }
 137: 
 138: static
 139: numlabels(row)
 140: {
 141:         int i, col, regions, ndrives;
 142: 
 143: #define COLWIDTH        14
 144: #define DRIVESPERLINE   ((wnd->_maxx - INSET) / COLWIDTH)
 145:     for (ndrives = 0, i = 0; i < dk_ndrive; i++)
 146:         if (dk_select[i])
 147:             ndrives++;
 148:         regions = howmany(ndrives, DRIVESPERLINE);
 149:         /*
 150:          * Deduct -regions for blank line after each scrolling region.
 151:          */
 152:         linesperregion = (wnd->_maxy - row - regions) / regions;
 153:         /*
 154:          * Minimum region contains space for two
 155:          * label lines and one line of statistics.
 156:          */
 157:         if (linesperregion < 3)
 158:                 linesperregion = 3;
 159:         col = 0;
 160:         for (i = 0; i < dk_ndrive; i++)
 161:                 if (dk_select[i] && dk_mspw[i] != 0.0) {
 162:                         if (col + COLWIDTH >= wnd->_maxx - INSET) {
 163:                                 col = 0, row += linesperregion + 1;
 164:                                 if (row > wnd->_maxy - (linesperregion + 1))
 165:                                         break;
 166:                         }
 167:                         mvwaddstr(wnd, row, col + 4, dr_name[i]);
 168:                         mvwaddstr(wnd, row + 1, col, "bps tps msps");
 169:                         col += COLWIDTH;
 170:                 }
 171:         if (col)
 172:                 row += linesperregion + 1;
 173:         return (row);
 174: }
 175: 
 176: static
 177: barlabels(row)
 178:         int row;
 179: {
 180:         int i;
 181: 
 182:         mvwaddstr(wnd, row++, INSET,
 183:             "/0   /5   /10  /15  /20  /25  /30  /35  /40  /45  /50");
 184:         linesperregion = 2 + msps;
 185:         for (i = 0; i < dk_ndrive; i++)
 186:                 if (dk_select[i] && dk_mspw[i] != 0.0) {
 187:                         if (row > wnd->_maxy - linesperregion)
 188:                                 break;
 189:                         mvwprintw(wnd, row++, 0, "%3.3s   bps|", dr_name[i]);
 190:                         mvwaddstr(wnd, row++, 0, "      tps|");
 191:                         if (msps)
 192:                                 mvwaddstr(wnd, row++, 0, "     msps|");
 193:                 }
 194:         return (row);
 195: }
 196: 
 197: showiostat()
 198: {
 199:         register int i, row, col;
 200:         register long t;
 201: 
 202:         if (nlst[X_DK_BUSY].n_type == 0)
 203:                 return;
 204:         for (i = 0; i < dk_ndrive; i++) {
 205: #define X(fld)  t = s.fld[i]; s.fld[i] -= s1.fld[i]; s1.fld[i] = t
 206:                 X(dk_xfer); X(dk_seek); X(dk_wds); X(dk_time);
 207:         }
 208:         etime = 0;
 209:         for(i = 0; i < CPUSTATES; i++) {
 210:                 X(cp_time);
 211:                 etime += s.cp_time[i];
 212:         }
 213:         if (etime == 0.0)
 214:                 etime = 1.0;
 215:         etime /= (float) hz;
 216:         row = 1;
 217:         for (i = 0; i < CPUSTATES; i++)
 218:                 stat1(row++, i);
 219:         if (!numbers) {
 220:                 row += 2;
 221:                 for (i = 0; i < dk_ndrive; i++)
 222:                         if (dk_select[i] && dk_mspw[i] != 0.0) {
 223:                                 if (row > wnd->_maxy - linesperregion)
 224:                                         break;
 225:                                 row = stats(row, INSET, i);
 226:                         }
 227:                 return;
 228:         }
 229:         col = 0;
 230:         wmove(wnd, row + linesperregion, 0);
 231:         wdeleteln(wnd);
 232:         wmove(wnd, row + 3, 0);
 233:         winsertln(wnd);
 234:         for (i = 0; i < dk_ndrive; i++)
 235:                 if (dk_select[i] && dk_mspw[i] != 0.0) {
 236:                         if (col + COLWIDTH >= wnd->_maxx) {
 237:                                 col = 0, row += linesperregion + 1;
 238:                                 if (row > wnd->_maxy - (linesperregion + 1))
 239:                                         break;
 240:                                 wmove(wnd, row + linesperregion, 0);
 241:                                 wdeleteln(wnd);
 242:                                 wmove(wnd, row + 3, 0);
 243:                                 winsertln(wnd);
 244:                         }
 245:                         (void) stats(row + 3, col, i);
 246:                         col += COLWIDTH;
 247:                 }
 248: }
 249: 
 250: static
 251: stats(row, col, dn)
 252:         int row, dn;
 253: {
 254:         double atime, words, xtime, itime;
 255: 
 256:         atime = s.dk_time[dn];
 257:         atime /= (float) hz;
 258:         words = s.dk_wds[dn]*32.0;      /* number of words transferred */
 259:         xtime = dk_mspw[dn]*words;      /* transfer time */
 260:         itime = atime - xtime;          /* time not transferring */
 261:         if (xtime < 0)
 262:                 itime += xtime, xtime = 0;
 263:         if (itime < 0)
 264:                 xtime += itime, itime = 0;
 265:         if (numbers) {
 266:                 mvwprintw(wnd, row, col, "%3.0f%4.0f%5.1f",
 267:                     words / 512 / etime, s.dk_xfer[dn] / etime,
 268:                     s.dk_seek[dn] ? itime * 1000. / s.dk_seek[dn] : 0.0);
 269:                 return (row);
 270:         }
 271:         wmove(wnd, row++, col);
 272:         histogram(words / 512 / etime, 50, 1.0);
 273:         wmove(wnd, row++, col);
 274:         histogram(s.dk_xfer[dn] / etime, 50, 1.0);
 275:         if (msps) {
 276:                 wmove(wnd, row++, col);
 277:                 histogram(s.dk_seek[dn] ? itime * 1000. / s.dk_seek[dn] : 0,
 278:                    50, 1.0);
 279:         }
 280:         return (row);
 281: }
 282: 
 283: static
 284: stat1(row, o)
 285:         int row, o;
 286: {
 287:         register i;
 288:         double time;
 289: 
 290:         time = 0;
 291:         for (i = 0; i < CPUSTATES; i++)
 292:                 time += s.cp_time[i];
 293:         if (time == 0.0)
 294:                 time = 1.0;
 295:         wmove(wnd, row, INSET);
 296: #define CPUSCALE        0.5
 297:         histogram(100 * s.cp_time[o] / time, 50, CPUSCALE);
 298: }
 299: 
 300: histogram(val, colwidth, scale)
 301:         double val;
 302:         int colwidth;
 303:         double scale;
 304: {
 305:         char buf[10];
 306:         register int k;
 307:         register int v = (int)(val * scale) + 0.5;
 308: 
 309:         k = MIN(v, colwidth);
 310:         if (v > colwidth) {
 311:                 sprintf(buf, "%4.1f", val);
 312:                 k -= strlen(buf);
 313:                 while (k--)
 314:                         waddch(wnd, 'X');
 315:                 waddstr(wnd, buf);
 316:                 return;
 317:         }
 318:         while (k--)
 319:                 waddch(wnd, 'X');
 320:         wclrtoeol(wnd);
 321: }
 322: 
 323: cmdiostat(cmd, args)
 324:         char *cmd, *args;
 325: {
 326: 
 327:         if (prefix(cmd, "msps"))
 328:                 msps = !msps;
 329:     else if (prefix(cmd, "numbers"))
 330:                 numbers = 1;
 331:     else if (prefix(cmd, "bars"))
 332:                 numbers = 0;
 333:     else if (!dkcmd(cmd, args))
 334:         return (0);
 335:         wclear(wnd);
 336:         labeliostat();
 337:         refresh();
 338:         return (1);
 339: }

Defined functions

barlabels defined in line 176; used 1 times
closeiostat defined in line 24; used 2 times
cmdiostat defined in line 323; used 2 times
fetchiostat defined in line 96; used 2 times
histogram defined in line 300; used 4 times
initiostat defined in line 71; used 2 times
labeliostat defined in line 116; used 3 times
numlabels defined in line 138; used 1 times
openiostat defined in line 17; used 2 times
showiostat defined in line 197; used 2 times
stat1 defined in line 283; used 1 times
stats defined in line 250; used 2 times

Defined variables

etime defined in line 67; used 9 times
linesperregion defined in line 66; used 13 times
msps defined in line 69; used 5 times
nlst defined in line 35; used 12 times
numbers defined in line 68; used 5 times
sccsid defined in line 8; never used

Defined macros

COLWIDTH defined in line 143; used 5 times
CPUSCALE defined in line 296; used 1 times
DRIVESPERLINE defined in line 144; used 1 times
INSET defined in line 114; used 6 times
X defined in line 205; used 5 times
X_CP_TIME defined in line 46; used 1 times
X_DK_BUSY defined in line 36; used 6 times
X_DK_SEEK defined in line 44; used 1 times
X_DK_TIME defined in line 38; used 1 times
X_DK_WDS defined in line 42; used 1 times
X_DK_XFER defined in line 40; used 1 times
X_MBDINIT defined in line 49; never used
X_UBDINIT defined in line 51; never used
allocate defined in line 84; used 5 times
Last modified: 1986-01-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1862
Valid CSS Valid XHTML 1.0 Strict