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.3 (Berkeley) 4/12/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: 270: labelswap() 271: { 272: register int row; 273: 274: if (nswdev == 0) { 275: error("Don't know how many swap devices.\n"); 276: return; 277: } 278: colwidth = (COLS - OFFSET - (nswdev - 1)) / nswdev; 279: row = swaplabel(0, dmtext, 1); 280: (void) swaplabel(row, dmmax, 0); 281: } 282: 283: swaplabel(row, dmbound, donames) 284: register int row; 285: int dmbound, donames; 286: { 287: register int i, j; 288: 289: for (i = 0; i < nswdev; i++) { 290: if (donames) 291: mvwprintw(wnd, 292: row, OFFSET + i*(1 + colwidth) + (colwidth - 3)/2, 293: "%s%d", devnames[major(swdevt[i].sw_dev)], 294: minor(swdevt[i].sw_dev) >> 3); 295: for (j = 0; j + 5 < colwidth; j += 5) 296: mvwprintw(wnd, row + donames, 297: OFFSET + i*(1 + colwidth) + j, "/%-2d ", j); 298: } 299: row += 1 + donames; 300: for (j = 0, i = dmmin; i <= dmbound; i *= 2, j++, row++) { 301: int k; 302: 303: mvwprintw(wnd, row, 0, "%4d|", i); 304: for (k = 1; k < nswdev; k++) 305: mvwaddch(wnd, row, OFFSET + k*(1 + colwidth) - 1, '|'); 306: } 307: return (row); 308: }