add init routine and mbuf display; redo swap space display
authorSam Leffler <sam@ucbvax.Berkeley.EDU>
Mon, 3 Oct 1983 06:40:33 +0000 (22:40 -0800)
committerSam Leffler <sam@ucbvax.Berkeley.EDU>
Mon, 3 Oct 1983 06:40:33 +0000 (22:40 -0800)
SCCS-vsn: usr.bin/systat/Makefile 1.2
SCCS-vsn: usr.bin/systat/fetch.c 1.2
SCCS-vsn: usr.bin/systat/main.c 1.3
SCCS-vsn: usr.bin/systat/pigs.c 1.2
SCCS-vsn: usr.bin/systat/swap.c 1.3

usr/src/usr.bin/systat/Makefile
usr/src/usr.bin/systat/fetch.c
usr/src/usr.bin/systat/main.c
usr/src/usr.bin/systat/pigs.c
usr/src/usr.bin/systat/swap.c

index 76797fa..829dfa7 100644 (file)
@@ -1,7 +1,7 @@
-#       Makefile     1.1     83/10/01
+#       Makefile     1.2     83/10/02
 DESTDIR=
 CFLAGS= -O
 DESTDIR=
 CFLAGS= -O
-OBJS=   main.o fetch.o pigs.o swap.o
+OBJS=   main.o fetch.o pigs.o swap.o mbufs.o
 LIBS=   -lcurses -ltermlib -lm
 
 systat: ${OBJS}
 LIBS=   -lcurses -ltermlib -lm
 
 systat: ${OBJS}
@@ -11,6 +11,7 @@ main.o:       systat.h
 fetch.o:systat.h
 pigs.o:        systat.h
 swap.o:        systat.h
 fetch.o:systat.h
 pigs.o:        systat.h
 swap.o:        systat.h
+mbufs.o:systat.h
 
 install: systat
        install -s systat ${DESTDIR}/usr/lfl/bin/systat
 
 install: systat
        install -s systat ${DESTDIR}/usr/lfl/bin/systat
index 2b48662..6d11748 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)fetch.c    1.1 (Lucasfilm) %G%";
+static char sccsid[] = "@(#)fetch.c    1.2 (Lucasfilm) %G%";
 #endif
 
 #include "systat.h"
 #endif
 
 #include "systat.h"
@@ -58,10 +58,16 @@ getcmd(pid, mproc)
 {
         static char cmd[30];
 
 {
         static char cmd[30];
 
-        if (mproc == NULL || mproc->p_stat == SZOMB ||
-            mproc->p_flag&(SSYS|SWEXIT))
+        if (mproc == NULL || mproc->p_stat == SZOMB)
+               return ("");
+       if (pid == 1)
+               return ("swapper");
+       if (pid == 2)
+               return ("pagedaemon");
+        if (mproc->p_flag&(SSYS|SWEXIT))
                 return ("");
                 return ("");
-        getu(mproc);
+        if (getu(mproc) == 0)
+               return ("???");
         (void) strncpy(cmd, u.u_comm, sizeof (cmd));
         return (cmd);
 }
         (void) strncpy(cmd, u.u_comm, sizeof (cmd));
         return (cmd);
 }
@@ -80,8 +86,7 @@ getu(mproc)
                         return (0);
                 (void) lseek(swap, (long)dtob(mproc->p_swaddr), L_SET);
                 if (read(swap, (char *)&user.user, size) != size) {
                         return (0);
                 (void) lseek(swap, (long)dtob(mproc->p_swaddr), L_SET);
                 if (read(swap, (char *)&user.user, size) != size) {
-                        fprintf(stderr, "ps: cant read u for pid %d from %s\n",
-                            mproc->p_pid, swapf);
+                       error("cant read u for pid %d", mproc->p_pid);
                         return (0);
                 }
                 pcbpf = 0;
                         return (0);
                 }
                 pcbpf = 0;
@@ -91,16 +96,14 @@ getu(mproc)
         pteaddr = &Usrptma[btokmx(mproc->p_p0br) + mproc->p_szpt - 1];
         klseek(kmem, (long)pteaddr, L_SET);
         if (read(kmem, (char *)&apte, sizeof (apte)) != sizeof (apte)) {
         pteaddr = &Usrptma[btokmx(mproc->p_p0br) + mproc->p_szpt - 1];
         klseek(kmem, (long)pteaddr, L_SET);
         if (read(kmem, (char *)&apte, sizeof (apte)) != sizeof (apte)) {
-                printf("ps: cant read indir pte to get u for pid %d from %s\n",
-                    mproc->p_pid, swapf);
+                error("cant read indir pte to get u for pid %d", mproc->p_pid);
                 return (0);
         }
         klseek(mem,
             (long)ctob(apte.pg_pfnum+1) - (UPAGES+CLSIZE) * sizeof (struct pte),
                 L_SET);
         if (read(mem, (char *)arguutl, sizeof (arguutl)) != sizeof (arguutl)) {
                 return (0);
         }
         klseek(mem,
             (long)ctob(apte.pg_pfnum+1) - (UPAGES+CLSIZE) * sizeof (struct pte),
                 L_SET);
         if (read(mem, (char *)arguutl, sizeof (arguutl)) != sizeof (arguutl)) {
-                printf("ps: cant read page table for u of pid %d from %s\n",
-                    mproc->p_pid, kmemf);
+                error("cant read page table for u of pid %d", mproc->p_pid);
                 return (0);
         }
         if (arguutl[0].pg_fod == 0 && arguutl[0].pg_pfnum)
                 return (0);
         }
         if (arguutl[0].pg_fod == 0 && arguutl[0].pg_pfnum)
@@ -113,9 +116,9 @@ getu(mproc)
                 i = ncl * CLSIZE;
                 klseek(mem, (long)ctob(arguutl[CLSIZE+i].pg_pfnum), L_SET);
                 if (read(mem, user.upages[i], CLSIZE*NBPG) != CLSIZE*NBPG) {
                 i = ncl * CLSIZE;
                 klseek(mem, (long)ctob(arguutl[CLSIZE+i].pg_pfnum), L_SET);
                 if (read(mem, user.upages[i], CLSIZE*NBPG) != CLSIZE*NBPG) {
-                        printf("ps: cant read page %d of u of pid %d from %s\n",
-                            arguutl[CLSIZE+i].pg_pfnum, mproc->p_pid, memf);
-                        return(0);
+                        error("cant read page %d of u of pid %d\n",
+                            arguutl[CLSIZE+i].pg_pfnum, mproc->p_pid);
+                        return (0);
                 }
         }
         return (1);
                 }
         }
         return (1);
index f9e2abc..94bdab4 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)main.c     1.2 (Lucasfilm) %G%";
+static char sccsid[] = "@(#)main.c     1.3 (Lucasfilm) %G%";
 #endif
 
 #include "systat.h"
 #endif
 
 #include "systat.h"
@@ -31,6 +31,14 @@ struct nlist nlst[] = {
         { "_nswdev" },
 #define        X_SWDEVT        12
        { "_swdevt" },
         { "_nswdev" },
 #define        X_SWDEVT        12
        { "_swdevt" },
+#define        X_NTEXT         13
+       { "_ntext" },
+#define        X_TEXT          14
+       { "_text" },
+#define        X_DMTEXT        15
+       { "_dmtext" },
+#define        X_MBSTAT        16
+       { "_mbstat" },
         { "" }
 };
 
         { "" }
 };
 
@@ -43,10 +51,13 @@ int     die();
 int     display();
 int     suspend();
 
 int     display();
 int     suspend();
 
-int     showpigs(), openpigs(), fetchpigs(), labelpigs();
-int     showswap(), fetchswap(), labelswap();
-int     showuser(), openuser(), fetchuser(), labeluser();
-int     shownet(), opennet(), fetchnet(), labelnet();
+int     showpigs(), openpigs(), fetchpigs(), labelpigs(), initpigs();
+int     showswap(), fetchswap(), labelswap(), initswap();
+int    showmbufs(), fetchmbufs(), labelmbufs(), initmbufs();
+#ifdef notdef
+int     showuser(), openuser(), fetchuser(), labeluser(), inituser();
+int     shownet(), opennet(), fetchnet(), labelnet(), initnet();
+#endif
 
 struct  cmdtab {
         char    *c_name;
 
 struct  cmdtab {
         char    *c_name;
@@ -54,16 +65,20 @@ struct  cmdtab {
         int     (*c_open)();
         int     (*c_fetch)();
         int     (*c_label)();
         int     (*c_open)();
         int     (*c_fetch)();
         int     (*c_label)();
+       int     (*c_init)();
+       char    c_flags;
 } cmdtab[] = {
         { "pigs",       showpigs,       openpigs,       fetchpigs,
 } cmdtab[] = {
         { "pigs",       showpigs,       openpigs,       fetchpigs,
-          labelpigs },
+          labelpigs,   initpigs },
         { "swap",       showswap,       openpigs,       fetchswap,
         { "swap",       showswap,       openpigs,       fetchswap,
-          labelswap },
+          labelswap,   initswap },
+        { "mbufs",     showmbufs,      openpigs,       fetchmbufs,
+          labelmbufs,  initmbufs },
 #ifdef notdef
         { "user",       showuser,       openuser,       fetchuser,
 #ifdef notdef
         { "user",       showuser,       openuser,       fetchuser,
-          labeluser },
+          labeluser,   inituser },
         { "net",        shownet,        opennet,        fetchnet,
         { "net",        shownet,        opennet,        fetchnet,
-          labelnet },
+          labelnet,    initnet },
 #endif
         { "" }
 };
 #endif
         { "" }
 };
@@ -112,7 +127,6 @@ main(argc, argv)
         lseek(kmem, nlst[X_CCPU].n_value, 0);
         read(kmem, &ccpu, sizeof (ccpu));
         lccpu = log(ccpu);
         lseek(kmem, nlst[X_CCPU].n_value, 0);
         read(kmem, &ccpu, sizeof (ccpu));
         lccpu = log(ccpu);
-        (*curcmd->c_fetch)();
         labels();
 
         known[0].k_uid = -1;
         labels();
 
         known[0].k_uid = -1;
@@ -138,8 +152,12 @@ main(argc, argv)
                         if (ch >= 'A' && ch <= 'Z')
                                 ch += 'a' - 'A';
                         if (col == 0) {
                         if (ch >= 'A' && ch <= 'Z')
                                 ch += 'a' - 'A';
                         if (col == 0) {
+#define        mask(s) (1 << ((s) - 1))
                                 if (ch == CTRL(l)) {
                                 if (ch == CTRL(l)) {
-                                        wrefresh(curscr);
+                                       int oldmask = sigblock(mask(SIGALRM));
+
+                                       wrefresh(curscr);
+                                       sigsetmask(oldmask);
                                         continue;
                                 }
                                 if (ch != ':')
                                         continue;
                                 }
                                 if (ch != ':')
@@ -303,6 +321,10 @@ display()
         /* Get the load average over the last minute. */
         lseek(kmem, nlst[X_AVENRUN].n_value, L_SET);
         read(kmem, &lave, sizeof (lave));
         /* Get the load average over the last minute. */
         lseek(kmem, nlst[X_AVENRUN].n_value, L_SET);
         read(kmem, &lave, sizeof (lave));
+       if (curcmd->c_flags == 0) {
+               (*curcmd->c_init)();
+               curcmd->c_flags = 1;
+       }
         (*curcmd->c_fetch)();
         j = 5.0*lave + 0.5;
         dellave -= lave;
         (*curcmd->c_fetch)();
         j = 5.0*lave + 0.5;
         dellave -= lave;
@@ -334,3 +356,11 @@ die()
         endwin();
         exit(0);
 }
         endwin();
         exit(0);
 }
+
+error(fmt, a1, a2, a3)
+{
+
+       mvprintw(22, 0, fmt, a1, a2, a3);
+       clrtoeol();
+       refresh();
+}
index f219ffa..a496efd 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)pigs.c     1.1 (Lucasfilm) %G%";
+static char sccsid[] = "@(#)pigs.c     1.2 (Lucasfilm) %G%";
 #endif
 
 #include "systat.h"
 #endif
 
 #include "systat.h"
@@ -134,24 +134,28 @@ openpigs()
 
 struct proc *kprocp;
 
 
 struct proc *kprocp;
 
-fetchpigs()
+initpigs()
 {
 {
-        register int i;
-        register struct p_times *prt;
-        register float time;
-        register struct proc *pp;
 
         if (procp == NULL) {
                 procp = getw(nlst[X_PROC].n_value);
                 nproc = getw(nlst[X_NPROC].n_value);
                 kprocp = (struct proc *)malloc(sizeof (*kprocp) * nproc);
         }
 
         if (procp == NULL) {
                 procp = getw(nlst[X_PROC].n_value);
                 nproc = getw(nlst[X_NPROC].n_value);
                 kprocp = (struct proc *)malloc(sizeof (*kprocp) * nproc);
         }
-        if (usrpt == NULL) {
-                usrpt = (struct pte *)nlst[X_USRPT].n_value;
-                Usrptma = (struct pte *)nlst[X_USRPTMAP].n_value;
-                pt = (struct p_times *)malloc(nproc * sizeof (struct p_times));
-                return;
-        }
+        if (usrpt != NULL)
+               return;
+       usrpt = (struct pte *)nlst[X_USRPT].n_value;
+       Usrptma = (struct pte *)nlst[X_USRPTMAP].n_value;
+       pt = (struct p_times *)malloc(nproc * sizeof (struct p_times));
+}
+
+fetchpigs()
+{
+        register int i;
+        register struct p_times *prt;
+        register float time;
+        register struct proc *pp;
+
         prt = pt;
         lseek(kmem, procp, L_SET);
         read(kmem, kprocp, sizeof (struct proc) * nproc);
         prt = pt;
         lseek(kmem, procp, L_SET);
         read(kmem, kprocp, sizeof (struct proc) * nproc);
index 6a8e8f2..b55e409 100644 (file)
@@ -1,51 +1,73 @@
 #ifndef lint
 #ifndef lint
-static char *sccsid = "@(#)swap.c      1.2 (Lucasfilm) %G%";
+static char *sccsid = "@(#)swap.c      1.3 (Lucasfilm) %G%";
 #endif
 
 #include "systat.h"
 
 #include <sys/map.h>
 #include <sys/conf.h>
 #endif
 
 #include "systat.h"
 
 #include <sys/map.h>
 #include <sys/conf.h>
+#include <sys/text.h>
 
 /* these don't belong here */
 
 /* these don't belong here */
+#define X_PROC          0
+#define X_NPROC         1
+#define X_USRPTMAP      4
+#define X_USRPT         5
 #define X_NSWAP         6
 #define X_NSWAP         6
-#define X_SWAPMAP       7
-#define X_NSWAPMAP      8
 #define X_DMMIN         9
 #define X_DMMAX         10
 #define X_NSWDEV        11
 #define        X_SWDEVT        12
 #define X_DMMIN         9
 #define X_DMMAX         10
 #define X_NSWDEV        11
 #define        X_SWDEVT        12
-
-static  int dmmin;
-static  int dmmax;
-static  int nswdev;
-static  int nswapmap;
-static  int nswap;
-static  struct map *swapmap;
-static short *buckets;
-static short *overflow;
+#define        X_NTEXT         13
+#define        X_TEXT          14
+#define        X_DMTEXT        15
+
+int    dmmin;
+int    dmmax;
+int    dmtext;
+int    nswdev;
+#define        MAXSWAPDEV      4
+short  buckets[MAXSWAPDEV][NDMAP];
 struct swdevt *swdevt;
 struct swdevt *swdevt;
+struct proc *kprocp;
+int    ntext;
+int    textaddr;
+struct text *xtext;
 
 
-fetchswap()
+initswap()
 {
 
 {
 
-        if (nswapmap == 0) {
-                nswapmap = getw(nlst[X_NSWAPMAP].n_value);
-                swapmap = (struct map *)calloc(nswapmap, sizeof (struct map));
-                nswap = getw(nlst[X_NSWAP].n_value);
+        if (nswdev == 0) {
                 dmmin = getw(nlst[X_DMMIN].n_value);
                 dmmax = getw(nlst[X_DMMAX].n_value);
                 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);
                 nswdev = getw(nlst[X_NSWDEV].n_value);
-               buckets = (short *)calloc(nswdev, sizeof (short));
-               overflow = (short *)calloc(nswdev, sizeof (short));
                swdevt = (struct swdevt *)calloc(nswdev, sizeof (*swdevt));
                klseek(kmem, nlst[X_SWDEVT].n_value, L_SET);
                read(kmem, swdevt, nswdev * sizeof (struct swdevt));
                swdevt = (struct swdevt *)calloc(nswdev, sizeof (*swdevt));
                klseek(kmem, nlst[X_SWDEVT].n_value, L_SET);
                read(kmem, swdevt, nswdev * sizeof (struct swdevt));
-               swapmap->m_name = "swap";
-                return;
+               ntext = getw(nlst[X_NTEXT].n_value);
+               xtext = (struct text *)calloc(ntext, sizeof (struct text));
+               textaddr = getw(nlst[X_TEXT].n_value);
         }
         }
-        klseek(kmem, getw(nlst[X_SWAPMAP].n_value), L_SET);
-        read(kmem, swapmap, nswapmap * sizeof (struct map));
+        if (procp == NULL) {
+                procp = getw(nlst[X_PROC].n_value);
+                nproc = getw(nlst[X_NPROC].n_value);
+                kprocp = (struct proc *)malloc(sizeof (*kprocp) * nproc);
+        }
+        if (usrpt != NULL)
+                return;
+       usrpt = (struct pte *)nlst[X_USRPT].n_value;
+       Usrptma = (struct pte *)nlst[X_USRPTMAP].n_value;
+       pt = (struct p_times *)malloc(nproc * sizeof (struct p_times));
+}
+
+fetchswap()
+{
+
+        lseek(kmem, procp, L_SET);
+        read(kmem, kprocp, sizeof (struct proc) * nproc);
+       lseek(kmem, textaddr, L_SET);
+       read(kmem, xtext, ntext * sizeof (struct text));
 }
 
 #ifdef vax
 }
 
 #ifdef vax
@@ -58,245 +80,164 @@ int       colwidth;
 labelswap()
 {
        register int i, j;
 labelswap()
 {
        register int i, j;
+       register int row;
 
        if (nswdev == 0)
 
        if (nswdev == 0)
-               fetchswap();
+               initswap();
        if (nswdev == 0) {
                mvaddstr(22, 0, "Can't find number of swap devices.\n");
                return;
        }
         move(5, 0);
        colwidth = (70 - (nswdev - 1)) / nswdev;
        if (nswdev == 0) {
                mvaddstr(22, 0, "Can't find number of swap devices.\n");
                return;
        }
         move(5, 0);
        colwidth = (70 - (nswdev - 1)) / nswdev;
+       row = swaplabel(5, 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++) {
        for (i = 0; i < nswdev; i++) {
-               move(5, 5 + i * (1 + colwidth) + (colwidth - 3) / 2);
-               printw("%s%d", devnames[major(swdevt[i].sw_dev)],
-                   minor(swdevt[i].sw_dev) >> 3);
+               if (donames) {
+                       move(row, 5 + i * (1 + colwidth) + (colwidth - 3) / 2);
+                       printw("%s%d", devnames[major(swdevt[i].sw_dev)],
+                           minor(swdevt[i].sw_dev) >> 3);
+               }
                for (j = 0; j + 5 < colwidth; j += 5) {
                for (j = 0; j + 5 < colwidth; j += 5) {
-                       move(6, 5 + i * (1 + colwidth) + j);
+                       move(row + donames, 5 + i * (1 + colwidth) + j);
                        printw("/%-2d  ", j);
                }
        }
                        printw("/%-2d  ", j);
                }
        }
-       for (j = 0, i = dmmax; i >= dmmin; i /= 2, j++) {
+       row += 1 + donames;
+       for (j = 0, i = dmmin; i <= dmbound; i *= 2, j++, row++) {
                int k;
 
                int k;
 
-               mvprintw(7 + j, 0, "%4d|", i);
+               mvprintw(row, 0, "%4d|", i);
                for (k = 1; k < nswdev; k++)
                for (k = 1; k < nswdev; k++)
-                       mvwaddch(wnd, 4 + j, k * (1 + colwidth) - 1, '|');
+                       mvwaddch(wnd, row - 3, k * (1 + colwidth) - 1, '|');
        }
        }
+       return (row);
 }
 
 }
 
+extern union {
+        struct  user user;
+        char    upages[UPAGES][NBPG];
+} user;
+#define u       user.user
+
 showswap()
 {
         register int i, j;
 showswap()
 {
         register int i, j;
+       register struct proc *pp;
+       register struct text *xp;
        register int row;
        register int row;
+       register int ts;
+       register swblk_t *dp;
 
        if (nswdev == 0)
                return;
 
        if (nswdev == 0)
                return;
-       for (row = 4, i = dmmax; i >= dmmin; i /= 2, row++) {
-move(22, 0); clrtoeol(); printw("size %d", i); refresh();
-               do {
-                       j = rmalloc(swapmap, i);
-                       if (j)
-                               buckets[(j / dmmax) % nswdev]++;
-               } while (j);
-               for (j = 0; j < nswdev; j++) {
-                       register int k;
-move(21 - j, 0); clrtoeol();
-printw("buckets[%d]=%d", j, buckets[j]);
-refresh();
-                       wmove(wnd, row, j * (1 + colwidth));
-                       k = MIN(buckets[j], colwidth);
-                       while (k--)
-                               waddch(wnd, 'X');
-                       k = MAX(colwidth - buckets[j], 0);
-                       while (k--)
-                               waddch(wnd, ' ');
-                       buckets[j] = 0;
+       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(4, dmtext, 'X');
+        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) {
+                       error("showswap: getu failed on pid %d", pp->p_pid);
+                       continue;
+               }
+               vsacct(&u.u_dmap);
+               vsacct(&u.u_smap);
 #ifdef notdef
 #ifdef notdef
-       printf("overflow:");
-       for (i = 0; i < nswdev; i++)
-               printf("\t%d", overflow[i]);
-       printf("\n");
+               if ((pp->p_flag & SLOAD) == 0)
+                       vusize(pp);
 #endif
 #endif
+        }
+       (void) swapdisplay(row + 1, dmmax, 'X');
 }
 
 }
 
-/*
- * Allocate 'size' units from the given
- * map. Return the base of the allocated space.
- * In a map, the addresses are increasing and the
- * list is terminated by a 0 size.
- *
- * Algorithm is first-fit.
- *
- * This routine knows about the interleaving of the swapmap
- * and handles that.
- */
-long
-rmalloc(mp, size)
-       register struct map *mp;
-       long size;
+swapdisplay(baserow, dmbound, c)
+       int baserow, dmbound;
+       char c;
 {
 {
-       register struct mapent *ep = (struct mapent *)(mp+1);
-       register int addr;
-       register struct mapent *bp;
-       swblk_t first, rest;
+       register int i, j, k, row;
+       register short *pb;
+       char buf[10];
 
 
-       if (size <= 0 || size > dmmax)
-               return (0);
-       /*
-        * Search for a piece of the resource map which has enough
-        * free space to accomodate the request.
-        */
-       for (bp = ep; bp->m_size; bp++) {
-               if (bp->m_size >= size) {
-                       /*
-                        * If allocating from swapmap,
-                        * then have to respect interleaving
-                        * boundaries.
-                        */
-                       if (nswdev > 1 &&
-                           (first = dmmax - bp->m_addr%dmmax) < bp->m_size) {
-                               if (bp->m_size - first < size)
-                                       continue;
-                               addr = bp->m_addr + first;
-                               rest = bp->m_size - first - size;
-                               bp->m_size = first;
-                               if (rest)
-                                       rmfree(mp, rest, addr+size);
-                               return (addr);
-                       }
-                       /*
-                        * Allocate from the map.
-                        * If there is no space left of the piece
-                        * we allocated from, move the rest of
-                        * the pieces to the left.
-                        */
-                       addr = bp->m_addr;
-                       bp->m_addr += size;
-                       if ((bp->m_size -= size) == 0) {
-                               do {
-                                       bp++;
-                                       (bp-1)->m_addr = bp->m_addr;
-                               } while ((bp-1)->m_size = bp->m_size);
+       for (row = baserow, i = dmmin; i <= dmbound; i *= 2, row++) {
+               for (j = 0; j < nswdev; j++) {
+                       pb = &buckets[j][row - baserow];
+                       wmove(wnd, row, 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, ' ');
                        }
                        }
-                       if (addr % CLSIZE)
-                               return (0);
-                       return (addr);
+                       *pb = 0;
                }
        }
                }
        }
-       return (0);
+       return (row);
 }
 
 }
 
-/*
- * Free the previously allocated space at addr
- * of size units into the specified map.
- * Sort addr into map and combine on
- * one or both ends if possible.
- */
-rmfree(mp, size, addr)
-       struct map *mp;
-       long size, addr;
+vsacct(dmp)
+       register struct dmap *dmp;
 {
 {
-       struct mapent *firstbp;
-       register struct mapent *bp;
-       register int t;
+       register swblk_t *ip;
+       register int blk = dmmin, index = 0;
 
 
-       /*
-        * Both address and size must be
-        * positive, or the protocol has broken down.
-        */
-       if (addr <= 0 || size <= 0)
-               goto badrmfree;
-       /*
-        * Locate the piece of the map which starts after the
-        * returned space (or the end of the map).
-        */
-       firstbp = bp = (struct mapent *)(mp + 1);
-       for (; bp->m_addr <= addr && bp->m_size != 0; bp++)
-               continue;
-       /*
-        * If the piece on the left abuts us,
-        * then we should combine with it.
-        */
-       if (bp > firstbp && (bp-1)->m_addr+(bp-1)->m_size >= addr) {
-               /*
-                * Check no overlap (internal error).
-                */
-               if ((bp-1)->m_addr+(bp-1)->m_size > addr)
-                       goto badrmfree;
-               /*
-                * Add into piece on the left by increasing its size.
-                */
-               (bp-1)->m_size += size;
-               /*
-                * If the combined piece abuts the piece on
-                * the right now, compress it in also,
-                * by shifting the remaining pieces of the map over.
-                */
-               if (bp->m_addr && addr+size >= bp->m_addr) {
-                       if (addr+size > bp->m_addr)
-                               goto badrmfree;
-                       (bp-1)->m_size += bp->m_size;
-                       while (bp->m_size) {
-                               bp++;
-                               (bp-1)->m_addr = bp->m_addr;
-                               (bp-1)->m_size = bp->m_size;
-                       }
+       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++;
                }
                }
-               goto done;
-       }
-       /*
-        * Don't abut on the left, check for abutting on
-        * the right.
-        */
-       if (addr+size >= bp->m_addr && bp->m_size) {
-               if (addr+size > bp->m_addr)
-                       goto badrmfree;
-               bp->m_addr -= size;
-               bp->m_size += size;
-               goto done;
-       }
-       /*
-        * Don't abut at all.  Make a new entry
-        * and check for map overflow.
-        */
-       do {
-               t = bp->m_addr;
-               bp->m_addr = addr;
-               addr = t;
-               t = bp->m_size;
-               bp->m_size = size;
-               bp++;
-       } while (size = t);
-       /*
-        * Segment at bp is to be the delimiter;
-        * If there is not room for it 
-        * then the table is too full
-        * and we must discard something.
-        */
-       if (bp+1 > mp->m_limit) {
-               /*
-                * Back bp up to last available segment.
-                * which contains a segment already and must
-                * be made into the delimiter.
-                * Discard second to last entry,
-                * since it is presumably smaller than the last
-                * and move the last entry back one.
-                */
-               bp--;
-               overflow[((bp-1)->m_addr % dmmax) / nswdev] += 
-                   (bp-1)->m_size;
-#ifdef notdef
-               printf("%s: rmap ovflo, lost [%d,%d)\n", mp->m_name,
-                   (bp-1)->m_addr, (bp-1)->m_addr+(bp-1)->m_size);
-#endif
-               bp[-1] = bp[0];
-               bp[0].m_size = bp[0].m_addr = 0;
        }
        }
-done:
-       return;
-badrmfree:
-       printf("bad rmfree\n");
+}
+
+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);
 }
 }