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