[BACK]Return to iostat.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / systat

Annotation of src/usr.bin/systat/iostat.c, Revision 1.20

1.20    ! henning     1: /*     $OpenBSD: iostat.c,v 1.19 2002/12/16 01:57:04 tdeval Exp $      */
1.3       deraadt     2: /*     $NetBSD: iostat.c,v 1.5 1996/05/10 23:16:35 thorpej Exp $       */
1.1       deraadt     3:
                      4: /*
                      5:  * Copyright (c) 1980, 1992, 1993
                      6:  *     The Regents of the University of California.  All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *     This product includes software developed by the University of
                     19:  *     California, Berkeley and its contributors.
                     20:  * 4. Neither the name of the University nor the names of its contributors
                     21:  *    may be used to endorse or promote products derived from this software
                     22:  *    without specific prior written permission.
                     23:  *
                     24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     34:  * SUCH DAMAGE.
                     35:  */
                     36:
                     37: #ifndef lint
                     38: #if 0
                     39: static char sccsid[] = "@(#)iostat.c   8.1 (Berkeley) 6/6/93";
                     40: #endif
1.20    ! henning    41: static char rcsid[] = "$OpenBSD: iostat.c,v 1.19 2002/12/16 01:57:04 tdeval Exp $";
1.12      heko       42: #endif /* not lint */
1.1       deraadt    43:
                     44: #include <sys/param.h>
                     45: #include <sys/dkstat.h>
                     46: #include <sys/buf.h>
1.3       deraadt    47: #include <sys/time.h>
1.1       deraadt    48:
                     49: #include <string.h>
                     50: #include <stdlib.h>
                     51: #include <paths.h>
                     52: #include "systat.h"
                     53: #include "extern.h"
                     54:
1.3       deraadt    55: #include "dkstats.h"
1.19      tdeval     56: extern struct _disk    cur, last;
1.1       deraadt    57:
                     58: static  int linesperregion;
                     59: static  double etime;
                     60: static  int numbers = 0;               /* default display bar graphs */
1.3       deraadt    61: static  int secs = 0;                  /* default seconds shown */
1.1       deraadt    62:
1.17      millert    63: static int barlabels(int);
                     64: static void histogram(double, int, double);
                     65: static int numlabels(int);
                     66: static int stats(int, int, int);
                     67: static void stat1(int, int);
1.1       deraadt    68:
                     69:
                     70: WINDOW *
1.18      deraadt    71: openiostat(void)
1.1       deraadt    72: {
                     73:        return (subwin(stdscr, LINES-1-5, 0, 5, 0));
                     74: }
                     75:
                     76: void
1.18      deraadt    77: closeiostat(WINDOW *w)
1.1       deraadt    78: {
                     79:        if (w == NULL)
                     80:                return;
                     81:        wclear(w);
                     82:        wrefresh(w);
                     83:        delwin(w);
                     84: }
                     85:
                     86: int
1.18      deraadt    87: initiostat(void)
1.1       deraadt    88: {
1.3       deraadt    89:        dkinit(1);
                     90:        dkreadstats();
1.9       kstailey   91:        return (1);
1.1       deraadt    92: }
                     93:
                     94: void
1.18      deraadt    95: fetchiostat(void)
1.1       deraadt    96: {
1.19      tdeval     97:        if (cur.dk_ndrive == 0)
1.1       deraadt    98:                return;
1.3       deraadt    99:        dkreadstats();
1.1       deraadt   100: }
                    101:
                    102: #define        INSET   10
                    103:
                    104: void
1.18      deraadt   105: labeliostat(void)
1.1       deraadt   106: {
                    107:        int row;
                    108:
                    109:        row = 0;
                    110:        wmove(wnd, row, 0); wclrtobot(wnd);
                    111:        mvwaddstr(wnd, row++, INSET,
                    112:            "/0   /10  /20  /30  /40  /50  /60  /70  /80  /90  /100");
                    113:        mvwaddstr(wnd, row++, 0, "cpu  user|");
                    114:        mvwaddstr(wnd, row++, 0, "     nice|");
                    115:        mvwaddstr(wnd, row++, 0, "   system|");
                    116:        mvwaddstr(wnd, row++, 0, "interrupt|");
                    117:        mvwaddstr(wnd, row++, 0, "     idle|");
                    118:        if (numbers)
                    119:                row = numlabels(row + 1);
                    120:        else
                    121:                row = barlabels(row + 1);
                    122: }
                    123:
                    124: static int
1.18      deraadt   125: numlabels(int row)
1.1       deraadt   126: {
                    127:        int i, col, regions, ndrives;
                    128:
1.19      tdeval    129:        if (cur.dk_ndrive == 0) {
1.7       kstailey  130:                mvwaddstr(wnd, row++, INSET, "No drives attached.");
                    131:                return (row);
                    132:        }
1.11      deraadt   133: #define COLWIDTH       17
1.4       mickey    134: #define DRIVESPERLINE  ((wnd->_maxx - INSET) / COLWIDTH)
1.19      tdeval    135:        for (ndrives = 0, i = 0; i < cur.dk_ndrive; i++)
1.3       deraadt   136:                if (cur.dk_select[i])
1.1       deraadt   137:                        ndrives++;
                    138:        regions = howmany(ndrives, DRIVESPERLINE);
                    139:        /*
                    140:         * Deduct -regions for blank line after each scrolling region.
                    141:         */
1.4       mickey    142:        linesperregion = (wnd->_maxy - row - regions) / regions;
1.1       deraadt   143:        /*
                    144:         * Minimum region contains space for two
                    145:         * label lines and one line of statistics.
                    146:         */
                    147:        if (linesperregion < 3)
                    148:                linesperregion = 3;
1.11      deraadt   149:        col = INSET;
1.19      tdeval    150:        for (i = 0; i < cur.dk_ndrive; i++)
1.3       deraadt   151:                if (cur.dk_select[i] /*&& cur.dk_bytes[i] != 0.0*/) {
1.11      deraadt   152:                        if (col + COLWIDTH >= wnd->_maxx) {
                    153:                                col = INSET, row += linesperregion + 1;
1.4       mickey    154:                                if (row > wnd->_maxy - (linesperregion + 1))
1.1       deraadt   155:                                        break;
                    156:                        }
1.3       deraadt   157:                        mvwaddstr(wnd, row, col + 4, cur.dk_name[i]);
1.11      deraadt   158:                        mvwaddstr(wnd, row + 1, col, " KBps tps  sec");
1.1       deraadt   159:                        col += COLWIDTH;
                    160:                }
                    161:        if (col)
                    162:                row += linesperregion + 1;
                    163:        return (row);
                    164: }
                    165:
                    166: static int
1.18      deraadt   167: barlabels(int row)
1.1       deraadt   168: {
                    169:        int i;
                    170:
1.19      tdeval    171:        if (cur.dk_ndrive == 0) {
1.7       kstailey  172:                mvwaddstr(wnd, row++, INSET, "No drives attached.");
                    173:                return (row);
                    174:        }
1.1       deraadt   175:        mvwaddstr(wnd, row++, INSET,
1.3       deraadt   176:            "/0   /10  /20  /30  /40  /50  /60  /70  /80  /90  /100");
                    177:        linesperregion = 2 + secs;
1.1       deraadt   178:        for (i = 0; i < dk_ndrive; i++)
1.3       deraadt   179:                if (cur.dk_select[i] /*&& cur.dk_bytes[i] != 0.0*/) {
1.4       mickey    180:                        if (row > wnd->_maxy - linesperregion)
1.1       deraadt   181:                                break;
1.6       maja      182:                        mvwprintw(wnd, row++, 0, "%4.4s  Kps|", cur.dk_name[i]);
1.1       deraadt   183:                        mvwaddstr(wnd, row++, 0, "      tps|");
1.3       deraadt   184:                        if (secs)
                    185:                                mvwaddstr(wnd, row++, 0, "     msec|");
1.1       deraadt   186:                }
                    187:        return (row);
                    188: }
                    189:
                    190:
                    191: void
1.18      deraadt   192: showiostat(void)
1.1       deraadt   193: {
1.13      mpech     194:        int i, row, col;
1.1       deraadt   195:
1.3       deraadt   196:        dkswap();
                    197:
1.1       deraadt   198:        etime = 0;
1.18      deraadt   199:        for (i = 0; i < CPUSTATES; i++) {
1.3       deraadt   200:                etime += cur.cp_time[i];
1.1       deraadt   201:        }
                    202:        if (etime == 0.0)
                    203:                etime = 1.0;
                    204:        etime /= (float) hz;
                    205:        row = 1;
                    206:
                    207:        /*
                    208:         * Interrupt CPU state not calculated yet.
1.16      deraadt   209:         */
1.1       deraadt   210:        for (i = 0; i < CPUSTATES; i++)
                    211:                stat1(row++, i);
1.7       kstailey  212:
1.19      tdeval    213:        if (last.dk_ndrive != cur.dk_ndrive)
                    214:                labeliostat();
                    215:
                    216:        if (cur.dk_ndrive == 0)
1.7       kstailey  217:                return;
                    218:
1.1       deraadt   219:        if (!numbers) {
                    220:                row += 2;
1.19      tdeval    221:                for (i = 0; i < cur.dk_ndrive; i++)
1.3       deraadt   222:                        if (cur.dk_select[i] /*&& cur.dk_bytes[i] != 0.0*/) {
1.4       mickey    223:                                if (row > wnd->_maxy - linesperregion)
1.1       deraadt   224:                                        break;
                    225:                                row = stats(row, INSET, i);
                    226:                        }
                    227:                return;
                    228:        }
1.11      deraadt   229:        col = INSET;
1.1       deraadt   230:        wmove(wnd, row + linesperregion, 0);
                    231:        wdeleteln(wnd);
                    232:        wmove(wnd, row + 3, 0);
                    233:        winsertln(wnd);
1.19      tdeval    234:        for (i = 0; i < cur.dk_ndrive; i++)
1.3       deraadt   235:                if (cur.dk_select[i] /*&& cur.dk_bytes[i] != 0.0*/) {
1.4       mickey    236:                        if (col + COLWIDTH >= wnd->_maxx) {
1.11      deraadt   237:                                col = INSET, row += linesperregion + 1;
1.4       mickey    238:                                if (row > wnd->_maxy - (linesperregion + 1))
1.1       deraadt   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 int
1.18      deraadt   251: stats(int row, int col, int dn)
1.1       deraadt   252: {
1.3       deraadt   253:        double atime, words;
                    254:
                    255:        /* time busy in disk activity */
                    256:        atime = (double)cur.dk_time[dn].tv_sec +
                    257:                ((double)cur.dk_time[dn].tv_usec / (double)1000000);
1.1       deraadt   258:
1.3       deraadt   259:        words = cur.dk_bytes[dn] / 1024.0;      /* # of K transferred */
1.1       deraadt   260:        if (numbers) {
1.11      deraadt   261:                mvwprintw(wnd, row, col, "%5.0f%4.0f%5.1f",
1.3       deraadt   262:                    words / etime, cur.dk_xfer[dn] / etime, atime / etime);
1.1       deraadt   263:                return (row);
                    264:        }
                    265:        wmove(wnd, row++, col);
1.3       deraadt   266:        histogram(words / etime, 50, 0.5);
1.1       deraadt   267:        wmove(wnd, row++, col);
1.3       deraadt   268:        histogram(cur.dk_xfer[dn] / etime, 50, 0.5);
                    269:        if (secs) {
1.1       deraadt   270:                wmove(wnd, row++, col);
1.3       deraadt   271:                atime *= 1000;  /* In milliseconds */
                    272:                histogram(atime / etime, 50, 0.5);
1.1       deraadt   273:        }
                    274:        return (row);
                    275: }
                    276:
                    277: static void
1.18      deraadt   278: stat1(int row, int o)
1.1       deraadt   279: {
1.13      mpech     280:        int i;
1.1       deraadt   281:        double time;
                    282:
                    283:        time = 0;
                    284:        for (i = 0; i < CPUSTATES; i++)
1.3       deraadt   285:                time += cur.cp_time[i];
1.1       deraadt   286:        if (time == 0.0)
                    287:                time = 1.0;
                    288:        wmove(wnd, row, INSET);
                    289: #define CPUSCALE       0.5
1.3       deraadt   290:        histogram(100.0 * cur.cp_time[o] / time, 50, CPUSCALE);
1.1       deraadt   291: }
                    292:
                    293: static void
1.18      deraadt   294: histogram(double val, int colwidth, double scale)
1.1       deraadt   295: {
1.20    ! henning   296:        int v = (int)(val * scale + 0.5);
        !           297:        int factor = 1;
        !           298:        int y, x;
        !           299:
        !           300:        while (v > colwidth) {
        !           301:                v = (v + 5) / 10;
        !           302:                factor *= 10;
1.1       deraadt   303:        }
1.20    ! henning   304:        getyx(wnd, y, x);
1.1       deraadt   305:        wclrtoeol(wnd);
1.20    ! henning   306:        whline(wnd, 'X', v);
        !           307:        if (factor != 1)
        !           308:                mvwprintw(wnd, y, x + colwidth + 1, "* %d ", factor);
1.1       deraadt   309: }
                    310:
                    311: int
1.18      deraadt   312: cmdiostat(char *cmd, char *args)
1.1       deraadt   313: {
                    314:
1.3       deraadt   315:        if (prefix(cmd, "secs"))
                    316:                secs = !secs;
1.1       deraadt   317:        else if (prefix(cmd, "numbers"))
                    318:                numbers = 1;
                    319:        else if (prefix(cmd, "bars"))
                    320:                numbers = 0;
                    321:        else if (!dkcmd(cmd, args))
                    322:                return (0);
                    323:        wclear(wnd);
                    324:        labeliostat();
                    325:        refresh();
                    326:        return (1);
                    327: }