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