/* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ #ifndef lint static char sccsid[] = "@(#)swap.c 5.3 (Berkeley) 4/12/86"; #endif not lint #include "systat.h" #include #include #include #include #include #include #include WINDOW * openswap() { return (subwin(stdscr, LINES-5-1, 0, 5, 0)); } closeswap(w) WINDOW *w; { if (w == NULL) return; wclear(w); wrefresh(w); delwin(w); } int dmmin; int dmmax; int dmtext; int nswdev; #define MAXSWAPDEV 4 short buckets[MAXSWAPDEV][NDMAP]; struct swdevt *swdevt; int colwidth; extern union { struct user user; char upages[UPAGES][NBPG]; } user; #define u user.user showswap() { register int i, j; register struct proc *pp; register struct text *xp; register int row; register int ts; register swblk_t *dp; if (xtext == 0) return; for (xp = xtext; xp < &xtext[ntext]; xp++) { if (xp->x_iptr == NULL) continue; ts = ctod(xp->x_size); dp = xp->x_daddr; for (i = 0; i < ts; i += dmtext) { j = ts - i; if (j > dmtext) j = dmtext; #define swatodev(addr) (((addr) / dmmax) % nswdev) buckets[swatodev(*dp)][dmtoindex(j)]++; dp++; } if ((xp->x_flag & XPAGI) && xp->x_ptdaddr) buckets[swatodev(xp->x_ptdaddr)] [dmtoindex(ctod(ctopt(xp->x_size)))]++; } row = swapdisplay(2, dmtext, 'X'); if (kprocp == NULL) return; for (i = 0, pp = kprocp; i < nproc; i++, pp++) { if (pp->p_stat == 0 || pp->p_stat == SZOMB) continue; if (pp->p_flag & SSYS) continue; if (getu(pp) == 0) continue; vsacct(&u.u_dmap); vsacct(&u.u_smap); #ifdef notdef if ((pp->p_flag & SLOAD) == 0) vusize(pp); #endif } (void) swapdisplay(1+row, dmmax, 'X'); } #define OFFSET 5 /* left hand column */ swapdisplay(baserow, dmbound, c) int baserow, dmbound; char c; { register int i, j, k, row; register short *pb; char buf[10]; for (row = baserow, i = dmmin; i <= dmbound; i *= 2, row++) { for (j = 0; j < nswdev; j++) { pb = &buckets[j][row - baserow]; wmove(wnd, row, OFFSET + j * (1 + colwidth)); k = MIN(*pb, colwidth); if (*pb > colwidth) { sprintf(buf, " %d", *pb); k -= strlen(buf); while (k--) waddch(wnd, c); waddstr(wnd, buf); } else { while (k--) waddch(wnd, c); k = MAX(colwidth - *pb, 0); while (k--) waddch(wnd, ' '); } *pb = 0; } } return (row); } vsacct(dmp) register struct dmap *dmp; { register swblk_t *ip; register int blk = dmmin, index = 0; for (ip = dmp->dm_map; dmp->dm_alloc > 0; ip++) { if (ip - dmp->dm_map >= NDMAP) { error("vsacct NDMAP"); break; } if (*ip == 0) error("vsacct *ip == 0"); buckets[swatodev(*ip)][index]++; dmp->dm_alloc -= blk; if (blk < dmmax) { blk *= 2; index++; } } } dmtoindex(dm) int dm; { register int i, j; for (j = 0, i = dmmin; i <= dmmax; i *= 2, j++) if (dm <= i) return (j); error("dmtoindex(%d)", dm); return (NDMAP - 1); } static struct nlist nlst[] = { #define X_PROC 0 { "_proc" }, #define X_NPROC 1 { "_nproc" }, #define X_USRPTMAP 2 { "_Usrptmap" }, #define X_USRPT 3 { "_usrpt" }, #define X_NSWAP 4 { "_nswap" }, #define X_DMMIN 5 { "_dmmin" }, #define X_DMMAX 6 { "_dmmax" }, #define X_DMTEXT 7 { "_dmtext" }, #define X_NSWDEV 8 { "_nswdev" }, #define X_SWDEVT 9 { "_swdevt" }, #define X_NTEXT 10 { "_ntext" }, #define X_TEXT 11 { "_text" }, { "" } }; initswap() { if (nlst[X_PROC].n_type == 0) { nlist("/vmunix", nlst); if (nlst[X_PROC].n_type == 0) { error("namelist on /vmunix failed"); return(0); } } if (nswdev == 0) { dmmin = getw(nlst[X_DMMIN].n_value); dmmax = getw(nlst[X_DMMAX].n_value); dmtext = getw(nlst[X_DMTEXT].n_value); nswdev = getw(nlst[X_NSWDEV].n_value); if (nswdev > MAXSWAPDEV) nswdev = MAXSWAPDEV; swdevt = (struct swdevt *)calloc(nswdev, sizeof (*swdevt)); klseek(kmem, nlst[X_SWDEVT].n_value, L_SET); read(kmem, swdevt, nswdev * sizeof (struct swdevt)); ntext = getw(nlst[X_NTEXT].n_value); textp = getw(nlst[X_TEXT].n_value); } if (procp == NULL) { procp = getw(nlst[X_PROC].n_value); nproc = getw(nlst[X_NPROC].n_value); } if (xtext == NULL) xtext = (struct text *)calloc(ntext, sizeof (struct text)); if (kprocp == NULL) kprocp = (struct proc *)calloc(nproc, sizeof (struct proc)); if (usrpt != NULL) return(1); usrpt = (struct pte *)nlst[X_USRPT].n_value; Usrptma = (struct pte *)nlst[X_USRPTMAP].n_value; if (pt == NULL) pt = (struct p_times *)malloc(nproc * sizeof (struct p_times)); return(1); } fetchswap() { if (nlst[X_PROC].n_type == 0) return; if (kprocp == NULL) { kprocp = (struct proc *)malloc(sizeof (*kprocp) * nproc); if (kprocp == NULL) return; } lseek(kmem, procp, L_SET); if (read(kmem, kprocp, sizeof (struct proc) * nproc) != sizeof (struct proc) * nproc) { error("couldn't read proc table"); return; } if (xtext == NULL) { xtext = (struct text *)calloc(ntext, sizeof (struct text)); if (xtext == NULL) return; } lseek(kmem, textp, L_SET); if (read(kmem, xtext, ntext * sizeof (struct text)) != sizeof (struct text) * ntext) error("couldn't read text table"); } #ifdef vax char *devnames[] = { "hp", "ht", "up", "rk", "sw", "tm", "ts", "mt", "tu", "ra", "ut", "rb", "rx", "rl" }; #endif labelswap() { register int row; if (nswdev == 0) { error("Don't know how many swap devices.\n"); return; } colwidth = (COLS - OFFSET - (nswdev - 1)) / nswdev; row = swaplabel(0, dmtext, 1); (void) swaplabel(row, dmmax, 0); } swaplabel(row, dmbound, donames) register int row; int dmbound, donames; { register int i, j; for (i = 0; i < nswdev; i++) { if (donames) mvwprintw(wnd, row, OFFSET + i*(1 + colwidth) + (colwidth - 3)/2, "%s%d", devnames[major(swdevt[i].sw_dev)], minor(swdevt[i].sw_dev) >> 3); for (j = 0; j + 5 < colwidth; j += 5) mvwprintw(wnd, row + donames, OFFSET + i*(1 + colwidth) + j, "/%-2d ", j); } row += 1 + donames; for (j = 0, i = dmmin; i <= dmbound; i *= 2, j++, row++) { int k; mvwprintw(wnd, row, 0, "%4d|", i); for (k = 1; k < nswdev; k++) mvwaddch(wnd, row, OFFSET + k*(1 + colwidth) - 1, '|'); } return (row); }