| .rn '' }` |
| ''' $RCSfile: mm.3,v $$Revision: 1.1 $$Date: 1999/08/17 15:59:45 $ |
| ''' |
| ''' $Log: mm.3,v $ |
| ''' Revision 1.1 1999/08/17 15:59:45 rbb |
| ''' Initial revision |
| ''' |
| ''' |
| .de Sh |
| .br |
| .if t .Sp |
| .ne 5 |
| .PP |
| \fB\\$1\fR |
| .PP |
| .. |
| .de Sp |
| .if t .sp .5v |
| .if n .sp |
| .. |
| .de Ip |
| .br |
| .ie \\n(.$>=3 .ne \\$3 |
| .el .ne 3 |
| .IP "\\$1" \\$2 |
| .. |
| .de Vb |
| .ft CW |
| .nf |
| .ne \\$1 |
| .. |
| .de Ve |
| .ft R |
| |
| .fi |
| .. |
| ''' |
| ''' |
| ''' Set up \*(-- to give an unbreakable dash; |
| ''' string Tr holds user defined translation string. |
| ''' Bell System Logo is used as a dummy character. |
| ''' |
| .tr \(*W-|\(bv\*(Tr |
| .ie n \{\ |
| .ds -- \(*W- |
| .ds PI pi |
| .if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch |
| .if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch |
| .ds L" "" |
| .ds R" "" |
| ''' \*(M", \*(S", \*(N" and \*(T" are the equivalent of |
| ''' \*(L" and \*(R", except that they are used on ".xx" lines, |
| ''' such as .IP and .SH, which do another additional levels of |
| ''' double-quote interpretation |
| .ds M" """ |
| .ds S" """ |
| .ds N" """"" |
| .ds T" """"" |
| .ds L' ' |
| .ds R' ' |
| .ds M' ' |
| .ds S' ' |
| .ds N' ' |
| .ds T' ' |
| 'br\} |
| .el\{\ |
| .ds -- \(em\| |
| .tr \*(Tr |
| .ds L" `` |
| .ds R" '' |
| .ds M" `` |
| .ds S" '' |
| .ds N" `` |
| .ds T" '' |
| .ds L' ` |
| .ds R' ' |
| .ds M' ` |
| .ds S' ' |
| .ds N' ` |
| .ds T' ' |
| .ds PI \(*p |
| 'br\} |
| .\" If the F register is turned on, we'll generate |
| .\" index entries out stderr for the following things: |
| .\" TH Title |
| .\" SH Header |
| .\" Sh Subsection |
| .\" Ip Item |
| .\" X<> Xref (embedded |
| .\" Of course, you have to process the output yourself |
| .\" in some meaninful fashion. |
| .if \nF \{ |
| .de IX |
| .tm Index:\\$1\t\\n%\t"\\$2" |
| .. |
| .nr % 0 |
| .rr F |
| .\} |
| .TH mm 3 "24-Jun-1999" "MM 1.0.8" "Shared Memory Library" |
| .UC |
| .if n .hy 0 |
| .if n .na |
| .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' |
| .de CQ \" put $1 in typewriter font |
| .ft CW |
| 'if n "\c |
| 'if t \\&\\$1\c |
| 'if n \\&\\$1\c |
| 'if n \&" |
| \\&\\$2 \\$3 \\$4 \\$5 \\$6 \\$7 |
| '.ft R |
| .. |
| .\" @(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2 |
| . \" AM - accent mark definitions |
| .bd B 3 |
| . \" fudge factors for nroff and troff |
| .if n \{\ |
| . ds #H 0 |
| . ds #V .8m |
| . ds #F .3m |
| . ds #[ \f1 |
| . ds #] \fP |
| .\} |
| .if t \{\ |
| . ds #H ((1u-(\\\\n(.fu%2u))*.13m) |
| . ds #V .6m |
| . ds #F 0 |
| . ds #[ \& |
| . ds #] \& |
| .\} |
| . \" simple accents for nroff and troff |
| .if n \{\ |
| . ds ' \& |
| . ds ` \& |
| . ds ^ \& |
| . ds , \& |
| . ds ~ ~ |
| . ds ? ? |
| . ds ! ! |
| . ds / |
| . ds q |
| .\} |
| .if t \{\ |
| . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" |
| . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' |
| . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' |
| . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' |
| . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' |
| . ds ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10' |
| . ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m' |
| . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' |
| . ds q o\h'-\w'o'u*8/10'\s-4\v'.4m'\z\(*i\v'-.4m'\s+4\h'\w'o'u*8/10' |
| .\} |
| . \" troff and (daisy-wheel) nroff accents |
| .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' |
| .ds 8 \h'\*(#H'\(*b\h'-\*(#H' |
| .ds v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#] |
| .ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u' |
| .ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u' |
| .ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#] |
| .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] |
| .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' |
| .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' |
| .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] |
| .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] |
| .ds ae a\h'-(\w'a'u*4/10)'e |
| .ds Ae A\h'-(\w'A'u*4/10)'E |
| .ds oe o\h'-(\w'o'u*4/10)'e |
| .ds Oe O\h'-(\w'O'u*4/10)'E |
| . \" corrections for vroff |
| .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' |
| .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' |
| . \" for low resolution devices (crt and lpr) |
| .if \n(.H>23 .if \n(.V>19 \ |
| \{\ |
| . ds : e |
| . ds 8 ss |
| . ds v \h'-1'\o'\(aa\(ga' |
| . ds _ \h'-1'^ |
| . ds . \h'-1'. |
| . ds 3 3 |
| . ds o a |
| . ds d- d\h'-1'\(ga |
| . ds D- D\h'-1'\(hy |
| . ds th \o'bp' |
| . ds Th \o'LP' |
| . ds ae ae |
| . ds Ae AE |
| . ds oe oe |
| . ds Oe OE |
| .\} |
| .rm #[ #] #H #V #F C |
| .SH "NAME" |
| \fBMM \- Shared Memory Library\fR |
| .SH "VERSION" |
| MM 1.0.8 (24-Jun-1999) |
| .SH "SYNOPSIS" |
| .PP |
| .Vb 1 |
| \& #include "mm.h" |
| .Ve |
| \fB Global Malloc-Replacement API\fR |
| .PP |
| .Vb 14 |
| \& int \fBMM_create\fR(size_t size, const char *file); |
| \& int \fBMM_permission\fR(mode_t mode, uid_t owner, gid_t group); |
| \& void \fBMM_destroy\fR(void); |
| \& int \fBMM_lock\fR(mm_lock_mode mode); |
| \& int \fBMM_unlock\fR(void); |
| \& void *\fBMM_malloc\fR(size_t size); |
| \& void *\fBMM_realloc\fR(void *ptr, size_t size); |
| \& void \fBMM_free\fR(void *ptr); |
| \& void *\fBMM_calloc\fR(size_t number, size_t size); |
| \& char *\fBMM_strdup\fR(const char *str); |
| \& size_t \fBMM_sizeof\fR(void *ptr); |
| \& size_t \fBMM_maxsize\fR(void); |
| \& size_t \fBMM_available\fR(void); |
| \& char *\fBMM_error\fR(void); |
| .Ve |
| \fB Standard Malloc-Style API\fR |
| .PP |
| .Vb 15 |
| \& MM *\fBmm_create\fR(size_t size, char *file); |
| \& int \fBmm_permission\fR(MM *mm, mode_t mode, uid_t owner, gid_t group); |
| \& void \fBmm_destroy\fR(MM *mm); |
| \& int \fBmm_lock\fR(MM *mm, mm_lock_mode mode); |
| \& int \fBmm_unlock\fR(MM *mm); |
| \& void *\fBmm_malloc\fR(MM *mm, size_t size); |
| \& void *\fBmm_realloc\fR(MM *mm, void *ptr, size_t size); |
| \& void \fBmm_free\fR(MM *mm, void *ptr); |
| \& void *\fBmm_calloc\fR(MM *mm, size_t number, size_t size); |
| \& char *\fBmm_strdup\fR(MM *mm, const char *str); |
| \& size_t \fBmm_sizeof\fR(void *ptr); |
| \& size_t \fBmm_maxsize\fR(void); |
| \& size_t \fBmm_available\fR(MM *mm); |
| \& char *\fBmm_error\fR(void); |
| \& void \fBmm_display_info\fR(MM *mm); |
| .Ve |
| \fB Low-level Shared Memory API\fR |
| .PP |
| .Vb 9 |
| \& void *\fBmm_core_create\fR(size_t size, char *file); |
| \& int \fBmm_core_permission\fR(void *core, mode_t mode, uid_t owner, gid_t group); |
| \& void \fBmm_core_delete\fR(void *core); |
| \& int \fBmm_core_lock\fR(void *core, mm_lock_mode mode); |
| \& int \fBmm_core_unlock\fR(void *core); |
| \& size_t \fBmm_core_size\fR(void *core); |
| \& size_t \fBmm_core_maxsegsize\fR(void); |
| \& size_t \fBmm_core_align2page\fR(size_t size); |
| \& size_t \fBmm_core_align2click\fR(size_t size); |
| .Ve |
| \fB Internal Library API\fR |
| .PP |
| .Vb 3 |
| \& void \fBmm_lib_error_set\fR(unsigned int, const char *str); |
| \& char *\fBmm_lib_error_get\fR(void); |
| \& int \fBmm_lib_version\fR(void); |
| .Ve |
| .SH "DESCRIPTION" |
| The \fBMM\fR 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 \fImalloc\fR\|(3)\-style API for a convenient and well known way to work |
| with data-structures inside those shared memory segments. |
| .PP |
| The abbreviation \fBMM\fR is historically and originally comes from the phrase |
| ``\fImemory mapped\fR'\*(R' as used by the POSIX.1 \fImmap\fR\|(2) function. Because this |
| facility is internally used by this library on most platforms to create the |
| shared memory segments. |
| .Sh "\s-1LIBRARY\s0 \s-1STRUCTURE\s0" |
| This library is structured into three main APIs which are internally based on |
| each other: |
| .Ip "\fBGlobal Malloc-Replacement \s-1API\s0\fR" 4 |
| This is the most high-level \s-1API\s0 which directly can be used as replacement \s-1API\s0 |
| for the \s-1POSIX\s0.1 memory allocation \s-1API\s0 (\fImalloc\fR\|(2) and friends). This is |
| useful when converting \fIheap\fR based data structures to \fIshared memory\fR |
| based data structures without the need to change the code dramatically. All |
| which is needed is to prefix the \s-1POSIX\s0.1 memory allocation functions with |
| \f(CWMM_\fR, i.e. \f(CWmalloc\fR becomes \f(CWMM_malloc\fR, \f(CWstrdup\fR becomes \f(CWMM_strdup\fR, |
| etc. This \s-1API\s0 internally uses just a global \f(CWMM*\fR pool for calling the |
| corresponding functions (with prefix \f(CWmm_\fR) of the \fIStandard Malloc-Style |
| \s-1API\s0\fR. |
| .Ip "\fBStandard Malloc-Style \s-1API\s0\fR" 4 |
| This is the standard high-level memory allocation \s-1API\s0. It's interface is |
| similar to the \fIGlobal Malloc-Replacement \s-1API\s0\fR but it uses an explicit \f(CWMM*\fR |
| pool to operate on. That's why every function of this \s-1API\s0 has an argument of |
| type \f(CWMM*\fR as the first argument. This \s-1API\s0 provides a comfortable way to |
| work with small dynamically allocated shared memory chunks inside large |
| statically allocated shared memory segments. It's internally based on the |
| \fILow-Level Shared Memory \s-1API\s0\fR for creating the underlaying shared memory |
| segment. |
| .Ip "\fBLow-Level Shared Memory \s-1API\s0\fR" 4 |
| This is the basis of the whole \fB\s-1MM\s0\fR library. It provides low-level functions |
| for creating shared memory segments with mutual exclusion (in short: \fImutex\fR) |
| 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. |
| .Sh "\s-1SHARED\s0 \s-1MEMORY\s0 \s-1IMPLEMENTATION\s0" |
| Internally the shared memory facility is implemented in various |
| platform-dependent variants. Each has it's own advantages and disadvantages |
| (in addition to the fact that some variants aren't available at all on some |
| platforms). The \s-1MM\s0 libraries configuration procedure tried 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 \s-1MM\s0 configuration mechanism chooses the last available one in the list |
| as the preferred variant. |
| .Ip "Classical mmap(2) on temporary file (\s-1MMFILE\s0)" 4 |
| \fIAdvantage:\fR maximum portable. |
| \fIDisadvantage:\fR needs a temporary file on the filesystem |
| .Ip "mmap(2) via \s-1POSIX\s0.1 shm_open(3) on temporary file (\s-1MMPOSX\s0)" 4 |
| \fIAdvantage:\fR standardized by \s-1POSIX\s0.1 and theoretically portable. |
| \fIDisadvantage:\fR needs a temporary file on the filesystem and is |
| is usually not available on existing Unix platform. |
| .Ip "\s-1SVR4-\s0style mmap(2) on \f(CW/dev/zero\fR device (\s-1MMZERO\s0)" 4 |
| \fIAdvantage:\fR widely available on mostly portable on \s-1SVR4\s0 platforms. |
| \fIDisadvantage:\fR needs the \f(CW/dev/zero/\fR device and an \fImmap\fR\|(2) |
| which supports memory mapping through it. |
| .Ip "4.4BSD\-style mmap(2) via \f(CWMAP_ANON\fR facility (\s-1MMANON\s0)" 4 |
| \fIAdvantage:\fR doesn't need a temporary file or external device |
| \fIDisadvantage:\fR usually only available on \s-1BSD\s0 platforms and derivatives. |
| .Ip "SysV \s-1IPC\s0 shmget(2) (\s-1IPCSHM\s0)" 4 |
| \fIAdvantage:\fR doesn't need a temporary file or external device |
| \fIDisadvantage:\fR although available on mostly all modern Unix platforms it has |
| hard restrictions like the maximum size of a single shared memory segment (can |
| be as small as 100KB, but depends on the platform). |
| .Sh "\s-1LOCKING\s0 \s-1IMPLEMENTATION\s0" |
| As for the shared memory facility, internally the locking facility is |
| implemented in various platform-dependent variants. A short overview of |
| implemented variants is given: |
| .Ip "4.2BSD\-style flock(2) on temporary file (\s-1FLOCK\s0)" 4 |
| \fIAdvantage:\fR exists on a lot of platforms, especially on older Unix |
| derivates. \fIDisadvantage:\fR needs a temporary file on the filesystem and has |
| to reopen filedescriptors to it in \fIeach\fR\|(!) \fIfork\fR\|(2)ed child process. |
| .Ip "SysV \s-1IPC\s0 semget(2) (\s-1IPCSEM\s0)" 4 |
| \fIAdvantage:\fR exists on a lot of platforms and doesn't need a temporary file. |
| \fIDisadvantage:\fR an unmeant termination of the application leads to a |
| semaphore leak because the facility doesn't allow an \*(L"remove in advance\*(R" trick |
| (as the \s-1IPC\s0 shared memory facility does!) for safe cleanups. |
| .Ip "\s-1SVR4-\s0style fcntl(2) on temporary file (\s-1FCNTL\s0)" 4 |
| \fIAdvantage:\fR exists on a lot of platforms and is also the most powerful |
| variant (although not always the fastest one). \fIDisadvantage:\fR needs a |
| temporary file. |
| .Sh "\s-1MEMORY\s0 \s-1ALLOCATION\s0 \s-1STRATEGY\s0" |
| The memory allocation strategy the \fIStandard Malloc-Style \s-1API\s0\fR functions use |
| internally is the following: |
| .Ip "\fBAllocation\fR" 4 |
| When a chunk of memory has to be allocated, the internal list of free chunks |
| is searched for a minimal-sized chunk which is larger or equal than the size |
| of the to be allocated chunk (some sort of a \fIbest fit algorithm\fR). |
| .Sp |
| When 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) and one with the remaining |
| size (which is immediately re-inserted into the list of free chunks). |
| .Sp |
| When 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 \fIout of memory\fR error occurs). |
| .Ip "\fBDeallocation\fR" 4 |
| When 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 next free chunk when possible, i.e. |
| the free chunks stay physically seamless (one after another) in memory, to |
| automatically form larger free chunks out of smaller ones. |
| .Sp |
| This way the shared memory segment is automatically defragmented when memory |
| is deallocated. |
| .PP |
| This strategy reduces memory waste and fragmentation caused by small and |
| frequent allocations and deallocations to a minimum. |
| .PP |
| 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's 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 when possible). |
| .SH "API FUNCTIONS" |
| In the following all API functions are described in detail. |
| The order directly follows the one in the SYNOPSIS. |
| .Sh "Global Malloc-Replacement \s-1API\s0" |
| .Ip "int \fBMM_create\fR(size_t \fIsize\fR, const char *\fIfile\fR);" 4 |
| This initialized the global shared memory pool with \fIsize\fR and \fIfile\fR and |
| has be called \fIbefore\fR any \fIfork\fR\|(2) operations are performed by the |
| application. |
| .Ip "int \fBMM_permission\fR(mode_t \fImode\fR, uid_t \fIowner\fR, gid_t \fIgroup\fR);" 4 |
| This sets the filesystem \fImode\fR, \fIowner\fR and \fIgroup\fR for the global shared |
| memory pool (has effects only when the underlaying shared memory segment |
| implementation is actually based on external auxiliary files). The arguments |
| are directly passed through to \fIchmod\fR\|(2) and \fIchown\fR\|(2). |
| .Ip "void \fBMM_destroy\fR(void);" 4 |
| This destroys the global shared memory pool and should be called \fIafter\fR all |
| child processes were killed. |
| .Ip "int \fBMM_lock\fR(mm_lock_mode \fImode\fR);" 4 |
| This locks the global shared memory pool for the current process in order to |
| perform either shared/read-only (\fImode\fR is \f(CWMM_LOCK_RD\fR) or |
| exclusive/read-write (\fImode\fR is \f(CWMM_LOCK_RW\fR) operations inside the global |
| shared memory pool. |
| .Ip "int \fBMM_unlock\fR(void);" 4 |
| This unlocks the global shared memory pool for the current process after |
| mutual exclusion operations were performed inside the global shared memory |
| pool. |
| .Ip "void *\fBMM_malloc\fR(size_t \fIsize\fR);" 4 |
| Identical to the \s-1POSIX\s0.1 \fImalloc\fR\|(3) function but instead of allocating |
| memory from the \fIheap\fR it allocates it from the global shared memory pool. |
| .Ip "void \fBMM_free\fR(void *\fIptr\fR);" 4 |
| Identical to the \s-1POSIX\s0.1 \fIfree\fR\|(3) function but instead of deallocating |
| memory in the \fIheap\fR it deallocates it in the global shared memory pool. |
| .Ip "void *\fBMM_realloc\fR(void *\fIptr\fR, size_t \fIsize\fR);" 4 |
| Identical to the \s-1POSIX\s0.1 \fIrealloc\fR\|(3) function but instead of reallocating |
| memory in the \fIheap\fR it reallocates it inside the global shared memory pool. |
| .Ip "void *\fBMM_calloc\fR(size_t \fInumber\fR, size_t \fIsize\fR);" 4 |
| Identical to the \s-1POSIX\s0.1 \fIcalloc\fR\|(3) function but instead of allocating and |
| initializing memory from the \fIheap\fR it allocates and initializes it from the |
| global shared memory pool. |
| .Ip "char *\fBMM_strdup\fR(const char *\fIstr\fR);" 4 |
| Identical to the \s-1POSIX\s0.1 \fIstrdup\fR\|(3) function but instead of creating the |
| string copy in the \fIheap\fR it creates it in the global shared memory pool. |
| .Ip "size_t \fBMM_sizeof\fR(const void *\fIptr\fR);" 4 |
| This function returns the size in bytes of the chunk starting at \fIptr\fR when |
| \fIptr\fR was previously allocated with \fIMM_malloc\fR\|(3). The result is undefined |
| when \fIptr\fR was not previously allocated with \fIMM_malloc\fR\|(3). |
| .Ip "size_t \fBMM_maxsize\fR(void);" 4 |
| This function returns the maximum size which is allowed |
| as the first argument to the \fIMM_create\fR\|(3) function. |
| .Ip "size_t \fBMM_available\fR(void);" 4 |
| Returns the amount in bytes of still available (free) memory in the global |
| shared memory pool. |
| .Ip "char *\fBMM_error\fR(void);" 4 |
| Returns the last error message which occurred inside the \fB\s-1MM\s0\fR library. |
| .Sh "Standard Malloc-Style \s-1API\s0" |
| .Ip "\s-1MM\s0 *\fBmm_create\fR(size_t \fIsize\fR, const char *\fIfile\fR);" 4 |
| This creates a shared memory pool which has space for approximately a total of |
| \fIsize\fR bytes with the help of \fIfile\fR. Here \fIfile\fR 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 an \f(CWMM\fR 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 \f(CWNULL\fR is returned. A \fIsize\fR of 0 means to |
| allocate the maximum allowed size which is platform dependent and between a |
| few \s-1KB\s0 and the soft limit of 64MB. |
| .Ip "int \fBmm_permission\fR(\s-1MM\s0 *\fImm\fR, mode_t \fImode\fR, uid_t \fIowner\fR, gid_t \fIgroup\fR);" 4 |
| This sets the filesystem \fImode\fR, \fIowner\fR and \fIgroup\fR for the shared memory |
| pool \fImm\fR (has effects only when the underlaying shared memory segment |
| implementation is actually based on external auxiliary files). The arguments |
| are directly passed through to \fIchmod\fR\|(2) and \fIchown\fR\|(2). |
| .Ip "void \fBmm_destroy\fR(\s-1MM\s0 *\fImm\fR);" 4 |
| This destroys the complete shared memory pool \fImm\fR 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. |
| .Ip "int \fBmm_lock\fR(\s-1MM\s0 *\fImm\fR, mm_lock_mode \fImode\fR);" 4 |
| This locks the shared memory pool \fImm\fR for the current process in order to |
| perform either shared/read-only (\fImode\fR is \f(CWMM_LOCK_RD\fR) or |
| exclusive/read-write (\fImode\fR is \f(CWMM_LOCK_RW\fR) operations inside the global |
| shared memory pool. |
| .Ip "int \fBMM_unlock\fR(\s-1MM\s0 *\fImm\fR);" 4 |
| This unlocks the shared memory pool \fImm\fR for the current process after mutual |
| exclusion operations were performed inside the global shared memory pool. |
| .Ip "void *\fBmm_malloc\fR(\s-1MM\s0 *\fImm\fR, size_t \fIsize\fR);" 4 |
| This function allocates \fIsize\fR bytes from the shared memory pool \fImm\fR and |
| returns either a (virtual memory word aligned) pointer to it or \f(CWNULL\fR in |
| case of an error (out of memory). It behaves like the \s-1POSIX\s0.1 \fImalloc\fR\|(3) |
| function but instead of allocating memory from the \fIheap\fR it allocates it |
| from the shared memory segment underlaying \fImm\fR. |
| .Ip "void \fBmm_free\fR(\s-1MM\s0 *\fImm\fR, void *\fIptr\fR);" 4 |
| This deallocates the chunk starting at \fIptr\fR in the shared memory pool \fImm\fR. |
| It behaves like the \s-1POSIX\s0.1 \fIfree\fR\|(3) function but instead of deallocating |
| memory from the \fIheap\fR it deallocates it from the shared memory segment |
| underlaying \fImm\fR. |
| .Ip "void *\fBmm_realloc\fR(\s-1MM\s0 *\fImm\fR, void *\fIptr\fR, size_t \fIsize\fR);" 4 |
| This function reallocates the chunk starting at \fIptr\fR inside the shared |
| memory pool \fImm\fR with the new size of \fIsize\fR bytes. It behaves like the |
| \s-1POSIX\s0.1 \fIrealloc\fR\|(3) function but instead of reallocating memory in the |
| \fIheap\fR it reallocates it in the shared memory segment underlaying \fImm\fR. |
| .Ip "void *\fBmm_calloc\fR(\s-1MM\s0 *\fImm\fR, size_t \fInumber\fR, size_t \fIsize\fR);" 4 |
| This is similar to \fImm_malloc\fR\|(3), but additionally clears the chunk. It behaves |
| like the \s-1POSIX\s0.1 \fIcalloc\fR\|(3) function. It allocates space for \fInumber\fR |
| objects, each \fIsize\fR bytes in length from the shared memory pool \fImm\fR. The |
| result is identical to calling \fImm_malloc\fR\|(3) with an argument of ``\fInumber\fR * |
| \fIsize\fR'\*(R', with the exception that the allocated memory is initialized to nul |
| bytes. |
| .Ip "char *\fBmm_strdup\fR(\s-1MM\s0 *\fImm\fR, const char *\fIstr\fR);" 4 |
| This function behaves like the \s-1POSIX\s0.1 \fIstrdup\fR\|(3) function. It allocates |
| sufficient memory inside the shared memory pool \fImm\fR for a copy of the string |
| \fIstr\fR, does the copy, and returns a pointer to it. The pointer may |
| subsequently be used as an argument to the function \fImm_free\fR\|(3). If |
| insufficient shared memory is available, \f(CWNULL\fR is returned. |
| .Ip "size_t \fBmm_sizeof\fR(const void *\fIptr\fR);" 4 |
| This function returns the size in bytes of the chunk starting at \fIptr\fR when |
| \fIptr\fR was previously allocated with \fImm_malloc\fR\|(3). The result is undefined |
| when \fIptr\fR was not previously allocated with \fImm_malloc\fR\|(3). |
| .Ip "size_t \fBmm_maxsize\fR(void);" 4 |
| This function returns the maximum size which is allowed as the first argument |
| to the \fImm_create\fR\|(3) function. |
| .Ip "size_t \fBmm_available\fR(\s-1MM\s0 *\fImm\fR);" 4 |
| Returns the amount in bytes of still available (free) memory in the |
| shared memory pool \fImm\fR. |
| .Ip "char *\fBmm_error\fR(void);" 4 |
| Returns the last error message which occurred inside the \fB\s-1MM\s0\fR library. |
| .Ip "void \fBmm_display_info\fR(\s-1MM\s0 *\fImm\fR);" 4 |
| This is debugging function which displays a summary page for the shared memory |
| pool \fImm\fR describing various internal sizes and counters. |
| .Sh "Low-Level Shared Memory \s-1API\s0" |
| .Ip "void *\fBmm_core_create\fR(size_t \fIsize\fR, const char *\fIfile\fR);" 4 |
| This creates a shared memory area which is at least \fIsize\fR bytes in size with |
| the help of \fIfile\fR. The value \fIsize\fR has to be greater than 0 and less or |
| equal the value returned by \fImm_core_maxsegsize\fR\|(3). Here \fIfile\fR 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 \f(CWNULL\fR in case of an error. |
| The application is guaranteed to be able to access the shared memory segment |
| from byte 0 to byte \fIsize\fR\-1 starting at the returned address. |
| .Ip "int \fBmm_core_permission\fR(void *\fIcore\fR, mode_t \fImode\fR, uid_t \fIowner\fR, gid_t \fIgroup\fR);" 4 |
| This sets the filesystem \fImode\fR, \fIowner\fR and \fIgroup\fR for the shared memory |
| segment \fIcode\fR (has effects only when the underlaying shared memory segment |
| implementation is actually based on external auxiliary files). The arguments |
| are directly passed through to \fIchmod\fR\|(2) and \fIchown\fR\|(2). |
| .Ip "void \fBmm_core_delete\fR(void *\fIcore\fR);" 4 |
| This deletes a shared memory segment \fIcore\fR (as previously returned by a |
| \fImm_core_create\fR\|(3) call). After this operation, accessing the segment starting |
| at \fIcore\fR is no longer allowed and will usually lead to a segmentation fault. |
| .Ip "int \fBmm_core_lock\fR(const void *\fIcore\fR, mm_lock_mode \fImode\fR);" 4 |
| This function acquires an advisory lock for the current process on the shared |
| memory segment \fIcore\fR for either shared/read-only (\fImode\fR is \f(CWMM_LOCK_RD\fR) |
| or exclusive/read-write (\fImode\fR is \f(CWMM_LOCK_RW\fR) operations between |
| \fIfork\fR\|(2)'ed child processes. |
| .Ip "int \fBmm_core_unlock\fR(const void *\fIcore\fR);" 4 |
| This function releases a previously acquired advisory lock for the current |
| process on the shared memory segment \fIcore\fR. |
| .Ip "size_t \fBmm_core_size\fR(const void *\fIcore\fR);" 4 |
| This returns the size in bytes of \fIcore\fR. This size is exactly the size which |
| was used for creating the shared memory area via \fImm_core_create\fR\|(3). The |
| function is provided just for convenience reasons to not require the |
| application to remember the memory size behind \fIcore\fR itself. |
| .Ip "size_t \fBmm_core_maxsegsize\fR(void);" 4 |
| This returns the number of bytes of a maximum-size shared memory segment which |
| is allowed to allocate via the \s-1MM\s0 library. It is between a few \s-1KB\s0 and the soft |
| limit of 64MB. |
| .Ip "size_t \fBmm_core_align2page\fR(size_t \fIsize\fR);" 4 |
| This is just a utility function which can be used to align the number \fIsize\fR |
| to the next virtual memory \fIpage\fR boundary used by the underlaying platform. |
| The memory page boundary under Unix platforms is usually somewhere between |
| 2048 and 16384 bytes. You don't have to align the \fIsize\fR arguments of other |
| \fB\s-1MM\s0\fR library functions yourself, because this is already done internally. |
| This function is exported by the \fB\s-1MM\s0\fR library just for convenience reasons in |
| case an application wants to perform simular calculations for other purposes. |
| .Ip "size_t \fBmm_core_align2word\fR(size_t \fIsize\fR);" 4 |
| This is another utility function which can be used to align the number \fIsize\fR |
| to the next virtual memory \fIword\fR boundary used by the underlaying platform. |
| The memory word boundary under Unix platforms is usually somewhere between 4 |
| and 16 bytes. You don't have to align the \fIsize\fR arguments of other \fB\s-1MM\s0\fR |
| library functions yourself, because this is already done internally. This |
| function is exported by the \fB\s-1MM\s0\fR library just for convenience reasons in case |
| an application wants to perform simular calculations for other purposes. |
| .Sh "Low-Level Shared Memory \s-1API\s0" |
| .Ip "void \fBmm_lib_error_set\fR(unsigned int, const char *str);" 4 |
| This is a function which is used internally by the various \s-1MM\s0 function to set |
| an error string. It's usually not called directly from applications. |
| .Ip "char *\fBmm_lib_error_get\fR(void);" 4 |
| This is a function which is used internally by \fIMM_error\fR\|(3) and \fImm_error\fR\|(3) |
| functions to get the current error string. It's usually not called directly |
| from applications. |
| .Ip "int \fBmm_lib_version\fR(void);" 4 |
| This function returns a hex-value ``0x\fIV\fR\fI\s-1RR\s0\fR\fIT\fR\fI\s-1LL\s0\fR'\*(R' which describes the |
| current \s-1MM\s0 library version. \fIV\fR is the version, \fI\s-1RR\s0\fR the revisions, \fI\s-1LL\s0\fR |
| the level and \fIT\fR the type of the level (alphalevel=0, betalevel=1, |
| patchlevel=2, etc). For instance \s-1MM\s0 version 1.0.4 is encoded as 0x100204. The |
| reason for this unusual mapping is that this way the version number is |
| steadily \fIincreasing\fR. |
| .SH "RESTRICTIONS" |
| The maximum size of a continuous shared memory segment one can allocate |
| depends on the underlaying platform. This cannot be changed, of course. But |
| currently the high-level \fImalloc\fR\|(3)\-style API just uses a single shared memory |
| segment as the underlaying data structure for an \f(CWMM\fR object which means that |
| the maximum amount of memory a \f(CWMM\fR object represents also depends on the |
| platform. |
| .PP |
| This should be changed in later versions by allowing the high-level |
| \fImalloc\fR\|(3)\-style API to internally use multiple shared memory segments to form |
| the \f(CWMM\fR object. This way \f(CWMM\fR objects could have arbitrary sizes, although |
| the maximum size of an allocatable chunk still is bounded by the maximum size |
| of a shared memory segment. |
| .SH "SEE ALSO" |
| mm-\fIconfig\fR\|(1). |
| .PP |
| \fImalloc\fR\|(3), \fIcalloc\fR\|(3), \fIrealloc\fR\|(3), \fIstrdup\fR\|(3), \fIfree\fR\|(3), \fImmap\fR\|(2), \fIshmget\fR\|(2), |
| \fIshmctl\fR\|(2), \fIflock\fR\|(2), \fIfcntl\fR\|(2), \fIsemget\fR\|(2), \fIsemctl\fR\|(2), \fIsemop\fR\|(2). |
| .SH "HOME" |
| http://www.engelschall.com/sw/mm/ |
| |
| .SH "HISTORY" |
| This library was originally written in January 1999 by \fIRalf S. Engelschall\fR |
| <rse@engelschall.com> for use in the \fBExtended API\fR (EAPI) of the \fBApache\fR |
| HTTP server project (see www.apache.org), which was originally invented for |
| \fBmod_ssl\fR (see http://www.modssl.org/). |
| .PP |
| It's base idea (a malloc-style API for handling shared memory) was originally |
| derived from the non-publically available \fImm_malloc\fR library written in |
| October 1997 by \fICharles Randall\fR <crandall@matchlogic.com> for MatchLogic, |
| Inc. |
| .SH "AUTHOR" |
| .PP |
| .Vb 3 |
| \& Ralf S. Engelschall |
| \& rse@engelschall.com |
| \& www.engelschall.com |
| .Ve |
| |
| .rn }` '' |
| .IX Title "mm 3" |
| .IX Name "B<MM - Shared Memory Library>" |
| |
| .IX Header "NAME" |
| |
| .IX Header "VERSION" |
| |
| .IX Header "SYNOPSIS" |
| |
| .IX Header "DESCRIPTION" |
| |
| .IX Subsection "\s-1LIBRARY\s0 \s-1STRUCTURE\s0" |
| |
| .IX Item "\fBGlobal Malloc-Replacement \s-1API\s0\fR" |
| |
| .IX Item "\fBStandard Malloc-Style \s-1API\s0\fR" |
| |
| .IX Item "\fBLow-Level Shared Memory \s-1API\s0\fR" |
| |
| .IX Subsection "\s-1SHARED\s0 \s-1MEMORY\s0 \s-1IMPLEMENTATION\s0" |
| |
| .IX Item "Classical mmap(2) on temporary file (\s-1MMFILE\s0)" |
| |
| .IX Item "mmap(2) via \s-1POSIX\s0.1 shm_open(3) on temporary file (\s-1MMPOSX\s0)" |
| |
| .IX Item "\s-1SVR4-\s0style mmap(2) on \f(CW/dev/zero\fR device (\s-1MMZERO\s0)" |
| |
| .IX Item "4.4BSD\-style mmap(2) via \f(CWMAP_ANON\fR facility (\s-1MMANON\s0)" |
| |
| .IX Item "SysV \s-1IPC\s0 shmget(2) (\s-1IPCSHM\s0)" |
| |
| .IX Subsection "\s-1LOCKING\s0 \s-1IMPLEMENTATION\s0" |
| |
| .IX Item "4.2BSD\-style flock(2) on temporary file (\s-1FLOCK\s0)" |
| |
| .IX Item "SysV \s-1IPC\s0 semget(2) (\s-1IPCSEM\s0)" |
| |
| .IX Item "\s-1SVR4-\s0style fcntl(2) on temporary file (\s-1FCNTL\s0)" |
| |
| .IX Subsection "\s-1MEMORY\s0 \s-1ALLOCATION\s0 \s-1STRATEGY\s0" |
| |
| .IX Item "\fBAllocation\fR" |
| |
| .IX Item "\fBDeallocation\fR" |
| |
| .IX Header "API FUNCTIONS" |
| |
| .IX Subsection "Global Malloc-Replacement \s-1API\s0" |
| |
| .IX Item "int \fBMM_create\fR(size_t \fIsize\fR, const char *\fIfile\fR);" |
| |
| .IX Item "int \fBMM_permission\fR(mode_t \fImode\fR, uid_t \fIowner\fR, gid_t \fIgroup\fR);" |
| |
| .IX Item "void \fBMM_destroy\fR(void);" |
| |
| .IX Item "int \fBMM_lock\fR(mm_lock_mode \fImode\fR);" |
| |
| .IX Item "int \fBMM_unlock\fR(void);" |
| |
| .IX Item "void *\fBMM_malloc\fR(size_t \fIsize\fR);" |
| |
| .IX Item "void \fBMM_free\fR(void *\fIptr\fR);" |
| |
| .IX Item "void *\fBMM_realloc\fR(void *\fIptr\fR, size_t \fIsize\fR);" |
| |
| .IX Item "void *\fBMM_calloc\fR(size_t \fInumber\fR, size_t \fIsize\fR);" |
| |
| .IX Item "char *\fBMM_strdup\fR(const char *\fIstr\fR);" |
| |
| .IX Item "size_t \fBMM_sizeof\fR(const void *\fIptr\fR);" |
| |
| .IX Item "size_t \fBMM_maxsize\fR(void);" |
| |
| .IX Item "size_t \fBMM_available\fR(void);" |
| |
| .IX Item "char *\fBMM_error\fR(void);" |
| |
| .IX Subsection "Standard Malloc-Style \s-1API\s0" |
| |
| .IX Item "\s-1MM\s0 *\fBmm_create\fR(size_t \fIsize\fR, const char *\fIfile\fR);" |
| |
| .IX Item "int \fBmm_permission\fR(\s-1MM\s0 *\fImm\fR, mode_t \fImode\fR, uid_t \fIowner\fR, gid_t \fIgroup\fR);" |
| |
| .IX Item "void \fBmm_destroy\fR(\s-1MM\s0 *\fImm\fR);" |
| |
| .IX Item "int \fBmm_lock\fR(\s-1MM\s0 *\fImm\fR, mm_lock_mode \fImode\fR);" |
| |
| .IX Item "int \fBMM_unlock\fR(\s-1MM\s0 *\fImm\fR);" |
| |
| .IX Item "void *\fBmm_malloc\fR(\s-1MM\s0 *\fImm\fR, size_t \fIsize\fR);" |
| |
| .IX Item "void \fBmm_free\fR(\s-1MM\s0 *\fImm\fR, void *\fIptr\fR);" |
| |
| .IX Item "void *\fBmm_realloc\fR(\s-1MM\s0 *\fImm\fR, void *\fIptr\fR, size_t \fIsize\fR);" |
| |
| .IX Item "void *\fBmm_calloc\fR(\s-1MM\s0 *\fImm\fR, size_t \fInumber\fR, size_t \fIsize\fR);" |
| |
| .IX Item "char *\fBmm_strdup\fR(\s-1MM\s0 *\fImm\fR, const char *\fIstr\fR);" |
| |
| .IX Item "size_t \fBmm_sizeof\fR(const void *\fIptr\fR);" |
| |
| .IX Item "size_t \fBmm_maxsize\fR(void);" |
| |
| .IX Item "size_t \fBmm_available\fR(\s-1MM\s0 *\fImm\fR);" |
| |
| .IX Item "char *\fBmm_error\fR(void);" |
| |
| .IX Item "void \fBmm_display_info\fR(\s-1MM\s0 *\fImm\fR);" |
| |
| .IX Subsection "Low-Level Shared Memory \s-1API\s0" |
| |
| .IX Item "void *\fBmm_core_create\fR(size_t \fIsize\fR, const char *\fIfile\fR);" |
| |
| .IX Item "int \fBmm_core_permission\fR(void *\fIcore\fR, mode_t \fImode\fR, uid_t \fIowner\fR, gid_t \fIgroup\fR);" |
| |
| .IX Item "void \fBmm_core_delete\fR(void *\fIcore\fR);" |
| |
| .IX Item "int \fBmm_core_lock\fR(const void *\fIcore\fR, mm_lock_mode \fImode\fR);" |
| |
| .IX Item "int \fBmm_core_unlock\fR(const void *\fIcore\fR);" |
| |
| .IX Item "size_t \fBmm_core_size\fR(const void *\fIcore\fR);" |
| |
| .IX Item "size_t \fBmm_core_maxsegsize\fR(void);" |
| |
| .IX Item "size_t \fBmm_core_align2page\fR(size_t \fIsize\fR);" |
| |
| .IX Item "size_t \fBmm_core_align2word\fR(size_t \fIsize\fR);" |
| |
| .IX Subsection "Low-Level Shared Memory \s-1API\s0" |
| |
| .IX Item "void \fBmm_lib_error_set\fR(unsigned int, const char *str);" |
| |
| .IX Item "char *\fBmm_lib_error_get\fR(void);" |
| |
| .IX Item "int \fBmm_lib_version\fR(void);" |
| |
| .IX Header "RESTRICTIONS" |
| |
| .IX Header "SEE ALSO" |
| |
| .IX Header "HOME" |
| |
| .IX Header "HISTORY" |
| |
| .IX Header "AUTHOR" |
| |