/* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ #ifndef lint static char sccsid[] = "@(#)pigs.c 5.4 (Berkeley) 12/11/85"; #endif not lint /* * Pigs display from Bill Reeves at Lucasfilm */ #include "systat.h" #include #include #include #include #include WINDOW * openpigs() { return (subwin(stdscr, LINES-5-1, 0, 5, 0)); } closepigs(w) WINDOW *w; { if (w == NULL) return; wclear(w); wrefresh(w); delwin(w); } int maxind; int factor; float total; struct passwd *getpwuid(); char pidname[30]; long stime[CPUSTATES]; double idle; showpigs() { register short auid; register int i, j, y; register float max; register struct p_times *ptptr; struct p_times temppt; register struct users *knptr; char *getpname(), *pnamp; if (pt == NULL) return; /* Accumulate the percent of cpu per user. */ ptptr = pt; numprocs = 0; total = 0.0; for (i = 0; i < nproc; i++) { /* discard inactive processes */ if (ptptr->pt_uid == -1) { ptptr++; continue; } /* Accumulate the percentage. */ total += ptptr->pt_pctcpu; numprocs++; ptptr++; } pt[numprocs].pt_pctcpu = idle; total += idle; pt[numprocs].pt_uid = -1; pt[numprocs].pt_pid = -1; pt[numprocs].pt_pp = NULL; if (total < 1.0) total = 1.0; factor = 50.0/total; /* Find the top few by executing a "bubble pass" ten times. */ y = numprocs + 1; if (y > wnd->_maxy-1) y = wnd->_maxy-1; for (i = 0; i < y; i++) { ptptr = &pt[i]; max = -10000.0; maxind = i; for (j = i; j < numprocs + 1; j++) { if (ptptr->pt_pctcpu > max) { max = ptptr->pt_pctcpu; maxind = j; } ptptr++; } if (maxind != i) { temppt = pt[i]; pt[i] = pt[maxind]; pt[maxind] = temppt; } } y = 1; ptptr = pt; i = numprocs + 1; if (i > wnd->_maxy-1) i = wnd->_maxy-1; for (; i > 0 && ptptr->pt_pctcpu > 0.01; i--) { /* Find the user's name. */ knptr = known; auid = ptptr->pt_uid; for (j = numknown - 1; j >= 0; j--) { if (knptr->k_uid == auid) { namp = knptr->k_name; break; } knptr++; } if (j < 0) { if (numknown < 30) { knptr = &known[numknown]; namp = strncpy(knptr->k_name, getpwuid(auid)->pw_name, 15); knptr->k_name[15] = '\0'; knptr->k_uid = auid; numknown++; } else namp = getpwuid(auid)-> pw_name; } pnamp = getpname(ptptr->pt_pid, ptptr->pt_pp); wmove(wnd, y, 0); wclrtoeol(wnd); mvwaddstr(wnd, y, 0, namp); sprintf(pidname, "%10.10s", pnamp); mvwaddstr(wnd, y, 9, pidname); wmove(wnd, y++, 20); for (j = ptptr->pt_pctcpu*factor + 0.5; j > 0; j--) waddch(wnd, 'X'); ptptr++; } wmove(wnd, y, 0); wclrtobot(wnd); } static struct nlist nlst[] = { #define X_PROC 0 { "_proc" }, #define X_NPROC 1 { "_nproc" }, #define X_USRPTMAP 2 { "_Usrptmap" }, #define X_USRPT 3 { "_usrpt" }, #define X_CPTIME 4 { "_cp_time" }, { "" } }; initpigs() { if (nlst[X_PROC].n_type == 0) { nlist("/vmunix", nlst); if (nlst[X_PROC].n_type == 0) { error("namelist on /vmunix failed"); return(0); } } if (procp == NULL) { procp = getw(nlst[X_PROC].n_value); nproc = getw(nlst[X_NPROC].n_value); } if (kprocp == NULL) kprocp = (struct proc *)calloc(nproc, sizeof (struct proc)); if (usrpt != NULL) return(1); usrpt = (struct pte *)nlst[X_USRPT].n_value; Usrptma = (struct pte *)nlst[X_USRPTMAP].n_value; if (pt == NULL) pt = (struct p_times *)calloc(nproc, sizeof (struct p_times)); lseek(kmem, (long)nlst[X_CPTIME].n_value, L_SET); read(kmem, stime, sizeof stime); return(1); } fetchpigs() { register int i; register struct p_times *prt; register float time; register struct proc *pp; long ctime[CPUSTATES]; double t; if (nlst[X_PROC].n_type == 0) return; if (kprocp == NULL) { kprocp = (struct proc *)calloc(nproc, sizeof (struct proc)); if (kprocp == NULL) return; } if (pt == NULL) { pt = (struct p_times *)calloc(nproc, sizeof (struct p_times)); if (pt == NULL) return; } prt = pt; lseek(kmem, procp, L_SET); read(kmem, kprocp, sizeof (struct proc) * nproc); for (i = 0, pp = kprocp; i < nproc; i++, pp++) { time = pp->p_time; if (time == 0 || (pp->p_flag & SLOAD) == 0) continue; prt->pt_pid = pp->p_pid; prt->pt_pp = pp; prt->pt_pctcpu = pp->p_pctcpu / (1.0 - exp(time * lccpu)); prt->pt_uid = pp->p_uid; prt++; } for (; prt < &pt[nproc]; prt++) prt->pt_uid = -1; lseek(kmem, (long)nlst[X_CPTIME].n_value, L_SET); read(kmem, ctime, sizeof ctime); t = 0; for (i = 0; i < CPUSTATES; i++) t += ctime[i] - stime[i]; if (t == 0.0) t = 1.0; idle = (ctime[CP_IDLE] - stime[CP_IDLE]) / t; for (i = 0; i < CPUSTATES; i++) stime[i] = ctime[i]; } labelpigs() { wmove(wnd, 0, 0); wclrtoeol(wnd); mvwaddstr(wnd, 0, 20, "/0 /10 /20 /30 /40 /50 /60 /70 /80 /90 /100"); }