Subject: anyone changed top source to reflect recent swap changes?
To: None <current-users@NetBSD.ORG>
From: Thorsten Frueauf <frueauf@ira.uka.de>
List: current-users
Date: 06/15/1997 19:29:26
Hello!

Did anyone change the source for top to reflect the recent swap changes?
I tryed the following diff with top-3.4, which kinda works, but I don't
know if it is the right thing (tm). Obviously one should introduce
a top-3.4/machine/m_netbsd13.c, so this is a quick hack anyway.

So if anyone has the right thing (tm) I would be happy to get it.

-- snip ---
*** m_netbsd10.c-orig	Fri Jan 26 06:27:18 1996
--- m_netbsd10.c	Sun Jun 15 19:14:54 1997
***************
*** 52,60 ****
  #include <sys/time.h>
  
  #ifdef USE_SWAP
  #include <stdlib.h>
! #include <sys/map.h>
! #include <sys/conf.h>
  #endif
  
  static int check_nlist __P((struct nlist *));
--- 52,67 ----
  #include <sys/time.h>
  
  #ifdef USE_SWAP
+ #include <sys/param.h>
+ #include <sys/stat.h>
+ 
+ #include <vm/vm_swap.h>
+ 
+ #include <unistd.h>
+ #include <errno.h>
+ #include <stdio.h>
  #include <stdlib.h>
! #include <string.h>
  #endif
  
  static int check_nlist __P((struct nlist *));
***************
*** 102,135 ****
  #define X_AVENRUN	4
      { "_averunnable" },		/* 4 */
  
- #ifdef USE_SWAP
- #define VM_SWAPMAP	5
- 	{ "_swapmap" },	/* list of free swap areas */
- #define VM_NSWAPMAP	6
- 	{ "_nswapmap" },/* size of the swap map */
- #define VM_SWDEVT	7
- 	{ "_swdevt" },	/* list of swap devices and sizes */
- #define VM_NSWAP	8
- 	{ "_nswap" },	/* size of largest swap device */
- #define VM_NSWDEV	9
- 	{ "_nswdev" },	/* number of swap devices */
- #define VM_DMMAX	10
- 	{ "_dmmax" },	/* maximum size of a swap block */
- #define VM_NISWAP	11
- 	{ "_niswap" },
- #define VM_NISWDEV	12
- 	{ "_niswdev" },
- #endif /* USE_SWAP */
- 
- #ifdef VM_REAL
- #ifdef USE_SWAP
- #define X_CNT           13
- #else
- #define X_CNT           5
- #endif
-     { "_cnt" },		        /* struct vmmeter cnt */
- #endif
- 
  #ifdef LASTPID
  #if (defined USE_SWAP && defined VM_REAL)
  #define X_LASTPID	14
--- 109,114 ----
***************
*** 304,312 ****
  #ifdef LASTPID
      lastpid_offset =  nlst[X_LASTPID].n_value;
  #endif
- #ifdef VM_REAL
-     cnt_offset = nlst[X_CNT].n_value;
- #endif
  
      /* this is used in calculating WCPU -- calculate it ahead of time */
      logcpu = log(loaddouble(ccpu));
--- 283,288 ----
***************
*** 429,437 ****
  	struct vmmeter sum;
  	static unsigned int swap_delay = 0;
  
-         (void) getkval(cnt_offset, (int *)(&sum), sizeof(sum),
- 		   "_cnt");
- 
  	/* convert memory stats to Kbytes */
  	memory_stats[0] = pagetok(sum.v_active_count);
  	memory_stats[1] = pagetok(sum.v_inactive_count);
--- 405,410 ----
***************
*** 450,456 ****
  
  #ifdef USE_SWAP
          if ((memory_stats[5] > 0 || memory_stats[6]) > 0 || swap_delay == 0) {
! 	    memory_stats[4] = swapmode();
  	}
          /* swap_delay++; XXX Arne */
  #else
--- 423,429 ----
  
  #ifdef USE_SWAP
          if ((memory_stats[5] > 0 || memory_stats[6]) > 0 || swap_delay == 0) {
! 	    memory_stats[4] = list_swap(0, 0, 1, 1, 1);;
  	}
          /* swap_delay++; XXX Arne */
  #else
***************
*** 819,941 ****
  		return (0);						\
  	}
  
! int
! swapmode()
! {
! 	char *header;
! 	int hlen, nswap, nswdev, dmmax, nswapmap, niswap, niswdev;
! 	int s, e, div, i, l, avail, nfree, npfree, used;
! 	struct swdevt *sw;
! 	long blocksize, *perdev;
! 	struct map *swapmap, *kswapmap;
! 	struct mapent *mp, *freemp;
! 
! 	KGET(VM_NSWAP, nswap);
! 	KGET(VM_NSWDEV, nswdev);
! 	KGET(VM_DMMAX, dmmax);
! 	KGET(VM_NSWAPMAP, nswapmap);
! 	KGET(VM_SWAPMAP, kswapmap);	/* kernel `swapmap' is a pointer */
! 	if ((sw = malloc(nswdev * sizeof(*sw))) == NULL ||
! 	    (perdev = malloc(nswdev * sizeof(*perdev))) == NULL ||
! 	    (freemp = mp = malloc(nswapmap * sizeof(*mp))) == NULL)
! 		err(1, "malloc");
! 	KGET1(VM_SWDEVT, sw, nswdev * sizeof(*sw), "swdevt");
! 	KGET2((long)kswapmap, mp, nswapmap * sizeof(*mp), "swapmap");
! 
! 	/* Supports sequential swap */
! 	if (nlst[VM_NISWAP].n_value != 0) {
! 		KGET(VM_NISWAP, niswap);
! 		KGET(VM_NISWDEV, niswdev);
! 	} else {
! 		niswap = nswap;
! 		niswdev = nswdev;
! 	}
! 
! 	/* First entry in map is `struct map'; rest are mapent's. */
! 	swapmap = (struct map *)mp;
! 	if (nswapmap != swapmap->m_limit - (struct mapent *)kswapmap)
! 		errx(1, "panic: nswapmap goof");
! 
! 	/* Count up swap space. */
! 	nfree = 0;
! 	memset(perdev, 0, nswdev * sizeof(*perdev));
! 	for (mp++; mp->m_addr != 0; mp++) {
! 		s = mp->m_addr;			/* start of swap region */
! 		e = mp->m_addr + mp->m_size;	/* end of region */
! 		nfree += mp->m_size;
! 
! 		/*
! 		 * Swap space is split up among the configured disks.
! 		 *
! 		 * For interleaved swap devices, the first dmmax blocks
! 		 * of swap space some from the first disk, the next dmmax
! 		 * blocks from the next, and so on up to niswap blocks.
! 		 *
! 		 * Sequential swap devices follow the interleaved devices
! 		 * (i.e. blocks starting at niswap) in the order in which
! 		 * they appear in the swdev table.  The size of each device
! 		 * will be a multiple of dmmax.
! 		 *
! 		 * The list of free space joins adjacent free blocks,
! 		 * ignoring device boundries.  If we want to keep track
! 		 * of this information per device, we'll just have to
! 		 * extract it ourselves.  We know that dmmax-sized chunks
! 		 * cannot span device boundaries (interleaved or sequential)
! 		 * so we loop over such chunks assigning them to devices.
! 		 */
! 		i = -1;
! 		while (s < e) {		/* XXX this is inefficient */
! 			int bound = roundup(s+1, dmmax);
! 
! 			if (bound > e)
! 				bound = e;
! 			if (bound <= niswap) {
! 				/* Interleaved swap chunk. */
! 				if (i == -1)
! 					i = (s / dmmax) % niswdev;
! 				perdev[i] += bound - s;
! 				if (++i >= niswdev)
! 					i = 0;
! 			} else {
! 				/* Sequential swap chunk. */
! 				if (i < niswdev) {
! 					i = niswdev;
! 					l = niswap + sw[i].sw_nblks;
! 				}
! 				while (s >= l) {
! 					/* XXX don't die on bogus blocks */
! 					if (i == nswdev-1)
! 						break;
! 					l += sw[++i].sw_nblks;
! 				}
! 				perdev[i] += bound - s;
! 			}
! 			s = bound;
! 		}
! 	}
! 
! 	header = getbsize(&hlen, &blocksize);
! 	div = blocksize / 512;
! 	avail = npfree = 0;
! 	for (i = 0; i < nswdev; i++) {
! 		int xsize, xfree;
! 
! 		xsize = sw[i].sw_nblks;
! 		xfree = perdev[i];
! 		used = xsize - xfree;
! 		npfree++;
! 		avail += xsize;
! 	}
! 
! 	/* 
! 	 * If only one partition has been set up via swapon(8), we don't
! 	 * need to bother with totals.
! 	 */
! 	used = avail - nfree;
! 	free (sw); free (freemp); free (perdev);
! 	return  (int)(((double)used / (double)avail * 100.0) + 0.5);
  }
- 
  
  #endif
  
--- 792,874 ----
  		return (0);						\
  	}
  
! list_swap(pri, kflag, pflag, tflag, dolong)
!         int     pri;
!         int     kflag;
!         int     pflag;
!         int     tflag;
!         int     dolong;
! {
!         struct  swapent *sep;
!         long    blocksize;
!         char    *header;
!         int     hlen, totalsize, size, totalinuse, inuse, ncounted;
!         int     rnswap, nswap = swapctl(SWAP_NSWAP, 0, 0);
! 
!         if (nswap < 1) {
!                 puts("no swap devices configured");
!                 exit(0);
!         }
! 
!         sep = (struct swapent *)malloc(nswap * sizeof(*sep));
!         if (sep == NULL)
!                 err(1, "malloc");
!         rnswap = swapctl(SWAP_STATS, (void *)sep, nswap);
!         if (nswap < 0)
!                 errx(1, "SWAP_STATS");
!         if (nswap != rnswap)
!                 warnx("SWAP_STATS gave different value than SWAP_NSWAP");
! 
!         if (dolong && tflag == 0) {
!                 if (kflag) {
!                         header = "1K-blocks";
!                         blocksize = 1024;
!                         hlen = strlen(header);
!                 } else
!                         header = getbsize(&hlen, &blocksize);
!                 (void)printf("%-11s %*s %8s %8s %8s  %s\n",
!                     "Device", hlen, header,
!                     "Used", "Avail", "Capacity", "Priority");
!         }
!         totalsize = totalinuse = ncounted = 0;
!         for (; rnswap-- > 0; sep++) {
!                 if (pflag && sep->se_priority != pri)
!                         continue;
!                 ncounted++;
!                 size = sep->se_nblks;
!                 inuse = sep->se_inuse;
!                 totalsize += size;
!                 totalinuse += inuse;
! 
!                 if (dolong && tflag == 0) {
!                         /* XXX handle se_dev == NODEV */
!                         (void)printf("/dev/%-6s %*d ",
!                             devname(sep->se_dev, S_IFBLK),
!                                 hlen, dbtob(size) / blocksize);
! 
!                         (void)printf("%8d %8d %5.0f%%    %d\n",
!                             dbtob(inuse) / blocksize,
!                             dbtob(size - inuse) / blocksize,
!                             (double)inuse / (double)size * 100.0,
!                             sep->se_priority);
!                 }
!         }
!         if (tflag)
!                 (void)printf("\t%dM/%dM swap space\n",
!                     dbtob(totalinuse) / (1024 * 1024),
!                     dbtob(totalsize) / (1024 * 1024));
!         else if (dolong == 0)
! (void)printf("total: %dk bytes allocated = %dk used, %dk available\n",
!                     dbtob(totalsize) / 1024,
!                     dbtob(totalinuse) / 1024,
!                     dbtob(totalsize - totalinuse) / 1024);
!         else if (ncounted > 1)
!                 (void)printf("%-11s %*d %8d %8d %5.0f%%\n", "Total", hlen,
!                     dbtob(totalsize) / blocksize,
!                     dbtob(totalinuse) / blocksize,
!                     dbtob(totalsize - totalinuse) / blocksize,
!                     (double)(totalinuse) / (double)totalsize * 100.0);
  }
  
  #endif
  
--- snip ---

Greets
      Thorsten