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[] = "@(#)swap.c 5.8 (Berkeley) 02/04/91"; 9 #endif not lint 10 11 #include "systat.h" 12 #include <sys/user.h> 13 #include <sys/proc.h> 14 #include <sys/text.h> 15 #include <sys/conf.h> 16 #include <sys/vmmac.h> 17 #include <machine/pte.h> 18 #include <paths.h> 19 20 WINDOW * 21 openswap() 22 { 23 return (subwin(stdscr, LINES-5-1, 0, 5, 0)); 24 } 25 26 closeswap(w) 27 WINDOW *w; 28 { 29 if (w == NULL) 30 return; 31 wclear(w); 32 wrefresh(w); 33 delwin(w); 34 } 35 36 int dmmin; 37 int dmmax; 38 int dmtext; 39 int nswdev; 40 #define MAXSWAPDEV 4 41 short buckets[MAXSWAPDEV][NDMAP]; 42 struct swdevt *swdevt; 43 int colwidth; 44 45 extern union { 46 struct user user; 47 char upages[UPAGES][NBPG]; 48 } user; 49 #define u user.user 50 51 showswap() 52 { 53 register int i, j; 54 register struct proc *pp; 55 register struct text *xp; 56 register int row; 57 register int ts; 58 register swblk_t *dp; 59 60 if (xtext == 0) 61 return; 62 for (xp = xtext; xp < &xtext[ntext]; xp++) { 63 if (xp->x_vptr == NULL) 64 continue; 65 ts = ctod(xp->x_size); 66 dp = xp->x_daddr; 67 for (i = 0; i < ts; i += dmtext) { 68 j = ts - i; 69 if (j > dmtext) 70 j = dmtext; 71 #define swatodev(addr) (((addr) / dmmax) % nswdev) 72 buckets[swatodev(*dp)][dmtoindex(j)]++; 73 dp++; 74 } 75 if ((xp->x_flag & XPAGV) && xp->x_ptdaddr) 76 buckets[swatodev(xp->x_ptdaddr)] 77 [dmtoindex(ctod(ctopt(xp->x_size)))]++; 78 } 79 row = swapdisplay(2, dmtext, 'X'); 80 if (kprocp == NULL) 81 return; 82 for (i = 0, pp = kprocp; i < nproc; i++, pp++) { 83 if (pp->p_stat == 0 || pp->p_stat == SZOMB) 84 continue; 85 if (pp->p_flag & SSYS) 86 continue; 87 if (getu(pp) == 0) 88 continue; 89 vsacct(&u.u_dmap); 90 vsacct(&u.u_smap); 91 #ifdef notdef 92 if ((pp->p_flag & SLOAD) == 0) 93 vusize(pp); 94 #endif 95 } 96 (void) swapdisplay(1+row, dmmax, 'X'); 97 } 98 99 #define OFFSET 5 /* left hand column */ 100 101 swapdisplay(baserow, dmbound, c) 102 int baserow, dmbound; 103 char c; 104 { 105 register int i, j, k, row; 106 register short *pb; 107 char buf[10]; 108 109 for (row = baserow, i = dmmin; i <= dmbound; i *= 2, row++) { 110 for (j = 0; j < nswdev; j++) { 111 pb = &buckets[j][row - baserow]; 112 wmove(wnd, row, OFFSET + j * (1 + colwidth)); 113 k = MIN(*pb, colwidth); 114 if (*pb > colwidth) { 115 sprintf(buf, " %d", *pb); 116 k -= strlen(buf); 117 while (k--) 118 waddch(wnd, c); 119 waddstr(wnd, buf); 120 } else { 121 while (k--) 122 waddch(wnd, c); 123 k = MAX(colwidth - *pb, 0); 124 while (k--) 125 waddch(wnd, ' '); 126 } 127 *pb = 0; 128 } 129 } 130 return (row); 131 } 132 133 vsacct(dmp) 134 register struct dmap *dmp; 135 { 136 register swblk_t *ip; 137 register int blk = dmmin, index = 0; 138 139 for (ip = dmp->dm_map; dmp->dm_alloc > 0; ip++) { 140 if (ip - dmp->dm_map >= NDMAP) { 141 error("vsacct NDMAP"); 142 break; 143 } 144 if (*ip == 0) 145 error("vsacct *ip == 0"); 146 buckets[swatodev(*ip)][index]++; 147 dmp->dm_alloc -= blk; 148 if (blk < dmmax) { 149 blk *= 2; 150 index++; 151 } 152 } 153 } 154 155 dmtoindex(dm) 156 int dm; 157 { 158 register int i, j; 159 160 for (j = 0, i = dmmin; i <= dmmax; i *= 2, j++) 161 if (dm <= i) 162 return (j); 163 error("dmtoindex(%d)", dm); 164 return (NDMAP - 1); 165 } 166 167 static struct nlist nlst[] = { 168 #define X_PROC 0 169 { "_proc" }, 170 #define X_NPROC 1 171 { "_nproc" }, 172 #define X_USRPTMAP 2 173 { "_Usrptmap" }, 174 #define X_USRPT 3 175 { "_usrpt" }, 176 #define X_NSWAP 4 177 { "_nswap" }, 178 #define X_DMMIN 5 179 { "_dmmin" }, 180 #define X_DMMAX 6 181 { "_dmmax" }, 182 #define X_DMTEXT 7 183 { "_dmtext" }, 184 #define X_NSWDEV 8 185 { "_nswdev" }, 186 #define X_SWDEVT 9 187 { "_swdevt" }, 188 #define X_NTEXT 10 189 { "_ntext" }, 190 #define X_TEXT 11 191 { "_text" }, 192 { "" } 193 }; 194 195 initswap() 196 { 197 if (nlst[X_PROC].n_type == 0) { 198 nlist(_PATH_UNIX, nlst); 199 if (nlst[X_PROC].n_type == 0) { 200 error("namelist on %s failed", _PATH_UNIX); 201 return(0); 202 } 203 } 204 if (nswdev == 0) { 205 dmmin = getword(nlst[X_DMMIN].n_value); 206 dmmax = getword(nlst[X_DMMAX].n_value); 207 dmtext = getword(nlst[X_DMTEXT].n_value); 208 nswdev = getword(nlst[X_NSWDEV].n_value); 209 if (nswdev > MAXSWAPDEV) 210 nswdev = MAXSWAPDEV; 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 = getword(nlst[X_NTEXT].n_value); 215 textp = getword(nlst[X_TEXT].n_value); 216 } 217 if (procp == NULL) { 218 procp = getword(nlst[X_PROC].n_value); 219 nproc = getword(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(1); 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 return(1); 232 } 233 234 fetchswap() 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 261 char *devnames[] = 262 { "hp", "ht", "up", "rk", "sw", "tm", "ts", "mt", "tu", "ra", "ut", 263 "rb", "rx", "rl" }; 264 #endif 265 #ifdef tahoe 266 char *devnames[] = { "ud", "vd", "xp", "cy", "sw" }; 267 #endif 268 269 labelswap() 270 { 271 register int row; 272 273 if (nswdev == 0) { 274 error("Don't know how many swap devices.\n"); 275 return; 276 } 277 colwidth = (COLS - OFFSET - (nswdev - 1)) / nswdev; 278 row = swaplabel(0, dmtext, 1); 279 (void) swaplabel(row, dmmax, 0); 280 } 281 282 swaplabel(row, dmbound, donames) 283 register int row; 284 int dmbound, donames; 285 { 286 register int i, j; 287 288 for (i = 0; i < nswdev; i++) { 289 if (donames) 290 mvwprintw(wnd, 291 row, OFFSET + i*(1 + colwidth) + (colwidth - 3)/2, 292 "%s%d", devnames[major(swdevt[i].sw_dev)], 293 minor(swdevt[i].sw_dev) >> 3); 294 for (j = 0; j + 5 < colwidth; j += 5) 295 mvwprintw(wnd, row + donames, 296 OFFSET + i*(1 + colwidth) + j, "/%-2d ", j); 297 } 298 row += 1 + donames; 299 for (j = 0, i = dmmin; i <= dmbound; i *= 2, j++, row++) { 300 int k; 301 302 mvwprintw(wnd, row, 0, "%4d|", i); 303 for (k = 1; k < nswdev; k++) 304 mvwaddch(wnd, row, OFFSET + k*(1 + colwidth) - 1, '|'); 305 } 306 return (row); 307 } 308