Annotation of 43BSD/ucb/systat/iostat.c, revision 1.1.1.1

1.1       root        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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.