changes from donn@utah-cs for common header file for pcc
[unix-history] / usr / src / usr.bin / systat / swap.c
CommitLineData
ce3b185b 1#ifndef lint
855ff304 2static char *sccsid = "@(#)swap.c 1.6 (Lucasfilm) %G%";
ce3b185b
SL
3#endif
4
5#include "systat.h"
855ff304
KM
6#include <sys/param.h>
7#include <sys/dir.h>
8#include <sys/user.h>
9#include <sys/proc.h>
10#include <sys/text.h>
11#include <sys/conf.h>
12#include <sys/file.h>
13#include <sys/vmmac.h>
14#include <machine/pte.h>
15#include <nlist.h>
ce3b185b 16
d830bff6
SL
17WINDOW *
18openswap()
ce3b185b 19{
d830bff6 20 static WINDOW *w = NULL;
ce3b185b 21
d830bff6
SL
22 if (w == NULL)
23 w = newwin(20, 70, 3, 5);
24 return (w);
852c7064
SL
25}
26
d830bff6
SL
27closeswap(w)
28 WINDOW *w;
852c7064
SL
29{
30
d830bff6 31 if (w == NULL)
c6265927 32 return;
d830bff6
SL
33 move(5, 0);
34 clrtobot();
35 wclear(w);
36 wrefresh(w);
ce3b185b
SL
37}
38
d830bff6
SL
39int dmmin;
40int dmmax;
41int dmtext;
42int nswdev;
43#define MAXSWAPDEV 4
44short buckets[MAXSWAPDEV][NDMAP];
45struct swdevt *swdevt;
e7a897ca
SL
46int colwidth;
47
852c7064
SL
48extern union {
49 struct user user;
50 char upages[UPAGES][NBPG];
51} user;
52#define u user.user
53
ce3b185b
SL
54showswap()
55{
e7a897ca 56 register int i, j;
852c7064
SL
57 register struct proc *pp;
58 register struct text *xp;
ce3b185b 59 register int row;
852c7064
SL
60 register int ts;
61 register swblk_t *dp;
ce3b185b 62
c6265927 63 if (xtext == 0)
e7a897ca 64 return;
852c7064
SL
65 for (xp = xtext; xp < &xtext[ntext]; xp++) {
66 if (xp->x_iptr == NULL)
67 continue;
68 ts = ctod(xp->x_size);
69 dp = xp->x_daddr;
70 for (i = 0; i < ts; i += dmtext) {
71 j = ts - i;
72 if (j > dmtext)
73 j = dmtext;
74#define swatodev(addr) (((addr) / dmmax) % nswdev)
75 buckets[swatodev(*dp)][dmtoindex(j)]++;
76 dp++;
e7a897ca 77 }
852c7064
SL
78 if ((xp->x_flag & XPAGI) && xp->x_ptdaddr)
79 buckets[swatodev(xp->x_ptdaddr)]
80 [dmtoindex(ctod(ctopt(xp->x_size)))]++;
e7a897ca 81 }
852c7064 82 row = swapdisplay(4, dmtext, 'X');
c6265927
SL
83 if (kprocp == NULL)
84 return;
852c7064
SL
85 for (i = 0, pp = kprocp; i < nproc; i++, pp++) {
86 if (pp->p_stat == 0 || pp->p_stat == SZOMB)
87 continue;
88 if (pp->p_flag & SSYS)
89 continue;
c6265927 90 if (getu(pp) == 0)
852c7064 91 continue;
852c7064
SL
92 vsacct(&u.u_dmap);
93 vsacct(&u.u_smap);
ce3b185b 94#ifdef notdef
852c7064
SL
95 if ((pp->p_flag & SLOAD) == 0)
96 vusize(pp);
ce3b185b 97#endif
852c7064
SL
98 }
99 (void) swapdisplay(row + 1, dmmax, 'X');
e7a897ca 100}
ce3b185b 101
852c7064
SL
102swapdisplay(baserow, dmbound, c)
103 int baserow, dmbound;
104 char c;
ce3b185b 105{
852c7064
SL
106 register int i, j, k, row;
107 register short *pb;
108 char buf[10];
ce3b185b 109
852c7064
SL
110 for (row = baserow, i = dmmin; i <= dmbound; i *= 2, row++) {
111 for (j = 0; j < nswdev; j++) {
112 pb = &buckets[j][row - baserow];
113 wmove(wnd, row, j * (1 + colwidth));
114 k = MIN(*pb, colwidth);
115 if (*pb > colwidth) {
116 sprintf(buf, " %d", *pb);
117 k -= strlen(buf);
118 while (k--)
119 waddch(wnd, c);
120 waddstr(wnd, buf);
121 } else {
122 while (k--)
123 waddch(wnd, c);
124 k = MAX(colwidth - *pb, 0);
125 while (k--)
126 waddch(wnd, ' ');
e7a897ca 127 }
852c7064 128 *pb = 0;
e7a897ca
SL
129 }
130 }
852c7064 131 return (row);
ce3b185b
SL
132}
133
852c7064
SL
134vsacct(dmp)
135 register struct dmap *dmp;
ce3b185b 136{
852c7064
SL
137 register swblk_t *ip;
138 register int blk = dmmin, index = 0;
ce3b185b 139
852c7064
SL
140 for (ip = dmp->dm_map; dmp->dm_alloc > 0; ip++) {
141 if (ip - dmp->dm_map >= NDMAP) {
142 error("vsacct NDMAP");
143 break;
144 }
145 if (*ip == 0)
146 error("vsacct *ip == 0");
147 buckets[swatodev(*ip)][index]++;
148 dmp->dm_alloc -= blk;
149 if (blk < dmmax) {
150 blk *= 2;
151 index++;
e7a897ca 152 }
e7a897ca 153 }
852c7064
SL
154}
155
156dmtoindex(dm)
157 int dm;
158{
159 register int i, j;
160
161 for (j = 0, i = dmmin; i <= dmmax; i *= 2, j++)
162 if (dm <= i)
163 return (j);
164 error("dmtoindex(%d)", dm);
165 return (NDMAP - 1);
ce3b185b 166}
d830bff6
SL
167
168static struct nlist nlst[] = {
169#define X_PROC 0
170 { "_proc" },
171#define X_NPROC 1
172 { "_nproc" },
173#define X_USRPTMAP 2
174 { "_Usrptmap" },
175#define X_USRPT 3
176 { "_usrpt" },
177#define X_NSWAP 4
178 { "_nswap" },
179#define X_DMMIN 5
180 { "_dmmin" },
181#define X_DMMAX 6
182 { "_dmmax" },
183#define X_DMTEXT 7
184 { "_dmtext" },
185#define X_NSWDEV 8
186 { "_nswdev" },
187#define X_SWDEVT 9
188 { "_swdevt" },
189#define X_NTEXT 10
190 { "_ntext" },
191#define X_TEXT 11
192 { "_text" },
193 { "" }
194};
195
196initswap()
197{
198
199 if (nlst[X_PROC].n_type == 0) {
200 nlist("/vmunix", nlst);
201 if (nlst[X_PROC].n_type == 0) {
202 error("namelist on /vmunix failed");
203 return;
204 }
205 }
206 if (nswdev == 0) {
207 dmmin = getw(nlst[X_DMMIN].n_value);
208 dmmax = getw(nlst[X_DMMAX].n_value);
209 dmtext = getw(nlst[X_DMTEXT].n_value);
210 nswdev = getw(nlst[X_NSWDEV].n_value);
211 swdevt = (struct swdevt *)calloc(nswdev, sizeof (*swdevt));
212 klseek(kmem, nlst[X_SWDEVT].n_value, L_SET);
213 read(kmem, swdevt, nswdev * sizeof (struct swdevt));
214 ntext = getw(nlst[X_NTEXT].n_value);
215 textp = getw(nlst[X_TEXT].n_value);
216 }
217 if (procp == NULL) {
218 procp = getw(nlst[X_PROC].n_value);
219 nproc = getw(nlst[X_NPROC].n_value);
220 }
221 if (xtext == NULL)
222 xtext = (struct text *)calloc(ntext, sizeof (struct text));
223 if (kprocp == NULL)
224 kprocp = (struct proc *)calloc(nproc, sizeof (struct proc));
225 if (usrpt != NULL)
226 return;
227 usrpt = (struct pte *)nlst[X_USRPT].n_value;
228 Usrptma = (struct pte *)nlst[X_USRPTMAP].n_value;
229 if (pt == NULL)
230 pt = (struct p_times *)malloc(nproc * sizeof (struct p_times));
231}
232
233fetchswap()
234{
235
236 if (nlst[X_PROC].n_type == 0)
237 return;
238 if (kprocp == NULL) {
239 kprocp = (struct proc *)malloc(sizeof (*kprocp) * nproc);
240 if (kprocp == NULL)
241 return;
242 }
243 lseek(kmem, procp, L_SET);
244 if (read(kmem, kprocp, sizeof (struct proc) * nproc) !=
245 sizeof (struct proc) * nproc) {
246 error("couldn't read proc table");
247 return;
248 }
249 if (xtext == NULL) {
250 xtext = (struct text *)calloc(ntext, sizeof (struct text));
251 if (xtext == NULL)
252 return;
253 }
254 lseek(kmem, textp, L_SET);
255 if (read(kmem, xtext, ntext * sizeof (struct text)) !=
256 sizeof (struct text) * ntext)
257 error("couldn't read text table");
258}
259
260#ifdef vax
261char *devnames[] =
262 { "hp", "ht", "up", "rk", "sw", "tm", "ts", "mt", "tu", "ra", "ut",
263 "rb", "rx", "rl" };
264#endif
265
266labelswap()
267{
268 register int i, j;
269 register int row;
270
271 if (nswdev == 0) {
272 error("Don't know how many swap devices.\n");
273 return;
274 }
275 move(5, 0);
276 colwidth = (70 - (nswdev - 1)) / nswdev;
277 row = swaplabel(5, dmtext, 1);
278 (void) swaplabel(row, dmmax, 0);
279}
280
281swaplabel(row, dmbound, donames)
282 register int row;
283 int dmbound, donames;
284{
285 register int i, j;
286
287 for (i = 0; i < nswdev; i++) {
288 if (donames) {
289 move(row, 5 + i * (1 + colwidth) + (colwidth - 3) / 2);
290 printw("%s%d", devnames[major(swdevt[i].sw_dev)],
291 minor(swdevt[i].sw_dev) >> 3);
292 }
293 for (j = 0; j + 5 < colwidth; j += 5) {
294 move(row + donames, 5 + i * (1 + colwidth) + j);
295 printw("/%-2d ", j);
296 }
297 }
298 row += 1 + donames;
299 for (j = 0, i = dmmin; i <= dmbound; i *= 2, j++, row++) {
300 int k;
301
302 mvprintw(row, 0, "%4d|", i);
303 for (k = 1; k < nswdev; k++)
304 mvwaddch(wnd, row - 3, k * (1 + colwidth) - 1, '|');
305 }
306 return (row);
307}