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