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