in_pcb.h now requires ip.h first
[unix-history] / usr / src / usr.bin / systat / pigs.c
CommitLineData
07ed1e09
KM
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
1cd14d1e 7#ifndef lint
bcc006b0 8static char sccsid[] = "@(#)pigs.c 5.7 (Berkeley) %G%";
07ed1e09
KM
9#endif not lint
10
11/*
12 * Pigs display from Bill Reeves at Lucasfilm
13 */
1cd14d1e
SL
14
15#include "systat.h"
855ff304
KM
16#include <sys/dir.h>
17#include <sys/time.h>
18#include <sys/proc.h>
855ff304 19#include <pwd.h>
eef33ea7 20#include <paths.h>
1cd14d1e 21
d830bff6
SL
22WINDOW *
23openpigs()
24{
b5eefd1e 25 return (subwin(stdscr, LINES-5-1, 0, 5, 0));
d830bff6
SL
26}
27
28closepigs(w)
29 WINDOW *w;
30{
d830bff6
SL
31 if (w == NULL)
32 return;
d830bff6
SL
33 wclear(w);
34 wrefresh(w);
b5eefd1e 35 delwin(w);
d830bff6
SL
36}
37
855ff304
KM
38int maxind;
39int factor;
40float total;
41struct passwd *getpwuid();
42char pidname[30];
bb15a69f
KM
43long stime[CPUSTATES];
44double idle;
855ff304 45
1cd14d1e
SL
46showpigs()
47{
eef33ea7
KB
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;
1cd14d1e 55
d830bff6
SL
56 if (pt == NULL)
57 return;
eef33ea7
KB
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;
ae4efee0 75 total += idle;
eef33ea7
KB
76 pt[numprocs].pt_uid = -1;
77 pt[numprocs].pt_pid = -1;
78 pt[numprocs].pt_pp = NULL;
1cd14d1e 79
ae4efee0
KM
80 if (total < 1.0)
81 total = 1.0;
eef33ea7 82 factor = 50.0/total;
1cd14d1e 83
eef33ea7 84 /* Find the top few by executing a "bubble pass" ten times. */
b5eefd1e
SL
85 y = numprocs + 1;
86 if (y > wnd->_maxy-1)
87 y = wnd->_maxy-1;
eef33ea7
KB
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;
b5eefd1e
SL
107 i = numprocs + 1;
108 if (i > wnd->_maxy-1)
109 i = wnd->_maxy-1;
eef33ea7
KB
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 }
b5eefd1e 143 wmove(wnd, y, 0); wclrtobot(wnd);
1cd14d1e
SL
144}
145
d830bff6 146static struct nlist nlst[] = {
1cd14d1e 147#define X_PROC 0
eef33ea7 148 { "_proc" },
1cd14d1e 149#define X_NPROC 1
eef33ea7 150 { "_nproc" },
d830bff6 151#define X_USRPTMAP 2
eef33ea7 152 { "_Usrptmap" },
d830bff6 153#define X_USRPT 3
eef33ea7 154 { "_usrpt" },
bb15a69f
KM
155#define X_CPTIME 4
156 { "_cp_time" },
eef33ea7 157 { "" }
d830bff6 158};
1cd14d1e 159
852c7064 160initpigs()
1cd14d1e 161{
d830bff6 162 if (nlst[X_PROC].n_type == 0) {
eef33ea7 163 nlist(_PATH_UNIX, nlst);
d830bff6 164 if (nlst[X_PROC].n_type == 0) {
eef33ea7 165 error("namelist on %s failed", _PATH_UNIX);
c0b7e584 166 return(0);
d830bff6
SL
167 }
168 }
eef33ea7
KB
169 if (procp == NULL) {
170 procp = getw(nlst[X_PROC].n_value);
171 nproc = getw(nlst[X_NPROC].n_value);
172 }
c6265927 173 if (kprocp == NULL)
eef33ea7
KB
174 kprocp = (struct proc *)calloc(nproc, sizeof (struct proc));
175 if (usrpt != NULL)
c0b7e584 176 return(1);
852c7064
SL
177 usrpt = (struct pte *)nlst[X_USRPT].n_value;
178 Usrptma = (struct pte *)nlst[X_USRPTMAP].n_value;
c6265927
SL
179 if (pt == NULL)
180 pt = (struct p_times *)calloc(nproc, sizeof (struct p_times));
bb15a69f
KM
181 lseek(kmem, (long)nlst[X_CPTIME].n_value, L_SET);
182 read(kmem, stime, sizeof stime);
c0b7e584 183 return(1);
852c7064
SL
184}
185
186fetchpigs()
187{
eef33ea7
KB
188 register int i;
189 register struct p_times *prt;
190 register float time;
191 register struct proc *pp;
bb15a69f 192 long ctime[CPUSTATES];
bb15a69f 193 double t;
852c7064 194
d830bff6
SL
195 if (nlst[X_PROC].n_type == 0)
196 return;
c6265927
SL
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 }
eef33ea7
KB
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;
bcc006b0
KM
216 prt->pt_pctcpu = ((double) pp->p_pctcpu / fscale) /
217 (1.0 - exp(time * lccpu));
eef33ea7
KB
218 prt->pt_uid = pp->p_uid;
219 prt++;
220 }
221 for (; prt < &pt[nproc]; prt++)
222 prt->pt_uid = -1;
bb15a69f
KM
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];
1cd14d1e
SL
233}
234
235labelpigs()
236{
b5eefd1e 237 wmove(wnd, 0, 0); wclrtoeol(wnd);
eef33ea7
KB
238 mvwaddstr(wnd, 0, 20,
239 "/0 /10 /20 /30 /40 /50 /60 /70 /80 /90 /100");
1cd14d1e 240}