[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.11

1.11    ! deraadt     1: /*     $OpenBSD: iostat.c,v 1.10 1997/12/19 09:03:32 deraadt 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.11    ! deraadt    41: static char rcsid[] = "$OpenBSD: iostat.c,v 1.10 1997/12/19 09:03:32 deraadt Exp $";
1.1       deraadt    42: #endif not lint
                     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 <nlist.h>
                     52: #include <paths.h>
                     53: #include "systat.h"
                     54: #include "extern.h"
                     55:
1.3       deraadt    56: #include "dkstats.h"
                     57: extern struct _disk    cur;
1.1       deraadt    58:
                     59: static  int linesperregion;
                     60: static  double etime;
                     61: static  int numbers = 0;               /* default display bar graphs */
1.3       deraadt    62: static  int secs = 0;                  /* default seconds shown */
1.1       deraadt    63:
                     64: static int barlabels __P((int));
                     65: static void histogram __P((double, int, double));
                     66: static int numlabels __P((int));
                     67: static int stats __P((int, int, int));
                     68: static void stat1 __P((int, int));
                     69:
                     70:
                     71: WINDOW *
                     72: openiostat()
                     73: {
                     74:        return (subwin(stdscr, LINES-1-5, 0, 5, 0));
                     75: }
                     76:
                     77: void
                     78: closeiostat(w)
                     79:        WINDOW *w;
                     80: {
                     81:        if (w == NULL)
                     82:                return;
                     83:        wclear(w);
                     84:        wrefresh(w);
                     85:        delwin(w);
                     86: }
                     87:
                     88: int
                     89: initiostat()
                     90: {
1.3       deraadt    91:        dkinit(1);
                     92:        dkreadstats();
1.9       kstailey   93:        return (1);
1.1       deraadt    94: }
                     95:
                     96: void
                     97: fetchiostat()
                     98: {
1.3       deraadt    99:        if (dk_ndrive == 0)
1.1       deraadt   100:                return;
1.3       deraadt   101:        dkreadstats();
1.1       deraadt   102: }
                    103:
                    104: #define        INSET   10
                    105:
                    106: void
                    107: labeliostat()
                    108: {
                    109:        int row;
                    110:
                    111:        row = 0;
                    112:        wmove(wnd, row, 0); wclrtobot(wnd);
                    113:        mvwaddstr(wnd, row++, INSET,
                    114:            "/0   /10  /20  /30  /40  /50  /60  /70  /80  /90  /100");
                    115:        mvwaddstr(wnd, row++, 0, "cpu  user|");
                    116:        mvwaddstr(wnd, row++, 0, "     nice|");
                    117:        mvwaddstr(wnd, row++, 0, "   system|");
                    118:        mvwaddstr(wnd, row++, 0, "interrupt|");
                    119:        mvwaddstr(wnd, row++, 0, "     idle|");
                    120:        if (numbers)
                    121:                row = numlabels(row + 1);
                    122:        else
                    123:                row = barlabels(row + 1);
                    124: }
                    125:
                    126: static int
                    127: numlabels(row)
                    128:        int row;
                    129: {
                    130:        int i, col, regions, ndrives;
                    131:
1.7       kstailey  132:        if (dk_ndrive == 0) {
                    133:                mvwaddstr(wnd, row++, INSET, "No drives attached.");
                    134:                return (row);
                    135:        }
1.11    ! deraadt   136: #define COLWIDTH       17
1.4       mickey    137: #define DRIVESPERLINE  ((wnd->_maxx - INSET) / COLWIDTH)
1.1       deraadt   138:        for (ndrives = 0, i = 0; i < dk_ndrive; i++)
1.3       deraadt   139:                if (cur.dk_select[i])
1.1       deraadt   140:                        ndrives++;
                    141:        regions = howmany(ndrives, DRIVESPERLINE);
                    142:        /*
                    143:         * Deduct -regions for blank line after each scrolling region.
                    144:         */
1.4       mickey    145:        linesperregion = (wnd->_maxy - row - regions) / regions;
1.1       deraadt   146:        /*
                    147:         * Minimum region contains space for two
                    148:         * label lines and one line of statistics.
                    149:         */
                    150:        if (linesperregion < 3)
                    151:                linesperregion = 3;
1.11    ! deraadt   152:        col = INSET;
1.1       deraadt   153:        for (i = 0; i < dk_ndrive; i++)
1.3       deraadt   154:                if (cur.dk_select[i] /*&& cur.dk_bytes[i] != 0.0*/) {
1.11    ! deraadt   155:                        if (col + COLWIDTH >= wnd->_maxx) {
        !           156:                                col = INSET, row += linesperregion + 1;
1.4       mickey    157:                                if (row > wnd->_maxy - (linesperregion + 1))
1.1       deraadt   158:                                        break;
                    159:                        }
1.3       deraadt   160:                        mvwaddstr(wnd, row, col + 4, cur.dk_name[i]);
1.11    ! deraadt   161:                        mvwaddstr(wnd, row + 1, col, " KBps tps  sec");
1.1       deraadt   162:                        col += COLWIDTH;
                    163:                }
                    164:        if (col)
                    165:                row += linesperregion + 1;
                    166:        return (row);
                    167: }
                    168:
                    169: static int
                    170: barlabels(row)
                    171:        int row;
                    172: {
                    173:        int i;
                    174:
1.7       kstailey  175:        if (dk_ndrive == 0) {
                    176:                mvwaddstr(wnd, row++, INSET, "No drives attached.");
                    177:                return (row);
                    178:        }
1.1       deraadt   179:        mvwaddstr(wnd, row++, INSET,
1.3       deraadt   180:            "/0   /10  /20  /30  /40  /50  /60  /70  /80  /90  /100");
                    181:        linesperregion = 2 + secs;
1.1       deraadt   182:        for (i = 0; i < dk_ndrive; i++)
1.3       deraadt   183:                if (cur.dk_select[i] /*&& cur.dk_bytes[i] != 0.0*/) {
1.4       mickey    184:                        if (row > wnd->_maxy - linesperregion)
1.1       deraadt   185:                                break;
1.6       maja      186:                        mvwprintw(wnd, row++, 0, "%4.4s  Kps|", cur.dk_name[i]);
1.1       deraadt   187:                        mvwaddstr(wnd, row++, 0, "      tps|");
1.3       deraadt   188:                        if (secs)
                    189:                                mvwaddstr(wnd, row++, 0, "     msec|");
1.1       deraadt   190:                }
                    191:        return (row);
                    192: }
                    193:
                    194:
                    195: void
                    196: showiostat()
                    197: {
                    198:        register int i, row, col;
                    199:
1.3       deraadt   200:        dkswap();
                    201:
1.1       deraadt   202:        etime = 0;
                    203:        for(i = 0; i < CPUSTATES; i++) {
1.3       deraadt   204:                etime += cur.cp_time[i];
1.1       deraadt   205:        }
                    206:        if (etime == 0.0)
                    207:                etime = 1.0;
                    208:        etime /= (float) hz;
                    209:        row = 1;
                    210:
                    211:        /*
                    212:         * Interrupt CPU state not calculated yet.
                    213:         */
                    214:        for (i = 0; i < CPUSTATES; i++)
                    215:                stat1(row++, i);
1.7       kstailey  216:
                    217:        if (dk_ndrive == 0)
                    218:                return;
                    219:
1.1       deraadt   220:        if (!numbers) {
                    221:                row += 2;
                    222:                for (i = 0; i < dk_ndrive; i++)
1.3       deraadt   223:                        if (cur.dk_select[i] /*&& cur.dk_bytes[i] != 0.0*/) {
1.4       mickey    224:                                if (row > wnd->_maxy - linesperregion)
1.1       deraadt   225:                                        break;
                    226:                                row = stats(row, INSET, i);
                    227:                        }
                    228:                return;
                    229:        }
1.11    ! deraadt   230:        col = INSET;
1.1       deraadt   231:        wmove(wnd, row + linesperregion, 0);
                    232:        wdeleteln(wnd);
                    233:        wmove(wnd, row + 3, 0);
                    234:        winsertln(wnd);
                    235:        for (i = 0; i < dk_ndrive; i++)
1.3       deraadt   236:                if (cur.dk_select[i] /*&& cur.dk_bytes[i] != 0.0*/) {
1.4       mickey    237:                        if (col + COLWIDTH >= wnd->_maxx) {
1.11    ! deraadt   238:                                col = INSET, row += linesperregion + 1;
1.4       mickey    239:                                if (row > wnd->_maxy - (linesperregion + 1))
1.1       deraadt   240:                                        break;
                    241:                                wmove(wnd, row + linesperregion, 0);
                    242:                                wdeleteln(wnd);
                    243:                                wmove(wnd, row + 3, 0);
                    244:                                winsertln(wnd);
                    245:                        }
                    246:                        (void) stats(row + 3, col, i);
                    247:                        col += COLWIDTH;
                    248:                }
                    249: }
                    250:
                    251: static int
                    252: stats(row, col, dn)
                    253:        int row, col, dn;
                    254: {
1.3       deraadt   255:        double atime, words;
                    256:
                    257:        /* time busy in disk activity */
                    258:        atime = (double)cur.dk_time[dn].tv_sec +
                    259:                ((double)cur.dk_time[dn].tv_usec / (double)1000000);
1.1       deraadt   260:
1.3       deraadt   261:        words = cur.dk_bytes[dn] / 1024.0;      /* # of K transferred */
1.1       deraadt   262:        if (numbers) {
1.11    ! deraadt   263:                mvwprintw(wnd, row, col, "%5.0f%4.0f%5.1f",
1.3       deraadt   264:                    words / etime, cur.dk_xfer[dn] / etime, atime / etime);
1.1       deraadt   265:                return (row);
                    266:        }
                    267:        wmove(wnd, row++, col);
1.3       deraadt   268:        histogram(words / etime, 50, 0.5);
1.1       deraadt   269:        wmove(wnd, row++, col);
1.3       deraadt   270:        histogram(cur.dk_xfer[dn] / etime, 50, 0.5);
                    271:        if (secs) {
1.1       deraadt   272:                wmove(wnd, row++, col);
1.3       deraadt   273:                atime *= 1000;  /* In milliseconds */
                    274:                histogram(atime / etime, 50, 0.5);
1.1       deraadt   275:        }
                    276:        return (row);
                    277: }
                    278:
                    279: static void
                    280: stat1(row, o)
                    281:        int row, o;
                    282: {
                    283:        register int i;
                    284:        double time;
                    285:
                    286:        time = 0;
                    287:        for (i = 0; i < CPUSTATES; i++)
1.3       deraadt   288:                time += cur.cp_time[i];
1.1       deraadt   289:        if (time == 0.0)
                    290:                time = 1.0;
                    291:        wmove(wnd, row, INSET);
                    292: #define CPUSCALE       0.5
1.3       deraadt   293:        histogram(100.0 * cur.cp_time[o] / time, 50, CPUSCALE);
1.1       deraadt   294: }
                    295:
                    296: static void
                    297: histogram(val, colwidth, scale)
                    298:        double val;
                    299:        int colwidth;
                    300:        double scale;
                    301: {
                    302:        char buf[10];
                    303:        register int k;
                    304:        register int v = (int)(val * scale) + 0.5;
                    305:
                    306:        k = MIN(v, colwidth);
                    307:        if (v > colwidth) {
1.10      deraadt   308:                snprintf(buf, sizeof buf, "%4.1f", val);
1.1       deraadt   309:                k -= strlen(buf);
                    310:                while (k--)
                    311:                        waddch(wnd, 'X');
                    312:                waddstr(wnd, buf);
1.3       deraadt   313:                wclrtoeol(wnd);
1.1       deraadt   314:                return;
                    315:        }
                    316:        while (k--)
                    317:                waddch(wnd, 'X');
                    318:        wclrtoeol(wnd);
                    319: }
                    320:
                    321: int
                    322: cmdiostat(cmd, args)
                    323:        char *cmd, *args;
                    324: {
                    325:
1.3       deraadt   326:        if (prefix(cmd, "secs"))
                    327:                secs = !secs;
1.1       deraadt   328:        else if (prefix(cmd, "numbers"))
                    329:                numbers = 1;
                    330:        else if (prefix(cmd, "bars"))
                    331:                numbers = 0;
                    332:        else if (!dkcmd(cmd, args))
                    333:                return (0);
                    334:        wclear(wnd);
                    335:        labeliostat();
                    336:        refresh();
                    337:        return (1);
                    338: }