The GNU mmalloc (mapped-malloc) package.	fnf@cygnus.com


Description
-----------

This is a heavily modified version of GNU malloc which has been extended to
use mmap() as the basic mechanism for for obtaining memory from the system,
rather than sbrk().  This gives it several advantages over the
more traditional malloc:

    *	Providing suitable precautions are taken to avoid memory region
	collisions, sbrk() is now available for use by applications that
	use this package and still need to use some memory management
	package that includes functions like malloc/realloc/free.

    *	Several different memory pools can be used, each of them growing
	or shinking under control of mmap(), with the mmalloc functions
	using a specific pool on a call by call basis.

    *   By using mmap, it is easy to create data pools which are intended to
	be persistent and exist as a filesystem object after the creating
	process has gone away.

    *	Because multiple memory pools can be managed, data used for a 
	specific purpose can be allocated into it's own memory pool, making
	it easier to allow applications to "dump" and "restore" initialized
	malloc-managed memory regions.  I.E., the "unexec" hack popularized
	by GNU emacs could potentially go away.


Implementation
--------------

The mmalloc functions contain no internal static state.  All of mmalloc
internal data is allocated in the mapped in region, along with the user
data that it manages.  This allows it to manage multiple such regions
and to "pick up where it left off" when such regions are later dynamically
mapped back in.

In some sense, malloc has been "purified" to contain no internal state
information and generalized to use multiple memory regions rather than a
single region managed by sbrk().  However the new routines now need an
extra parameter which informs malloc which memory region it is dealing
with (along with other information).

For ease of initial implementation, and to avoid exporting or importing
any more global variables or routines than necessary, this package is
implemented with all functions contained within a single source file.
At some future point, once everything has stabilized, it may be desirable
split it up into separate files.

The functions initially provided by mmalloc are:

    void *mmalloc_attach (int fd, void *baseaddr);
    void *mmalloc_detach (void *md);
    int mmalloc_errno (void *md);
    int mmalloc_setkey (void *md, int keynum, void *key);
    void *mmalloc_getkey (void *md, int keynum);

    void *mmalloc (void *md, size_t size);
    void *mrealloc (void *md, void *ptr, size_t size);
    void *mvalloc (void *md, size_t size);
    void mfree (void *md, void *ptr);

Backwards Compatibility
-----------------------

To allow a single malloc package to be used in a given application, provision
is made for the traditional malloc/realloc/free functions to be implemented
as special cases of the mmalloc functions.  In particular, if any of the
functions that expect malloc descriptors are called with a NULL pointer rather
than a valid malloc descriptor, then they default to using an mmap'd region
starting at the current sbrk() value and mapped to /dev/zero.  Applications
can simply include the following defines to use the mmalloc versions:

	#define malloc(size)		mmalloc ((void *)0, (size))
	#define realloc(ptr,size)	mrealloc ((void *)0, (ptr), (size));
	#define free(ptr)		mfree ((void *)0, (ptr))

or replace the existing malloc/realloc/free calls with the above patterns
if the #define's cause problems.

Note that this does not prevent calls to malloc/realloc/free within 
libraries from continuing to use the library version of malloc, so if this
is a problem, the compatibility issue needs to be dealt with in another way.


Function Descriptions
---------------------

    void *mmalloc_attach (int fd, void *baseaddr);

	Initialize access to a mmalloc managed region.

	If FD is a valid file descriptor for an open file then data for the
	mmalloc managed region is mapped to that file, otherwise "/dev/zero"
	is used and the data will not exist in any filesystem object.

	If the open file corresponding to FD is from a previous use of
	mmalloc and passes some basic sanity checks to ensure that it is
	compatible with the current mmalloc package, then it's data is
	mapped in and is immediately accessible at the same addresses in
	the current process as the process that created the file.

	If BASEADDR is not NULL, the mapping is established starting at the
	specified address in the process address space.  If BASEADDR is NULL,
	the mmalloc package chooses a suitable address at which to start the
	mapped region, which will be the value of the previous mapping if
	opening an existing file which was previously built by mmalloc, or
	for new files will be a value chosen by mmap.

	Specifying BASEADDR provides more control over where the regions
	start and how big they can be before bumping into existing mapped
	regions or future mapped regions.

	On success, returns a "malloc descriptor" which is used in subsequent
	calls to other mmalloc package functions.  It is explicitly "void *"
	("char *" for systems that don't fully support void) so that users
	of the package don't have to worry about the actual implementation
	details.

	On failure returns NULL.

    void *mmalloc_detach (void *md);

	Terminate access to a mmalloc managed region by closing the base
	file and unmapping all memory pages associated with the region.

	Returns NULL on success.

	Returns the malloc descriptor on failure, which can subsequently
	be used for further action (such as obtaining more information about
	the nature of the failure).

    void *mmalloc (void *md, size_t size);

	Given an mmalloc descriptor MD, allocate additional memory of
	SIZE bytes in the associated mapped region.

    void *mrealloc (void *md, void *ptr, size_t size);

	Given an mmalloc descriptor MD and a pointer to memory previously
	allocated by mmalloc in PTR, reallocate the memory to be SIZE bytes
	long, possibly moving the existing contents of memory if necessary.
	
    void *mvalloc (void *md, size_t size);

	Like mmalloc but the resulting memory is aligned on a page boundary.

    void mfree (void *md, void *ptr);

	Given an mmalloc descriptor MD and a pointer to memory previously
	allocated by mmalloc in PTR, free the previously allocated memory.

    int mmalloc_errno (void *md);

	Given a mmalloc descriptor, if the last mmalloc operation
	failed for some reason due to a system call failure, then
	returns the associated errno.  Returns 0 otherwise.
