xref: /original-bsd/usr.bin/systat/pigs.c (revision 53787e02)
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