1: /* 2: * Copyright (c) 1980 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: */ 6: 7: #ifndef lint 8: static char sccsid[] = "@(#)pigs.c 5.4 (Berkeley) 12/11/85"; 9: #endif not lint 10: 11: /* 12: * Pigs display from Bill Reeves at Lucasfilm 13: */ 14: 15: #include "systat.h" 16: #include <sys/dir.h> 17: #include <sys/time.h> 18: #include <sys/proc.h> 19: #include <sys/dk.h> 20: #include <pwd.h> 21: 22: WINDOW * 23: openpigs() 24: { 25: 26: return (subwin(stdscr, LINES-5-1, 0, 5, 0)); 27: } 28: 29: closepigs(w) 30: WINDOW *w; 31: { 32: 33: if (w == NULL) 34: return; 35: wclear(w); 36: wrefresh(w); 37: delwin(w); 38: } 39: 40: int maxind; 41: int factor; 42: float total; 43: struct passwd *getpwuid(); 44: char pidname[30]; 45: long stime[CPUSTATES]; 46: double idle; 47: 48: showpigs() 49: { 50: register short auid; 51: register int i, j, y; 52: register float max; 53: register struct p_times *ptptr; 54: struct p_times temppt; 55: register struct users *knptr; 56: char *getpname(), *pnamp; 57: 58: if (pt == NULL) 59: return; 60: /* Accumulate the percent of cpu per user. */ 61: ptptr = pt; 62: numprocs = 0; 63: total = 0.0; 64: for (i = 0; i < nproc; i++) { 65: /* discard inactive processes */ 66: if (ptptr->pt_uid == -1) { 67: ptptr++; 68: continue; 69: } 70: /* Accumulate the percentage. */ 71: total += ptptr->pt_pctcpu; 72: numprocs++; 73: ptptr++; 74: } 75: 76: pt[numprocs].pt_pctcpu = idle; 77: total += idle; 78: pt[numprocs].pt_uid = -1; 79: pt[numprocs].pt_pid = -1; 80: pt[numprocs].pt_pp = NULL; 81: 82: if (total < 1.0) 83: total = 1.0; 84: factor = 50.0/total; 85: 86: /* Find the top few by executing a "bubble pass" ten times. */ 87: y = numprocs + 1; 88: if (y > wnd->_maxy-1) 89: y = wnd->_maxy-1; 90: for (i = 0; i < y; i++) { 91: ptptr = &pt[i]; 92: max = -10000.0; 93: maxind = i; 94: for (j = i; j < numprocs + 1; j++) { 95: if (ptptr->pt_pctcpu > max) { 96: max = ptptr->pt_pctcpu; 97: maxind = j; 98: } 99: ptptr++; 100: } 101: if (maxind != i) { 102: temppt = pt[i]; 103: pt[i] = pt[maxind]; 104: pt[maxind] = temppt; 105: } 106: } 107: y = 1; 108: ptptr = pt; 109: i = numprocs + 1; 110: if (i > wnd->_maxy-1) 111: i = wnd->_maxy-1; 112: for (; i > 0 && ptptr->pt_pctcpu > 0.01; i--) { 113: /* Find the user's name. */ 114: knptr = known; 115: auid = ptptr->pt_uid; 116: for (j = numknown - 1; j >= 0; j--) { 117: if (knptr->k_uid == auid) { 118: namp = knptr->k_name; 119: break; 120: } 121: knptr++; 122: } 123: if (j < 0) { 124: if (numknown < 30) { 125: knptr = &known[numknown]; 126: namp = strncpy(knptr->k_name, 127: getpwuid(auid)->pw_name, 15); 128: knptr->k_name[15] = '\0'; 129: knptr->k_uid = auid; 130: numknown++; 131: } else 132: namp = getpwuid(auid)-> pw_name; 133: } 134: pnamp = getpname(ptptr->pt_pid, ptptr->pt_pp); 135: wmove(wnd, y, 0); 136: wclrtoeol(wnd); 137: mvwaddstr(wnd, y, 0, namp); 138: sprintf(pidname, "%10.10s", pnamp); 139: mvwaddstr(wnd, y, 9, pidname); 140: wmove(wnd, y++, 20); 141: for (j = ptptr->pt_pctcpu*factor + 0.5; j > 0; j--) 142: waddch(wnd, 'X'); 143: ptptr++; 144: } 145: wmove(wnd, y, 0); wclrtobot(wnd); 146: } 147: 148: static struct nlist nlst[] = { 149: #define X_PROC 0 150: { "_proc" }, 151: #define X_NPROC 1 152: { "_nproc" }, 153: #define X_USRPTMAP 2 154: { "_Usrptmap" }, 155: #define X_USRPT 3 156: { "_usrpt" }, 157: #define X_CPTIME 4 158: { "_cp_time" }, 159: { "" } 160: }; 161: 162: initpigs() 163: { 164: 165: if (nlst[X_PROC].n_type == 0) { 166: nlist("/vmunix", nlst); 167: if (nlst[X_PROC].n_type == 0) { 168: error("namelist on /vmunix failed"); 169: return(0); 170: } 171: } 172: if (procp == NULL) { 173: procp = getw(nlst[X_PROC].n_value); 174: nproc = getw(nlst[X_NPROC].n_value); 175: } 176: if (kprocp == NULL) 177: kprocp = (struct proc *)calloc(nproc, sizeof (struct proc)); 178: if (usrpt != NULL) 179: return(1); 180: usrpt = (struct pte *)nlst[X_USRPT].n_value; 181: Usrptma = (struct pte *)nlst[X_USRPTMAP].n_value; 182: if (pt == NULL) 183: pt = (struct p_times *)calloc(nproc, sizeof (struct p_times)); 184: lseek(kmem, (long)nlst[X_CPTIME].n_value, L_SET); 185: read(kmem, stime, sizeof stime); 186: return(1); 187: } 188: 189: fetchpigs() 190: { 191: register int i; 192: register struct p_times *prt; 193: register float time; 194: register struct proc *pp; 195: long ctime[CPUSTATES]; 196: double t; 197: 198: if (nlst[X_PROC].n_type == 0) 199: return; 200: if (kprocp == NULL) { 201: kprocp = (struct proc *)calloc(nproc, sizeof (struct proc)); 202: if (kprocp == NULL) 203: return; 204: } 205: if (pt == NULL) { 206: pt = (struct p_times *)calloc(nproc, sizeof (struct p_times)); 207: if (pt == NULL) 208: return; 209: } 210: prt = pt; 211: lseek(kmem, procp, L_SET); 212: read(kmem, kprocp, sizeof (struct proc) * nproc); 213: for (i = 0, pp = kprocp; i < nproc; i++, pp++) { 214: time = pp->p_time; 215: if (time == 0 || (pp->p_flag & SLOAD) == 0) 216: continue; 217: prt->pt_pid = pp->p_pid; 218: prt->pt_pp = pp; 219: prt->pt_pctcpu = pp->p_pctcpu / (1.0 - exp(time * lccpu)); 220: prt->pt_uid = pp->p_uid; 221: prt++; 222: } 223: for (; prt < &pt[nproc]; prt++) 224: prt->pt_uid = -1; 225: lseek(kmem, (long)nlst[X_CPTIME].n_value, L_SET); 226: read(kmem, ctime, sizeof ctime); 227: t = 0; 228: for (i = 0; i < CPUSTATES; i++) 229: t += ctime[i] - stime[i]; 230: if (t == 0.0) 231: t = 1.0; 232: idle = (ctime[CP_IDLE] - stime[CP_IDLE]) / t; 233: for (i = 0; i < CPUSTATES; i++) 234: stime[i] = ctime[i]; 235: } 236: 237: labelpigs() 238: { 239: 240: wmove(wnd, 0, 0); wclrtoeol(wnd); 241: mvwaddstr(wnd, 0, 20, 242: "/0 /10 /20 /30 /40 /50 /60 /70 /80 /90 /100"); 243: }