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