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