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