mm

TriggerTek Logo
abcdefghijklmnopqrstuvwxyz_
mm(3)			    Shared Memory Library			mm(3)



NAME
       OSSP mm - Shared Memory Allocation

VERSION
       OSSP mm 1.2.2 (19-Dec-2002)

SYNOPSIS
	#include "mm.h"

	Global Malloc-Replacement API

	int	MM_create(size_t size, const char *file);
	int	MM_permission(mode_t mode, uid_t owner, gid_t group);
	void	MM_destroy(void);
	int	MM_lock(mm_lock_mode mode);
	int	MM_unlock(void);
	void   *MM_malloc(size_t size);
	void   *MM_realloc(void *ptr, size_t size);
	void	MM_free(void *ptr);
	void   *MM_calloc(size_t number, size_t size);
	char   *MM_strdup(const char *str);
	size_t	MM_sizeof(void *ptr);
	size_t	MM_maxsize(void);
	size_t	MM_available(void);
	char   *MM_error(void);

	Standard Malloc-Style API

	MM     *mm_create(size_t size, char *file);
	int	mm_permission(MM *mm, mode_t mode, uid_t owner, gid_t group);
	void	mm_destroy(MM *mm);
	int	mm_lock(MM *mm, mm_lock_mode mode);
	int	mm_unlock(MM *mm);
	void   *mm_malloc(MM *mm, size_t size);
	void   *mm_realloc(MM *mm, void *ptr, size_t size);
	void	mm_free(MM *mm, void *ptr);
	void   *mm_calloc(MM *mm, size_t number, size_t size);
	char   *mm_strdup(MM *mm, const char *str);
	size_t	mm_sizeof(void *ptr);
	size_t	mm_maxsize(void);
	size_t	mm_available(MM *mm);
	char   *mm_error(void);
	void	mm_display_info(MM *mm);

	Low-level Shared Memory API

	void   *mm_core_create(size_t size, char *file);
	int	mm_core_permission(void *core, mode_t mode, uid_t owner, gid_t group);
	void	mm_core_delete(void *core);
	int	mm_core_lock(void *core, mm_lock_mode mode);
	int	mm_core_unlock(void *core);
	size_t	mm_core_size(void *core);
	size_t	mm_core_maxsegsize(void);
	size_t	mm_core_align2page(size_t size);
	size_t	mm_core_align2click(size_t size);

	Internal Library API

	void	mm_lib_error_set(unsigned int, const char *str);
	char   *mm_lib_error_get(void);
	int	mm_lib_version(void);

DESCRIPTION
       The OSSP mm library is a 2-layer abstraction library which simplifies
       the usage of shared memory between forked (and this way strongly
       related) processes under Unix platforms. On the first (lower) layer it
       hides all platform dependent implementation details (allocation and
       locking) when dealing with shared memory segments and on the second
       (higher) layer it provides a high-level malloc(3)-style API for a con-
       venient and well known way to work with data-structures inside those
       shared memory segments.

       The abbreviation OSSP mm is historically and originally comes from the
       phrase ‘‘memory mapped’’ as used by the POSIX.1 mmap(2) function.
       Because this facility is internally used by this library on most plat-
       forms to establish the shared memory segments.

       LIBRARY STRUCTURE

       This library is structured into three main APIs which are internally
       based on each other:

       Global Malloc-Replacement API
	   This is the most high-level API which directly can be used as
	   replacement API for the POSIX.1 memory allocation API (malloc(2)
	   and friends). This is useful when converting heap based data
	   structures to shared memory based data structures without the need
	   to change the code dramatically.  All which is needed is to prefix
	   the POSIX.1 memory allocation functions with ‘"MM_"’, i.e. ‘"mal-
	   loc"’ becomes ‘"MM_malloc"’, ‘"strdup"’ becomes ‘"MM_strdup"’,
	   etc. This API internally uses just a global ‘"MM *"’ pool for
	   calling the corresponding functions (those with prefix ‘"mm_"’) of
	   the Standard Malloc-Style API.

       Standard Malloc-Style API
	   This is the standard high-level memory allocation API. Its inter-
	   face is similar to the Global Malloc-Replacement API but it uses
	   an explicit ‘"MM *"’ pool to operate on. That is why every func-
	   tion of this API has an argument of type ‘"MM *"’ as its first
	   argument. This API provides a comfortable way to work with small
	   dynamically allocated shared memory chunks inside large statically
	   allocated shared memory segments. It is internally based on the
	   Low-Level Shared Memory API for creating the underlaying shared
	   memory segment.

       Low-Level Shared Memory API
	   This is the basis of the whole OSSP mm library. It provides low-
	   level functions for creating shared memory segments with mutual
	   exclusion (in short mutex) capabilities in a portable way. Inter-
	   nally the shared memory and mutex facility is implemented in vari-
	   ous platform-dependent ways. A list of implementation variants
	   follows under the next topic.

       SHARED MEMORY IMPLEMENTATION

       Internally the shared memory facility is implemented in various plat-
       form-dependent ways. Each way has its own advantages and disadvantages
       (in addition to the fact that some variants aren’t available at all on
       some platforms). The OSSP mm library’s configuration procedure tries
       hard to make a good decision. The implemented variants are now given
       for overview and background reasons with their advantages and disad-
       vantages and in an ascending order, i.e. the OSSP mm configuration
       mechanism chooses the last available one in the list as the preferred
       variant.

       Classical mmap(2) on temporary file (MMFILE)
	   Advantage: maximum portable.	 Disadvantage: needs a temporary file
	   on the filesystem.

       mmap(2) via POSIX.1 shm_open(3) on temporary file (MMPOSX)
	   Advantage: standardized by POSIX.1 and theoretically portable.
	   Disadvantage: needs a temporary file on the filesystem and is is
	   usually not available on existing Unix platform.

       SVR4-style mmap(2) on "/dev/zero" device (MMZERO)
	   Advantage: widely available and mostly portable on SVR4 platforms.
	   Disadvantage: needs the "/dev/zero" device and a mmap(2) which
	   supports memory mapping through this device.

       SysV IPC shmget(2) (IPCSHM)
	   Advantage: does not need a temporary file or external device.
	   Disadvantage: although available on mostly all modern Unix plat-
	   forms, it has strong restrictions like the maximum size of a sin-
	   gle shared memory segment (can be as small as 100KB, but depends
	   on the platform).

       4.4BSD-style mmap(2) via "MAP_ANON" facility (MMANON)
	   Advantage: does not need a temporary file or external device.
	   Disadvantage: usually only available on BSD platforms and deriva-
	   tives.

       LOCKING IMPLEMENTATION

       As for the shared memory facility, internally the locking facility is
       implemented in various platform-dependent ways. They are again listed
       in ascending order, i.e. the OSSP mm configuration mechanism chooses
       the last available one in the list as the preferred variant. The list
       of implemented variants is:

       4.2BSD-style flock(2) on temporary file (FLOCK)
	   Advantage: exists on a lot of platforms, especially on older Unix
	   derivates.  Disadvantage: needs a temporary file on the filesystem
	   and has to re-open file-descriptors to it in each(!) fork(2)’ed
	   child process.

       SysV IPC semget(2) (IPCSEM)
	   Advantage: exists on a lot of platforms and does not need a tempo-
	   rary file.  Disadvantage: an unmeant termination of the applica-
	   tion leads to a semaphore leak because the facility does not allow
	   a ‘‘remove in advance’’ trick (as the IPC shared memory facility
	   does) for safe cleanups.

       SVR4-style fcntl(2) on temporary file (FCNTL)
	   Advantage: exists on a lot of platforms and is also the most pow-
	   erful variant (although not always the fastest one). Disadvantage:
	   needs a temporary file.

       MEMORY ALLOCATION STRATEGY

       The memory allocation strategy the Standard Malloc-Style API functions
       use internally is the following:

       Allocation
	   If a chunk of memory has to be allocated, the internal list of
	   free chunks is searched for a minimal-size chunk which is larger
	   or equal than the size of the to be allocated chunk (a best fit
	   strategy).

	   If a chunk is found which matches this best-fit criteria, but is
	   still a lot larger than the requested size, it is split into two
	   chunks: One with exactly the requested size (which is the result-
	   ing chunk given back) and one with the remaining size (which is
	   immediately re-inserted into the list of free chunks).

	   If no fitting chunk is found at all in the list of free chunks, a
	   new one is created from the spare area of the shared memory seg-
	   ment until the segment is full (in which case an out of memory
	   error occurs).

       Deallocation
	   If a chunk of memory has to be deallocated, it is inserted in
	   sorted manner into the internal list of free chunks. The insertion
	   operation automatically merges the chunk with a previous and/or a
	   next free chunk if possible, i.e.  if the free chunks stay physi-
	   cally seamless (one after another) in memory, to automatically
	   form larger free chunks out of smaller ones.

	   This way the shared memory segment is automatically defragmented
	   when memory is deallocated.

       This strategy reduces memory waste and fragmentation caused by small
       and frequent allocations and deallocations to a minimum.

       The internal implementation of the list of free chunks is not spe-
       cially optimized (for instance by using binary search trees or even
       splay trees, etc), because it is assumed that the total amount of
       entries in the list of free chunks is always small (caused both by the
       fact that shared memory segments are usually a lot smaller than heaps
       and the fact that we always defragment by merging the free chunks if
       possible).

API FUNCTIONS
       In the following, all API functions are described in detail The order
       .  directly follows the one in the SYNOPSIS section above
       .

       Global Malloc-Replacement API


       int MM_create(size_t size, const char *file);
	   This initializes the global shared memory pool with size and file
	   and has to be called before any fork(2) operations are performed
	   by the application.

       int MM_permission(mode_t mode, uid_t owner, gid_t group);
	   This sets the filesystem mode, owner and group for the global
	   shared memory pool (has effects only if the underlaying shared
	   memory segment implementation is actually based on external auxil-
	   iary files).	 The arguments are directly passed through to
	   chmod(2) and chown(2).

       void MM_destroy(void);
	   This destroys the global shared memory pool and should be called
	   after all child processes were killed.

       int MM_lock(mm_lock_mode mode);
	   This locks the global shared memory pool for the current process
	   in order to perform either shared/read-only (mode is "MM_LOCK_RD")
	   or exclusive/read-write (mode is "MM_LOCK_RW") critical operations
	   inside the global shared memory pool.

       int MM_unlock(void);
	   This unlocks the global shared memory pool for the current process
	   after the critical operations were performed inside the global
	   shared memory pool.

       void *MM_malloc(size_t size);
	   Identical to the POSIX.1 malloc(3) function but instead of allo-
	   cating memory from the heap it allocates it from the global shared
	   memory pool.

       void MM_free(void *ptr);
	   Identical to the POSIX.1 free(3) function but instead of deallo-
	   cating memory in the heap it deallocates it in the global shared
	   memory pool.

       void *MM_realloc(void *ptr, size_t size);
	   Identical to the POSIX.1 realloc(3) function but instead of real-
	   locating memory in the heap it reallocates it inside the global
	   shared memory pool.

       void *MM_calloc(size_t number, size_t size);
	   Identical to the POSIX.1 calloc(3) function but instead of allo-
	   cating and initializing memory from the heap it allocates and ini-
	   tializes it from the global shared memory pool.

       char *MM_strdup(const char *str);
	   Identical to the POSIX.1 strdup(3) function but instead of creat-
	   ing the string copy in the heap it creates it in the global shared
	   memory pool.

       size_t MM_sizeof(const void *ptr);
	   This function returns the size in bytes of the chunk starting at
	   ptr when ptr was previously allocated with MM_malloc(3). The
	   result is undefined if ptr was not previously allocated with
	   MM_malloc(3).

       size_t MM_maxsize(void);
	   This function returns the maximum size which is allowed as the
	   first argument to the MM_create(3) function.

       size_t MM_available(void);
	   Returns the amount in bytes of still available (free) memory in
	   the global shared memory pool.

       char *MM_error(void);
	   Returns the last error message which occurred inside the OSSP mm
	   library.

       Standard Malloc-Style API


       MM *mm_create(size_t size, const char *file);
	   This creates a shared memory pool which has space for approxi-
	   mately a total of size bytes with the help of file. Here file is a
	   filesystem path to a file which need not to exist (and perhaps is
	   never created because this depends on the platform and chosen
	   shared memory and mutex implementation).  The return value is a
	   pointer to a "MM" structure which should be treated as opaque by
	   the application. It describes the internals of the created shared
	   memory pool. In case of an error "NULL" is returned.	 A size of 0
	   means to allocate the maximum allowed size which is platform
	   dependent and is between a few KB and the soft limit of 64MB.

       int mm_permission(MM *mm, mode_t mode, uid_t owner, gid_t group);
	   This sets the filesystem mode, owner and group for the shared mem-
	   ory pool mm (has effects only when the underlaying shared memory
	   segment implementation is actually based on external auxiliary
	   files).  The arguments are directly passed through to chmod(2) and
	   chown(2).

       void mm_destroy(MM *mm);
	   This destroys the complete shared memory pool mm and with it all
	   chunks which were allocated in this pool. Additionally any created
	   files on the filesystem corresponding the to shared memory pool
	   are unlinked.

       int mm_lock(MM *mm, mm_lock_mode mode);
	   This locks the shared memory pool mm for the current process in
	   order to perform either shared/read-only (mode is "MM_LOCK_RD") or
	   exclusive/read-write (mode is "MM_LOCK_RW") critical operations
	   inside the global shared memory pool.

       int mm_unlock(MM *mm);
	   This unlocks the shared memory pool mm for the current process
	   after critical operations were performed inside the global shared
	   memory pool.

       void *mm_malloc(MM *mm, size_t size);
	   This function allocates size bytes from the shared memory pool mm
	   and returns either a (virtual memory word aligned) pointer to it
	   or "NULL" in case of an error (out of memory). It behaves like the
	   POSIX.1 malloc(3) function but instead of allocating memory from
	   the heap it allocates it from the shared memory segment underlay-
	   ing mm.

       void mm_free(MM *mm, void *ptr);
	   This deallocates the chunk starting at ptr in the shared memory
	   pool mm.  It behaves like the POSIX.1 free(3) function but instead
	   of deallocating memory from the heap it deallocates it from the
	   shared memory segment underlaying mm.

       void *mm_realloc(MM *mm, void *ptr, size_t size);
	   This function reallocates the chunk starting at ptr inside the
	   shared memory pool mm with the new size of size bytes.  It behaves
	   like the POSIX.1 realloc(3) function but instead of reallocating
	   memory in the heap it reallocates it in the shared memory segment
	   underlaying mm.

       void *mm_calloc(MM *mm, size_t number, size_t size);
	   This is similar to mm_malloc(3), but additionally clears the
	   chunk. It behaves like the POSIX.1 calloc(3) function.  It allo-
	   cates space for number objects, each size bytes in length from the
	   shared memory pool mm.  The result is identical to calling mm_mal-
	   loc(3) with an argument of ‘‘number * size’’, with the exception
	   that the allocated memory is initialized to nul bytes.

       char *mm_strdup(MM *mm, const char *str);
	   This function behaves like the POSIX.1 strdup(3) function.  It
	   allocates sufficient memory inside the shared memory pool mm for a
	   copy of the string str, does the copy, and returns a pointer to
	   it.	The pointer may subsequently be used as an argument to the
	   function mm_free(3). If insufficient shared memory is available,
	   "NULL" is returned.

       size_t mm_sizeof(const void *ptr);
	   This function returns the size in bytes of the chunk starting at
	   ptr when ptr was previously allocated with mm_malloc(3). The
	   result is undefined when ptr was not previously allocated with
	   mm_malloc(3).

       size_t mm_maxsize(void);
	   This function returns the maximum size which is allowed as the
	   first argument to the mm_create(3) function.

       size_t mm_available(MM *mm);
	   Returns the amount in bytes of still available (free) memory in
	   the shared memory pool mm.

       char *mm_error(void);
	   Returns the last error message which occurred inside the OSSP mm
	   library.

       void mm_display_info(MM *mm);
	   This is debugging function which displays a summary page for the
	   shared memory pool mm describing various internal sizes and coun-
	   ters.

       Low-Level Shared Memory API


       void *mm_core_create(size_t size, const char *file);
	   This creates a shared memory area which is at least size bytes in
	   size with the help of file. The value size has to be greater than
	   0 and less or equal the value returned by mm_core_maxsegsize(3).
	   Here file is a filesystem path to a file which need not to exist
	   (and perhaps is never created because this depends on the platform
	   and chosen shared memory and mutex implementation).	The return
	   value is either a (virtual memory word aligned) pointer to the
	   shared memory segment or "NULL" in case of an error.	 The applica-
	   tion is guaranteed to be able to access the shared memory segment
	   from byte 0 to byte size-1 starting at the returned address.

       int mm_core_permission(void *core, mode_t mode, uid_t owner, gid_t
       group);
	   This sets the filesystem mode, owner and group for the shared mem-
	   ory segment code (has effects only when the underlaying shared
	   memory segment implementation is actually based on external auxil-
	   iary files).	 The arguments are directly passed through to
	   chmod(2) and chown(2).

       void mm_core_delete(void *core);
	   This deletes a shared memory segment core (as previously returned
	   by a mm_core_create(3) call). After this operation, accessing the
	   segment starting at core is no longer allowed and will usually
	   lead to a segmentation fault.

       int mm_core_lock(const void *core, mm_lock_mode mode);
	   This function acquires an advisory lock for the current process on
	   the shared memory segment core for either shared/read-only (mode
	   is "MM_LOCK_RD") or exclusive/read-write (mode is "MM_LOCK_RW")
	   critical operations between fork(2)’ed child processes.

       int mm_core_unlock(const void *core);
	   This function releases a previously acquired advisory lock for the
	   current process on the shared memory segment core.

       size_t mm_core_size(const void *core);
	   This returns the size in bytes of core. This size is exactly the
	   size which was used for creating the shared memory area via
	   mm_core_create(3). The function is provided just for convenience
	   reasons to not require the application to remember the memory size
	   behind core itself.

       size_t mm_core_maxsegsize(void);
	   This returns the number of bytes of a maximum-size shared memory
	   segment which is allowed to allocate via the MM library. It is
	   between a few KB and the soft limit of 64MB.

       size_t mm_core_align2page(size_t size);
	   This is just a utility function which can be used to align the
	   number size to the next virtual memory page boundary used by the
	   underlaying platform.  The memory page boundary under Unix plat-
	   forms is usually somewhere between 2048 and 16384 bytes. You do
	   not have to align the size arguments of other OSSP mm library
	   functions yourself, because this is already done internally.	 This
	   function is exported by the OSSP mm library just for convenience
	   reasons in case an application wants to perform similar
	   calculations for other purposes.

       size_t mm_core_align2word(size_t size);
	   This is another utility function which can be used to align the
	   number size to the next virtual memory word boundary used by the
	   underlaying platform.  The memory word boundary under Unix plat-
	   forms is usually somewhere between 4 and 16 bytes.  You do not
	   have to align the size arguments of other OSSP mm library func-
	   tions yourself, because this is already done internally.  This
	   function is exported by the OSSP mm library just for convenience
	   reasons in case an application wants to perform simular calcula-
	   tions for other purposes.

       Low-Level Shared Memory API


       void mm_lib_error_set(unsigned int, const char *str);
	   This is a function which is used internally by the various MM
	   function to set an error string. It’s usually not called directly
	   from applications.

       char *mm_lib_error_get(void);
	   This is a function which is used internally by MM_error(3) and
	   mm_error(3) functions to get the current error string. It is usu-
	   ally not called directly from applications.

       int mm_lib_version(void);
	   This function returns a hex-value ‘‘0xVRRTLL’’ which describes the
	   current OSSP mm library version. V is the version, RR the revi-
	   sions, LL the level and T the type of the level (alphalevel=0,
	   betalevel=1, patchlevel=2, etc). For instance OSSP mm version
	   1.0.4 is encoded as 0x100204.  The reason for this unusual mapping
	   is that this way the version number is steadily increasing.

RESTRICTIONS
       The maximum size of a continuous shared memory segment one can allo-
       cate depends on the underlaying platform. This cannot be changed, of
       course.	But currently the high-level malloc(3)-style API just uses a
       single shared memory segment as the underlaying data structure for an
       "MM" object which means that the maximum amount of memory an "MM"
       object represents also depends on the platform.

       This could be changed in later versions by allowing at least the high-
       level malloc(3)-style API to internally use multiple shared memory
       segments to form the "MM" object. This way "MM" objects could have
       arbitrary sizes, although the maximum size of an allocatable continous
       chunk still is bounded by the maximum size of a shared memory segment.

SEE ALSO
       mm-config(1).

       malloc(3), calloc(3), realloc(3), strdup(3), free(3), mmap(2),
       shmget(2), shmctl(2), flock(2), fcntl(2), semget(2), semctl(2),
       semop(2).

HOME
       http://www.ossp.org/pkg/lib/mm/

HISTORY
       This library was originally written in January 1999 by Ralf S.
       Engelschall <rse@engelschall.com> for use in the Extended API (EAPI)
       of the Apache HTTP server project (see http://www.apache.org/), which
       was originally invented for mod_ssl (see http://www.modssl.org/).

       Its base idea (a malloc-style API for handling shared memory) was
       originally derived from the non-publically available mm_malloc library
       written in October 1997 by Charles Randall <crandall@matchlogic.com>
       for MatchLogic, Inc.

       In 2000 this library joined the OSSP project where all other software
       development projects of Ralf S. Engelschall are located.

AUTHOR
	Ralf S. Engelschall
	rse@engelschall.com
	www.engelschall.com



19-Dec-2002			   MM 1.2.2				mm(3)