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

1.30    ! deraadt     1: /*     $OpenBSD: pigs.c,v 1.29 2015/01/16 00:03:37 deraadt 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: /*
                     34:  * Pigs display from Bill Reeves at Lucasfilm
                     35:  */
                     36:
1.29      deraadt    37: #include <sys/param.h> /* MAXCOMLEN */
                     38: #include <sys/signal.h>
1.27      miod       39: #include <sys/proc.h>
1.12      deraadt    40: #include <sys/resource.h>
1.27      miod       41: #include <sys/sched.h>
                     42: #include <sys/sysctl.h>
1.1       deraadt    43: #include <sys/time.h>
                     44:
                     45: #include <curses.h>
                     46: #include <math.h>
                     47: #include <pwd.h>
1.8       pvalchev   48: #include <err.h>
1.1       deraadt    49: #include <stdlib.h>
                     50: #include <string.h>
                     51:
                     52: #include "systat.h"
                     53:
1.13      millert    54: int compar(const void *, const void *);
1.22      canacar    55: void print_pg(void);
                     56: int read_pg(void);
                     57: int select_pg(void);
                     58: void showpigs(int k);
                     59:
1.25      guenther   60: static struct kinfo_proc *procbase = NULL;
1.22      canacar    61: static int nproc, pigs_cnt, *pb_indices = NULL;
                     62: static int onproc = -1;
1.1       deraadt    63:
                     64: static long stime[CPUSTATES];
                     65: static double  lccpu;
1.22      canacar    66: struct loadavg sysload;
                     67:
                     68:
1.1       deraadt    69:
1.22      canacar    70: field_def fields_pg[] = {
                     71:        {"USER", 6, 16, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
                     72:        {"NAME", 10, 24, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0},
                     73:        {"PID", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
                     74:        {"CPU", 5, 8, 1, FLD_ALIGN_RIGHT, -1, 0, 0, 0},
                     75:        {"", 30, 60, 1, FLD_ALIGN_BAR, -1, 0, 0, 100},
                     76: };
                     77:
1.24      jasper     78: #define FLD_PG_USER    FIELD_ADDR(fields_pg,0)
                     79: #define FLD_PG_NAME    FIELD_ADDR(fields_pg,1)
                     80: #define FLD_PG_PID     FIELD_ADDR(fields_pg,2)
                     81: #define FLD_PG_VALUE   FIELD_ADDR(fields_pg,3)
                     82: #define FLD_PG_BAR     FIELD_ADDR(fields_pg,4)
1.22      canacar    83:
                     84: /* Define views */
                     85: field_def *view_pg_0[] = {
                     86:        FLD_PG_PID, FLD_PG_USER, FLD_PG_NAME, FLD_PG_VALUE, FLD_PG_BAR, NULL
                     87: };
                     88:
                     89:
                     90: /* Define view managers */
                     91: struct view_manager pigs_mgr = {
                     92:        "Pigs", select_pg, read_pg, NULL, print_header,
                     93:        print_pg, keyboard_callback, NULL, NULL
                     94: };
                     95:
                     96: field_view views_pg[] = {
                     97:        {view_pg_0, "pigs", '5', &pigs_mgr},
                     98:        {NULL, NULL, 0, NULL}
                     99: };
                    100:
1.30    ! deraadt   101: int    fscale;
1.22      canacar   102:
1.30    ! deraadt   103: #define pctdouble(p) ((double)(p) / fscale)
        !           104:
        !           105: typedef long pctcpu;
1.22      canacar   106:
                    107: int
                    108: select_pg(void)
1.1       deraadt   109: {
1.30    ! deraadt   110:        int mib[] = { CTL_KERN, KERN_FSCALE };
        !           111:        size_t size = sizeof(fscale);
        !           112:
        !           113:         if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
        !           114:             &fscale, &size, NULL, 0) < 0)
        !           115:                 return (-1);
1.22      canacar   116:        num_disp = pigs_cnt;
                    117:        return (0);
1.1       deraadt   118: }
                    119:
1.22      canacar   120:
                    121: int
                    122: getprocs(void)
1.1       deraadt   123: {
1.22      canacar   124:        size_t size;
1.25      guenther  125:        int mib[6] = {CTL_KERN, KERN_PROC, KERN_PROC_KTHREAD, 0, sizeof(struct kinfo_proc), 0};
1.22      canacar   126:
                    127:        int st;
                    128:
                    129:        free(procbase);
                    130:        procbase = NULL;
                    131:
                    132:        st = sysctl(mib, 6, NULL, &size, NULL, 0);
                    133:        if (st == -1)
                    134:                return (1);
                    135:
                    136:        size = 5 * size / 4;            /* extra slop */
                    137:        if ((procbase = malloc(size + 1)) == NULL)
                    138:                return (1);
                    139:
1.25      guenther  140:        mib[5] = (int)(size / sizeof(struct kinfo_proc));
1.22      canacar   141:        st = sysctl(mib, 6, procbase, &size, NULL, 0);
                    142:        if (st == -1)
                    143:                return (1);
                    144:
1.25      guenther  145:        nproc = (int)(size / sizeof(struct kinfo_proc));
1.22      canacar   146:        return (0);
1.1       deraadt   147: }
                    148:
                    149:
1.22      canacar   150: int
                    151: read_pg(void)
1.1       deraadt   152: {
1.22      canacar   153:        static int cp_time_mib[] = { CTL_KERN, KERN_CPTIME };
1.23      canacar   154:        long ctimes[CPUSTATES];
1.22      canacar   155:        double t;
                    156:        int i, k;
                    157:        size_t size;
                    158:
                    159:        num_disp = pigs_cnt = 0;
1.1       deraadt   160:
1.22      canacar   161:        if (getprocs()) {
                    162:                error("Failed to read process info!");
                    163:                return 1;
1.1       deraadt   164:        }
                    165:
1.22      canacar   166:        if (nproc > onproc) {
                    167:                int *p;
1.28      doug      168:                p = reallocarray(pb_indices, nproc + 1, sizeof(int));
1.22      canacar   169:                if (p == NULL) {
                    170:                        error("Out of Memory!");
                    171:                        return 1;
1.1       deraadt   172:                }
1.22      canacar   173:                pb_indices = p;
                    174:                onproc = nproc;
1.1       deraadt   175:        }
1.22      canacar   176:
                    177:        memset(&procbase[nproc], 0, sizeof(*procbase));
                    178:
                    179:        for (i = 0; i <= nproc; i++)
                    180:                pb_indices[i] = i;
                    181:
                    182:        /*
                    183:         * and for the imaginary "idle" process
                    184:         */
1.23      canacar   185:        size = sizeof(ctimes);
                    186:        sysctl(cp_time_mib, 2, &ctimes, &size, NULL, 0);
1.22      canacar   187:
                    188:        t = 0;
                    189:        for (i = 0; i < CPUSTATES; i++)
1.23      canacar   190:                t += ctimes[i] - stime[i];
1.22      canacar   191:        if (t == 0.0)
                    192:                t = 1.0;
                    193:
1.23      canacar   194:        procbase[nproc].p_pctcpu = (ctimes[CP_IDLE] - stime[CP_IDLE]) / t / pctdouble(1);
1.22      canacar   195:        for (i = 0; i < CPUSTATES; i++)
1.23      canacar   196:                stime[i] = ctimes[i];
1.22      canacar   197:
                    198:        qsort(pb_indices, nproc + 1, sizeof (int), compar);
                    199:
                    200:        pigs_cnt = 0;
                    201:        for (k = 0; k < nproc + 1; k++) {
1.23      canacar   202:                int j = pb_indices[k];
                    203:                if (pctdouble(procbase[j].p_pctcpu) < 0.01)
1.22      canacar   204:                        break;
                    205:                pigs_cnt++;
                    206:        }
                    207:
                    208:        num_disp = pigs_cnt;
                    209:        return 0;
1.1       deraadt   210: }
                    211:
1.22      canacar   212:
                    213: void
                    214: print_pg(void)
                    215: {
                    216:        int n, count = 0;
                    217:
                    218:        for (n = dispstart; n < num_disp; n++) {
                    219:                showpigs(pb_indices[n]);
                    220:                count++;
                    221:                if (maxprint > 0 && count >= maxprint)
                    222:                        break;
                    223:        }
                    224: }
1.1       deraadt   225:
                    226: int
1.14      deraadt   227: initpigs(void)
1.1       deraadt   228: {
1.12      deraadt   229:        static int sysload_mib[] = {CTL_VM, VM_LOADAVG};
                    230:        static int cp_time_mib[] = { CTL_KERN, KERN_CPTIME };
                    231:        static int ccpu_mib[] = { CTL_KERN, KERN_CCPU };
1.22      canacar   232:        field_view *v;
1.12      deraadt   233:        size_t size;
1.1       deraadt   234:        fixpt_t ccpu;
                    235:
1.12      deraadt   236:        size = sizeof(stime);
1.22      canacar   237:        sysctl(cp_time_mib, 2, &stime, &size, NULL, 0);
1.12      deraadt   238:
                    239:        size = sizeof(sysload);
1.22      canacar   240:        sysctl(sysload_mib, 2, &sysload, &size, NULL, 0);
1.12      deraadt   241:
                    242:        size = sizeof(ccpu);
1.22      canacar   243:        sysctl(ccpu_mib, 2, &ccpu, &size, NULL, 0);
1.12      deraadt   244:
                    245:        lccpu = log((double) ccpu / sysload.fscale);
1.1       deraadt   246:
1.22      canacar   247:        for (v = views_pg; v->name != NULL; v++)
                    248:                add_view(v);
                    249:
1.1       deraadt   250:        return(1);
                    251: }
                    252:
                    253: void
1.22      canacar   254: showpigs(int k)
1.1       deraadt   255: {
1.25      guenther  256:        struct kinfo_proc *kp;
1.22      canacar   257:        double value;
                    258:        char *uname, *pname;
1.1       deraadt   259:
1.22      canacar   260:        if (procbase == NULL)
1.1       deraadt   261:                return;
1.22      canacar   262:
                    263:        value = pctdouble(procbase[k].p_pctcpu) * 100;
                    264:
                    265:        kp = &procbase[k];
                    266:        if (kp->p_comm[0] == '\0') {
                    267:                uname = "";
                    268:                pname = "<idle>";
                    269:        } else {
                    270:                uname = user_from_uid(kp->p_uid, 0);
                    271:                pname = kp->p_comm;
                    272:                print_fld_uint(FLD_PG_PID, kp->p_pid);
1.1       deraadt   273:        }
1.12      deraadt   274:
1.22      canacar   275:        tb_start();
                    276:        tbprintf("%.2f", value);
                    277:        print_fld_tb(FLD_PG_VALUE);
                    278:
                    279:        print_fld_str(FLD_PG_NAME, pname);
                    280:        print_fld_str(FLD_PG_USER, uname);
                    281:        print_fld_bar(FLD_PG_BAR, value);
                    282:
                    283:        end_line();
1.1       deraadt   284: }
                    285:
                    286:
                    287: int
1.14      deraadt   288: compar(const void *a, const void *b)
1.1       deraadt   289: {
1.22      canacar   290:        int i1 = *((int *)a);
                    291:        int i2 = *((int *)b);
                    292:
                    293:        return procbase[i1].p_pctcpu >
                    294:                procbase[i2].p_pctcpu ? -1 : 1;
1.1       deraadt   295: }
1.22      canacar   296: