Provided by: libmm-dev_1.4.2-5ubuntu3_amd64 bug

NAME

       OSSP mm - Shared Memory Allocation

VERSION

       OSSP mm 1.4.2 (15-Aug-2006)

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_reset(void);
        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_reset(MM *mm);
        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(MM *mm, 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 convenient 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 platforms 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. `"malloc"' 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 interface is similar to the
           Global Malloc-Replacement API but it uses an explicit `"MM *"' pool to operate on.
           That is why every function 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 underlying 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. Internally the shared memory and mutex facility is implemented in
           various 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 platform-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 disadvantages 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 platforms, it has strong restrictions like the
           maximum size of a single 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 derivatives.

       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 derivatives.
           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 temporary file.
           Disadvantage: an unmeant termination of the application 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 powerful 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 resulting 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 segment 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
           physically 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 specially 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 underlying 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_reset(void);
           This resets the global shared memory pool: all chunks that have been allocated in the
           pool are marked as free and are eligible for reuse. The global memory pool itself is
           not destroyed.

       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 allocating 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 deallocating 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 reallocating 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 allocating and initializing
           memory from the heap it allocates and initializes it from the global shared memory
           pool.

       char *MM_strdup(const char *str);
           Identical to the POSIX.1 strdup(3) function but instead of creating 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 approximately 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 memory pool mm (has
           effects only when the underlying 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_reset(MM *mm);
           This resets the shared memory pool mm: all chunks that have been allocated in the pool
           are marked as free and are eligible for reuse. The memory pool itself is not
           destroyed.

       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
           to the 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 underlying 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 underlying 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 underlying 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 allocates space for number objects, each size
           bytes in length from the shared memory pool mm.  The result is identical to calling
           mm_malloc(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(MM *mm, 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) inside the shared memory pool mm. 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 counters.

       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
           application 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 memory segment code (has
           effects only when the underlying 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_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 underlying platform.  The memory page
           boundary under Unix platforms 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 underlying platform.  The memory word
           boundary under Unix platforms is usually somewhere between 4 and 16 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.

       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 usually 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 revisions, 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 allocate depends on the
       underlying 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 underlying 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 continuous 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