Provided by: libmm-dev_1.4.2-7_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

15-Aug-2006                                         MM 1.4.2                                               mm(3)