-#else /* NEWVM */
-int dmmin, dmmax, nswdev;
-
-doswap()
-{
- struct proc *proc;
- int nproc;
- struct text *xtext;
- int ntext;
- struct map *swapmap;
- int nswapmap;
- struct swdevt *swdevt, *sw;
- register struct proc *pp;
- int nswap, used, tused, free, waste;
- int db, sb;
- register struct mapent *me;
- register struct text *xp;
- int i, j;
- long rmalloc();
-
- nproc = getword(nl[SNPROC].n_value);
- ntext = getword(nl[SNTEXT].n_value);
- if (nproc < 0 || nproc > 10000 || ntext < 0 || ntext > 10000) {
- fprintf(stderr, "number of procs/texts is preposterous (%d, %d)\n",
- nproc, ntext);
- return;
- }
- proc = (struct proc *)calloc(nproc, sizeof (struct proc));
- if (proc == NULL) {
- fprintf(stderr, "can't allocate memory for proc table\n");
- exit(1);
- }
- xtext = (struct text *)calloc(ntext, sizeof (struct text));
- if (xtext == NULL) {
- fprintf(stderr, "can't allocate memory for text table\n");
- exit(1);
- }
- nswapmap = getword(nl[SNSWAPMAP].n_value);
- swapmap = (struct map *)calloc(nswapmap, sizeof (struct map));
- if (swapmap == NULL) {
- fprintf(stderr, "can't allocate memory for swapmap\n");
- exit(1);
- }
- nswdev = getword(nl[SNSWDEV].n_value);
- swdevt = (struct swdevt *)calloc(nswdev, sizeof (struct swdevt));
- if (swdevt == NULL) {
- fprintf(stderr, "can't allocate memory for swdevt table\n");
- exit(1);
- }
- kvm_read(V(nl[SSWDEVT].n_value), swdevt,
- nswdev * sizeof (struct swdevt));
- kvm_read(V(getword(nl[SPROC].n_value)), proc,
- nproc * sizeof (struct proc));
- kvm_read(V(getword(nl[STEXT].n_value)), xtext,
- ntext * sizeof (struct text));
- kvm_read(V(getword(nl[SWAPMAP].n_value)), swapmap,
- nswapmap * sizeof (struct map));
-
- swapmap->m_name = "swap";
- swapmap->m_limit = (struct mapent *)&swapmap[nswapmap];
- dmmin = getword(nl[SDMMIN].n_value);
- dmmax = getword(nl[SDMMAX].n_value);
- nswap = 0;
- for (sw = swdevt; sw < &swdevt[nswdev]; sw++)
- if (sw->sw_freed)
- nswap += sw->sw_nblks;
- free = 0;
- for (me = (struct mapent *)(swapmap+1);
- me < (struct mapent *)&swapmap[nswapmap]; me++)
- free += me->m_size;
- tused = 0;
- for (xp = xtext; xp < &xtext[ntext]; xp++)
- if (xp->x_vptr!=NULL) {
- tused += ctod(clrnd(xp->x_size));
- if (xp->x_flag & XPAGV)
- tused += ctod(clrnd(ctopt(xp->x_size)));
- }
- used = tused;
- waste = 0;
- for (pp = proc; pp < &proc[nproc]; pp++) {
- if (pp->p_stat == 0 || pp->p_stat == SZOMB)
- continue;
- if (pp->p_flag & SSYS)
- continue;
- db = ctod(pp->p_dsize), sb = up(db);
- used += sb;
- waste += sb - db;
- db = ctod(pp->p_ssize), sb = up(db);
- used += sb;
- waste += sb - db;
- if ((pp->p_flag&SLOAD) == 0)
- used += ctod(vusize(pp));
- }
- if (totflg) {
-#define btok(x) ((x) / (1024 / DEV_BSIZE))
- printf("%3d/%3d 00k swap\n",
- btok(used/100), btok((used+free)/100));
- return;
- }
- printf("%dk used (%dk text), %dk free, %dk wasted, %dk missing\n",
- btok(used), btok(tused), btok(free), btok(waste),
-/* a dmmax/2 block goes to argmap */
- btok(nswap - dmmax/2 - (used + free)));
- printf("avail: ");
- for (i = dmmax; i >= dmmin; i /= 2) {
- j = 0;
- while (rmalloc(swapmap, i) != 0)
- j++;
- if (j) printf("%d*%dk ", j, btok(i));
- }
- free = 0;
- for (me = (struct mapent *)(swapmap+1);
- me < (struct mapent *)&swapmap[nswapmap]; me++)
- free += me->m_size;
- printf("%d*1k\n", btok(free));
-}
-
-up(size)
- register int size;
-{
- register int i, block;
-
- i = 0;
- block = dmmin;
- while (i < size) {
- i += block;
- if (block < dmmax)
- block *= 2;
- }
- return (i);
-}
-
-/*
- * Compute number of pages to be allocated to the u. area
- * and data and stack area page tables, which are stored on the
- * disk immediately after the u. area.
- */
-vusize(p)
- register struct proc *p;
-{
- register int tsz = p->p_tsize / NPTEPG;
-
- /*
- * We do not need page table space on the disk for page
- * table pages wholly containing text.
- */
- return (clrnd(UPAGES +
- clrnd(ctopt(p->p_tsize+p->p_dsize+p->p_ssize+UPAGES)) - tsz));
-}
-
-/*
- * 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;
-{
- register struct mapent *ep = (struct mapent *)(mp+1);
- register int addr;
- register struct mapent *bp;
- swblk_t first, rest;
-
- 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);
- }
- if (addr % CLSIZE)
- return (0);
- return (addr);
- }
- }
- return (0);
-}
-
-/*
- * 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;
-{
- struct mapent *firstbp;
- register struct mapent *bp;
- register int t;
-
- /*
- * 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;
- }
- }
- 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--;
- printf("%s: rmap ovflo, lost [%d,%d)\n", mp->m_name,
- (bp-1)->m_addr, (bp-1)->m_addr+(bp-1)->m_size);
- bp[-1] = bp[0];
- bp[0].m_size = bp[0].m_addr = 0;
- }
-done:
- return;
-badrmfree:
- printf("bad rmfree\n");
-}
-#endif /* NEWVM */
-