From: basile@soleil.serma.cea.fr (Basile STARYNKEVITCH)
Newsgroups: comp.unix.programmer
Subject: How to reserve adress ranges on SVR4 or SunOS5.0
Keywords: mmap, adress range
Date: 12 Aug 92 17:31:04 GMT
Reply-To: basile@soleil.serma.cea.fr (Basile STARYNKEVITCH)
Organization: Commissariat a l Energie Atomique

on SunOS5.0 Beta (= Solaris 2.0 Beta), Sun4/40 IPC, 20Mb RAM.

I'm writing a garbage collected system. I wish to reserve a rather huge
adress range (let say 0.5 or 1 GigaBytes) - usually much bigger than my
swap space. I won't use all of it (this range is an absolute max), but
i want to be sure my allocator could ask for contiguous adresses
ranges, so i would like to reserve a contiguous adress range and then
mmap MAP_FIXED /dev/zero O_RDWRD opened PROT_READ|PROT_WRITE some
bunches of it.  [basically i want some kind of sbrk(2) behavior, but
not interfering with the system break and malloc(3); i will also use
protection bits in my GC, like Appel, Chenay, et al].  In other words,
i wish to have a very big adress range into which i'm sure mmap won't
fall if not asked to by MAP_FIXED!.

I thought that opening /dev/zero as read-only, and mmap(2)ing it
without any access permitted would be ok. It doesn't work as expected
(iez it eats up swap space; mmap(2)-ing /dev/null don't work neither;
Does anybody have some ideas?? 

Please post your answers or email, thank you.


Here is a test run

cantor:basile:127: swap -s   ### swap space before 
total: 13928k bytes allocated + 5336k reserved = 19264k used, 41496k available

trying to reserve a lot of memory
cantor:basile:134: testmmap 131072 2048
 mypagesize=4096=0x1000 myreadlen=131072K=0x8000000 mywritelen=2048K=0x200000 
 mmap rzero read len=134217728=0x8000000 failure errno=11:No more processes 
 mmap zero write len=2097152=0x200000 at 0xef51f000 up to 0xef71efff
 sleeping 5 sec 
<Hit ^Z>
Stopped
cantor:basile:135: swap -s  ## while testmmap is sleeping
total: 14004k bytes allocated + 7384k reserved = 21388k used, 39396k available
cantor:basile:136: fg
testmmap 131072 2048
 exiting 

cantor:basile:137: testmmap 32768 2048
 mypagesize=4096=0x1000 myreadlen=32768K=0x2000000 mywritelen=2048K=0x200000 
 mmap rzero read len=33554432=0x2000000 at 0xed71f000 up to 0xef71efff
 mmap zero write len=2097152=0x200000 at 0xed71f000 up to 0xed91efff
 sleeping 5 sec 
<Hit ^Z>
Stopped
cantor:basile:138: swap -s
total: 14004k bytes allocated + 40152k reserved = 54156k used, 6604k available
cantor:basile:139: 

cantor:basile:139: fg
testmmap 32768 2048
 exiting 

here is a test program:

/* file SRC/testmmap.c */
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>

void *myreadmap;
void *mywritemap;
int   myreadlen;
int   mywritelen;
int   mypagesize;
int   myzero;
int   myreadzero;
int   mynull;
int
main(int argc, char **argv)
{
   myzero = open("/dev/zero", O_RDWR);
   if (myzero < 0) {
      perror(" open /dev/zero rdwr");
      exit(1);
   };
   myreadzero = open("/dev/zero", O_RDONLY);
   if (myreadzero < 0) {
      perror(" open /dev/zero read ");
      exit(1);
   };
   mynull = open("/dev/null", O_RDONLY);
   if (mynull < 0) {
      perror(" open /dev/null ");
      exit(1);
   };
   mypagesize = sysconf(_SC_PAGESIZE);
   if (argc >= 2)
      myreadlen = atoi(argv[1]) * 1024;
   if (argc >= 3)
      mywritelen = atoi(argv[2]) * 1024;
   printf(" mypagesize=%d=%#x myreadlen=%dK=%#x mywritelen=%dK=%#x \n",
	  mypagesize, mypagesize, myreadlen / 1024, myreadlen, mywritelen / 1024, mywritelen);
   myreadmap = mmap((void *) 0, myreadlen, 0, MAP_SHARED, myreadzero, 0);
   if (myreadmap == (void *) -1) {
      printf(" mmap rzero read len=%d=%#x failure errno=%d:%s \n",
	     myreadlen, myreadlen, errno, strerror(errno));
      myreadmap = 0;
   }
   else
      printf(" mmap rzero read len=%d=%#x at %#x up to %#x\n",
	     myreadlen, myreadlen, myreadmap, myreadmap + myreadlen - 1);
   mywritemap = mmap(myreadmap, mywritelen,
		     PROT_READ | PROT_WRITE,
		     myreadmap ? (MAP_PRIVATE | MAP_FIXED) : MAP_PRIVATE,
		     myzero, 0);
   if (mywritemap == (void *) -1)
      printf(" mmap zero write len=%d=%#x failure errno=%d:%s \n",
	     mywritelen, mywritelen, errno, strerror(errno));
   else
      printf(" mmap zero write len=%d=%#x at %#x up to %#x\n",
	     mywritelen, mywritelen, mywritemap, mywritemap + mywritelen - 1);
   printf(" sleeping 5 sec \n");
   sleep(5);
   printf(" exiting \n");
   exit(0);
   return 0;
}
/* eof testmmap.c */


-- 
Basile STARYNKEVITCH
Commissariat a l Energie Atomique
DRN/DMT/SERMA * C.E. Saclay bat.470 * 91191 GIF/YVETTE CEDEX * France
fax: (33) 1- 69.08.23.81;    phone: (33) 1- 69.08.40.66
email: basile@soleil.serma.cea.fr;  homephone: (33) 1- 46.65.45.53
N.B. Any opinions expressed here are solely mine, and not of my organization.
N.B. Les opinions exprimees ici me sont personnelles et n engagent pas le CEA.
Newsgroups: comp.unix.programmer