Subject: mmap() lossage??
To: None <netbsd-help@NetBSD.ORG>
From: Brian C. Grayson <bgrayson@ece.utexas.edu>
List: netbsd-help
Date: 04/25/1997 21:17:30
  Theoretically, if a program does

  { p = mmap(...); *p = 0; munmap(p);}

a million times, there should be at most one mmap()'s worth of
wasted VM, right?  This is the behavior under an AIX box and a
Solaris box, but under NetBSD there seems to be some lossage.
This is on -i386-current.

  Here's a simple test program (sorry about style -- it's just
something I whipped up).  Basically, it mmaps a region, touches
it, and then unmaps it.  The command-line arg specifies how many
iterations it should do.  Every tenth iteration, it does a
'vmstat' so that it can print out memory statistics (or, if you
have xosview, just watch the memmeter's FREE region shrink
(same with 'top')).  Eventually, with a high iteration count,
it'll start swapping things out!  On my home machine, this
process happily ramped up to 30MB of VM before I killed it.

  A sample output is appended below the program.

  Is there anything I am forgetting to do in this program?  I
thought munmap() should do everything I want.

  The usleep() is to prevent it from going full-tilt, because
once it starts swapping, an i486 box is basically paralyzed.
With the usleep(), the user can hit ^C and it will be noticed
within a few seconds.  :)

  Thanks in advance, as always!

#include <stdlib.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

void * mmapalloc(size_t len) {
  void * p;
  p = (void*) mmap(0, len+0x0fff, PROT_READ|PROT_WRITE,
                   MAP_ANON|MAP_PRIVATE, -1, 0);
  if (p != (void*) -1)
    return p;
  else {
    perror("mmap");
    return NULL;
  }
}

void mmapfree(void * p, size_t len) {
  if (munmap(p, len))
    perror("munmap");
}
 
main (int argc, char ** argv) {
  int* ap;
  int j;
  int allocsize = 0x1000, niters; 

  niters = 8;
  if (argc > 1)
    niters = atoi(argv[1]);

  system("vmstat");
  for (j = 0; j < niters; j++) {
      ap = mmapalloc(allocsize);
      *ap = 0;
      mmapfree(ap, allocsize);
    if (j%10 == 0) system("vmstat | tail -1");
    usleep(5000);
  }
}

(9:10pm):63 mmaptest 4000
 procs   memory     page                    disks      faults cpu
 r b w   avm   fre  flt  re  pi  po  fr  sr w0 f0 f1   in   sy cs us sy id
 1 0 0119216  5344   24   3   2   0   0   1  1  0  0  177  255 42  4  1 95
 2 0 0125216  5300   24   3   2   0   0   1  1  0  0  177  255 42  4  1 95
 2 0 0119240  5300   24   3   2   0   0   1  1  0  0  177  255 42  4  1 95
 2 0 0121404  5216   24   3   2   0   0   1  1  0  0  177  255 42  4  1 95
 2 0 0125444  5188   24   3   2   0   0   1  1  0  0  177  255 42  4  1 95
 2 0 0125536  5136   24   3   2   0   0   1  1  0  0  177  255 42  4  1 95
 2 0 0125616  5092   24   3   2   0   0   1  1  0  0  177  255 42  4  1 95
 2 0 0127916  5056   24   3   2   0   0   1  1  0  0  177  255 42  4  1 95
 2 0 0127996  5016   24   3   2   0   0   1  1  0  0  177  255 42  4  1 95
 2 0 0132044  4980   24   3   2   0   0   1  1  0  0  177  255 42  4  1 95
...
 2 0 0138496  2552   26   3   2   0   0   1  1  0  0  177  257  42  4  1 95
 2 0 0142548  2508   26   3   2   0   0   1  1  0  0  177  257  42  4  1 95
 2 0 0138656  2472   26   3   2   0   0   1  1  0  0  177  257  42  4  1 95
...
 3 0 0 63680   692   26   3   2   0   0   1  1  0  0  177  257  42  4  1 95
 2 0 0 67836   624   26   3   2   0   0   1  1  0  0  177  257  42  4  1 95
 2 0 0 63840   612   26   3   2   0   0   1  1  0  0  177  257  42  4  1 95
 1 0 0 68004   508   26   3   2   0   0   1  1  0  0  177  257  42  4  1 95
...
etc.

-- 
Brian Grayson (bgrayson@ece.utexas.edu)
Graduate Student, Electrical and Computer Engineering
The University of Texas at Austin
Office:  ENS 406       (512) 471-8011
Finger bgrayson@orac.ece.utexas.edu for PGP key.