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

Annotation of src/usr.bin/systat/pigs.c, Revision 1.17

1.17    ! otto        1: /*     $OpenBSD: pigs.c,v 1.16 2004/01/08 19:28:56 millert Exp $       */
1.1       deraadt     2: /*     $NetBSD: pigs.c,v 1.3 1995/04/29 05:54:50 cgd Exp $     */
                      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.
1.15      millert    16:  * 3. Neither the name of the University nor the names of its contributors
1.1       deraadt    17:  *    may be used to endorse or promote products derived from this software
                     18:  *    without specific prior written permission.
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     21:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     22:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     23:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     24:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     25:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     26:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     27:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     28:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     29:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     30:  * SUCH DAMAGE.
                     31:  */
                     32:
                     33: #ifndef lint
                     34: #if 0
                     35: static char sccsid[] = "@(#)pigs.c     8.2 (Berkeley) 9/23/93";
                     36: #endif
1.17    ! otto       37: static char rcsid[] = "$OpenBSD: pigs.c,v 1.16 2004/01/08 19:28:56 millert Exp $";
1.1       deraadt    38: #endif /* not lint */
                     39:
                     40: /*
                     41:  * Pigs display from Bill Reeves at Lucasfilm
                     42:  */
                     43:
                     44: #include <sys/param.h>
                     45: #include <sys/dkstat.h>
1.12      deraadt    46: #include <sys/resource.h>
1.1       deraadt    47: #include <sys/dir.h>
                     48: #include <sys/time.h>
                     49: #include <sys/proc.h>
                     50: #include <sys/sysctl.h>
                     51:
                     52: #include <curses.h>
                     53: #include <math.h>
                     54: #include <pwd.h>
1.8       pvalchev   55: #include <err.h>
1.1       deraadt    56: #include <stdlib.h>
                     57: #include <string.h>
                     58:
                     59: #include "extern.h"
                     60: #include "systat.h"
                     61:
1.13      millert    62: int compar(const void *, const void *);
1.1       deraadt    63:
                     64: static int nproc;
                     65: static struct p_times {
                     66:        float pt_pctcpu;
1.16      millert    67:        struct kinfo_proc2 *pt_kp;
1.1       deraadt    68: } *pt;
                     69:
                     70: static long stime[CPUSTATES];
                     71: static double  lccpu;
                     72:
                     73: WINDOW *
1.14      deraadt    74: openpigs(void)
1.1       deraadt    75: {
                     76:        return (subwin(stdscr, LINES-5-1, 0, 5, 0));
                     77: }
                     78:
                     79: void
1.14      deraadt    80: closepigs(WINDOW *w)
1.1       deraadt    81: {
                     82:        if (w == NULL)
                     83:                return;
                     84:        wclear(w);
                     85:        wrefresh(w);
                     86:        delwin(w);
                     87: }
                     88:
                     89:
                     90: void
1.14      deraadt    91: showpigs(void)
1.1       deraadt    92: {
1.9       mpech      93:        int i, j, y, k;
1.16      millert    94:        struct kinfo_proc2 *kp;
1.1       deraadt    95:        float total;
                     96:        int factor;
                     97:        char *uname, *pname, pidname[30];
                     98:
                     99:        if (pt == NULL)
                    100:                return;
                    101:        /* Accumulate the percent of cpu per user. */
                    102:        total = 0.0;
                    103:        for (i = 0; i <= nproc; i++) {
                    104:                /* Accumulate the percentage. */
                    105:                total += pt[i].pt_pctcpu;
                    106:        }
                    107:
                    108:        if (total < 1.0)
1.14      deraadt   109:                total = 1.0;
1.1       deraadt   110:        factor = 50.0/total;
                    111:
1.12      deraadt   112:        qsort(pt, nproc + 1, sizeof (struct p_times), compar);
1.1       deraadt   113:        y = 1;
                    114:        i = nproc + 1;
1.2       mickey    115:        if (i > wnd->_maxy-1)
                    116:                i = wnd->_maxy-1;
1.1       deraadt   117:        for (k = 0; i > 0 && pt[k].pt_pctcpu > 0.01; i--, y++, k++) {
1.16      millert   118:                kp = pt[k].pt_kp;
                    119:                if (kp == NULL) {
1.1       deraadt   120:                        uname = "";
                    121:                        pname = "<idle>";
1.12      deraadt   122:                } else {
1.16      millert   123:                        uname = user_from_uid(kp->p_uid, 0);
                    124:                        pname = kp->p_comm;
1.1       deraadt   125:                }
                    126:                wmove(wnd, y, 0);
                    127:                wclrtoeol(wnd);
                    128:                mvwaddstr(wnd, y, 0, uname);
1.5       deraadt   129:                snprintf(pidname, sizeof pidname, "%10.10s", pname);
1.1       deraadt   130:                mvwaddstr(wnd, y, 9, pidname);
                    131:                wmove(wnd, y, 20);
                    132:                for (j = pt[k].pt_pctcpu*factor + 0.5; j > 0; j--)
                    133:                        waddch(wnd, 'X');
                    134:        }
                    135:        wmove(wnd, y, 0); wclrtobot(wnd);
                    136: }
                    137:
1.12      deraadt   138: struct loadavg sysload;
1.1       deraadt   139:
                    140: int
1.14      deraadt   141: initpigs(void)
1.1       deraadt   142: {
1.12      deraadt   143:        static int sysload_mib[] = {CTL_VM, VM_LOADAVG};
                    144:        static int cp_time_mib[] = { CTL_KERN, KERN_CPTIME };
                    145:        static int ccpu_mib[] = { CTL_KERN, KERN_CCPU };
                    146:        size_t size;
1.1       deraadt   147:        fixpt_t ccpu;
                    148:
1.12      deraadt   149:        size = sizeof(stime);
                    150:        (void) sysctl(cp_time_mib, 2, &stime, &size, NULL, 0);
                    151:
                    152:        size = sizeof(sysload);
                    153:        (void) sysctl(sysload_mib, 2, &sysload, &size, NULL, 0);
                    154:
                    155:        size = sizeof(ccpu);
                    156:        (void) sysctl(ccpu_mib, 2, &ccpu, &size, NULL, 0);
                    157:
                    158:        lccpu = log((double) ccpu / sysload.fscale);
1.1       deraadt   159:
                    160:        return(1);
                    161: }
                    162:
                    163: void
1.14      deraadt   164: fetchpigs(void)
1.1       deraadt   165: {
1.12      deraadt   166:        static int cp_time_mib[] = { CTL_KERN, KERN_CPTIME };
                    167:        static int lastnproc = 0;
1.16      millert   168:        struct kinfo_proc2 *kpp;
1.12      deraadt   169:        long ctime[CPUSTATES];
                    170:        double t;
1.11      pvalchev  171:        int i;
1.12      deraadt   172:        size_t size;
1.17    ! otto      173:        float *pctp;
1.1       deraadt   174:
1.16      millert   175:        kpp = kvm_getproc2(kd, KERN_PROC_KTHREAD, 0, sizeof(*kpp), &nproc);
                    176:        if (kpp == NULL) {
1.1       deraadt   177:                error("%s", kvm_geterr(kd));
                    178:                if (pt)
                    179:                        free(pt);
                    180:                return;
                    181:        }
                    182:        if (nproc > lastnproc) {
                    183:                free(pt);
                    184:                if ((pt =
                    185:                    malloc((nproc + 1) * sizeof(struct p_times))) == NULL) {
                    186:                        error("Out of memory");
1.12      deraadt   187:                        die();
1.1       deraadt   188:                }
                    189:        }
                    190:        lastnproc = nproc;
                    191:        /*
                    192:         * calculate %cpu for each proc
                    193:         */
                    194:        for (i = 0; i < nproc; i++) {
                    195:                pt[i].pt_kp = &kpp[i];
                    196:                pctp = &pt[i].pt_pctcpu;
1.16      millert   197:                if (kpp->p_swtime == 0 || (kpp->p_flag & P_INMEM) == 0)
1.1       deraadt   198:                        *pctp = 0;
                    199:                else
1.16      millert   200:                        *pctp = ((double) kpp->p_pctcpu / sysload.fscale) /
                    201:                            (1.0 - exp(kpp->p_swtime * lccpu));
1.1       deraadt   202:        }
                    203:        /*
                    204:         * and for the imaginary "idle" process
                    205:         */
1.12      deraadt   206:        size = sizeof(ctime);
                    207:        (void) sysctl(cp_time_mib, 2, &ctime, &size, NULL, 0);
                    208:
1.1       deraadt   209:        t = 0;
                    210:        for (i = 0; i < CPUSTATES; i++)
                    211:                t += ctime[i] - stime[i];
                    212:        if (t == 0.0)
                    213:                t = 1.0;
                    214:        pt[nproc].pt_kp = NULL;
                    215:        pt[nproc].pt_pctcpu = (ctime[CP_IDLE] - stime[CP_IDLE]) / t;
                    216:        for (i = 0; i < CPUSTATES; i++)
                    217:                stime[i] = ctime[i];
                    218: }
                    219:
                    220: void
1.14      deraadt   221: labelpigs(void)
1.1       deraadt   222: {
                    223:        wmove(wnd, 0, 0);
                    224:        wclrtoeol(wnd);
                    225:        mvwaddstr(wnd, 0, 20,
                    226:            "/0   /10  /20  /30  /40  /50  /60  /70  /80  /90  /100");
                    227: }
                    228:
                    229: int
1.14      deraadt   230: compar(const void *a, const void *b)
1.1       deraadt   231: {
                    232:        return (((struct p_times *) a)->pt_pctcpu >
1.14      deraadt   233:            ((struct p_times *) b)->pt_pctcpu)? -1: 1;
1.1       deraadt   234: }