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

unix.superglobalmegacorp.com

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