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.9 (Berkeley) 06/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 <sys/stat.h> 18 #include <machine/pte.h> 19 #include <paths.h> 20 21 WINDOW * 22 openswap() 23 { 24 return (subwin(stdscr, LINES-5-1, 0, 5, 0)); 25 } 26 27 closeswap(w) 28 WINDOW *w; 29 { 30 if (w == NULL) 31 return; 32 wclear(w); 33 wrefresh(w); 34 delwin(w); 35 } 36 37 int dmmin; 38 int dmmax; 39 int dmtext; 40 int nswdev; 41 #define MAXSWAPDEV 4 42 short buckets[MAXSWAPDEV][NDMAP]; 43 struct swdevt *swdevt; 44 int colwidth; 45 46 extern union { 47 struct user user; 48 char upages[UPAGES][NBPG]; 49 } user; 50 #define u user.user 51 52 showswap() 53 { 54 register int i, j; 55 register struct proc *pp; 56 register struct text *xp; 57 register int row; 58 register int ts; 59 register swblk_t *dp; 60 61 if (xtext == 0) 62 return; 63 for (xp = xtext; xp < &xtext[ntext]; xp++) { 64 if (xp->x_vptr == NULL) 65 continue; 66 ts = ctod(xp->x_size); 67 dp = xp->x_daddr; 68 for (i = 0; i < ts; i += dmtext) { 69 j = ts - i; 70 if (j > dmtext) 71 j = dmtext; 72 #define swatodev(addr) (((addr) / dmmax) % nswdev) 73 buckets[swatodev(*dp)][dmtoindex(j)]++; 74 dp++; 75 } 76 if ((xp->x_flag & XPAGV) && xp->x_ptdaddr) 77 buckets[swatodev(xp->x_ptdaddr)] 78 [dmtoindex(ctod(ctopt(xp->x_size)))]++; 79 } 80 row = swapdisplay(2, dmtext, 'X'); 81 if (kprocp == NULL) 82 return; 83 for (i = 0, pp = kprocp; i < nproc; i++, pp++) { 84 if (pp->p_stat == 0 || pp->p_stat == SZOMB) 85 continue; 86 if (pp->p_flag & SSYS) 87 continue; 88 if (getu(pp) == 0) 89 continue; 90 vsacct(&u.u_dmap); 91 vsacct(&u.u_smap); 92 #ifdef notdef 93 if ((pp->p_flag & SLOAD) == 0) 94 vusize(pp); 95 #endif 96 } 97 (void) swapdisplay(1+row, dmmax, 'X'); 98 } 99 100 #define OFFSET 5 /* left hand column */ 101 102 swapdisplay(baserow, dmbound, c) 103 int baserow, dmbound; 104 char c; 105 { 106 register int i, j, k, row; 107 register short *pb; 108 char buf[10]; 109 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, OFFSET + 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, ' '); 127 } 128 *pb = 0; 129 } 130 } 131 return (row); 132 } 133 134 vsacct(dmp) 135 register struct dmap *dmp; 136 { 137 register swblk_t *ip; 138 register int blk = dmmin, index = 0; 139 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++; 152 } 153 } 154 } 155 156 dmtoindex(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); 166 } 167 168 static 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 196 initswap() 197 { 198 if (nlst[X_PROC].n_type == 0) { 199 nlist(_PATH_UNIX, nlst); 200 if (nlst[X_PROC].n_type == 0) { 201 error("namelist on %s failed", _PATH_UNIX); 202 return(0); 203 } 204 } 205 if (nswdev == 0) { 206 dmmin = getword(nlst[X_DMMIN].n_value); 207 dmmax = getword(nlst[X_DMMAX].n_value); 208 dmtext = getword(nlst[X_DMTEXT].n_value); 209 nswdev = getword(nlst[X_NSWDEV].n_value); 210 if (nswdev > MAXSWAPDEV) 211 nswdev = MAXSWAPDEV; 212 swdevt = (struct swdevt *)calloc(nswdev, sizeof (*swdevt)); 213 klseek(kmem, nlst[X_SWDEVT].n_value, L_SET); 214 read(kmem, swdevt, nswdev * sizeof (struct swdevt)); 215 ntext = getword(nlst[X_NTEXT].n_value); 216 textp = getword(nlst[X_TEXT].n_value); 217 } 218 if (procp == NULL) { 219 procp = getword(nlst[X_PROC].n_value); 220 nproc = getword(nlst[X_NPROC].n_value); 221 } 222 if (xtext == NULL) 223 xtext = (struct text *)calloc(ntext, sizeof (struct text)); 224 if (kprocp == NULL) 225 kprocp = (struct proc *)calloc(nproc, sizeof (struct proc)); 226 if (usrpt != NULL) 227 return(1); 228 usrpt = (struct pte *)nlst[X_USRPT].n_value; 229 Usrptma = (struct pte *)nlst[X_USRPTMAP].n_value; 230 if (pt == NULL) 231 pt = (struct p_times *)malloc(nproc * sizeof (struct p_times)); 232 return(1); 233 } 234 235 fetchswap() 236 { 237 if (nlst[X_PROC].n_type == 0) 238 return; 239 if (kprocp == NULL) { 240 kprocp = (struct proc *)malloc(sizeof (*kprocp) * nproc); 241 if (kprocp == NULL) 242 return; 243 } 244 lseek(kmem, procp, L_SET); 245 if (read(kmem, kprocp, sizeof (struct proc) * nproc) != 246 sizeof (struct proc) * nproc) { 247 error("couldn't read proc table"); 248 return; 249 } 250 if (xtext == NULL) { 251 xtext = (struct text *)calloc(ntext, sizeof (struct text)); 252 if (xtext == NULL) 253 return; 254 } 255 lseek(kmem, textp, L_SET); 256 if (read(kmem, xtext, ntext * sizeof (struct text)) != 257 sizeof (struct text) * ntext) 258 error("couldn't read text table"); 259 } 260 261 labelswap() 262 { 263 register int row; 264 265 if (nswdev == 0) { 266 error("Don't know how many swap devices.\n"); 267 return; 268 } 269 colwidth = (COLS - OFFSET - (nswdev - 1)) / nswdev; 270 row = swaplabel(0, dmtext, 1); 271 (void) swaplabel(row, dmmax, 0); 272 } 273 274 swaplabel(row, dmbound, donames) 275 register int row; 276 int dmbound, donames; 277 { 278 register int i, j; 279 280 for (i = 0; i < nswdev; i++) { 281 if (donames) 282 mvwprintw(wnd, 283 row, OFFSET + i*(1 + colwidth) + (colwidth - 3)/2, 284 "%s", devname(swdevt[i].sw_dev, S_IFBLK)); 285 for (j = 0; j + 5 < colwidth; j += 5) 286 mvwprintw(wnd, row + donames, 287 OFFSET + i*(1 + colwidth) + j, "/%-2d ", j); 288 } 289 row += 1 + donames; 290 for (j = 0, i = dmmin; i <= dmbound; i *= 2, j++, row++) { 291 int k; 292 293 mvwprintw(wnd, row, 0, "%4d|", i); 294 for (k = 1; k < nswdev; k++) 295 mvwaddch(wnd, row, OFFSET + k*(1 + colwidth) - 1, '|'); 296 } 297 return (row); 298 } 299