1## ====================================================================
2## Copyright (c) 1999-2006 Ralf S. Engelschall <rse@engelschall.com>
3## Copyright (c) 1999-2006 The OSSP Project <http://www.ossp.org/>
4##
5## Redistribution and use in source and binary forms, with or without
6## modification, are permitted provided that the following conditions
7## are met:
8##
9## 1. Redistributions of source code must retain the above copyright
10##    notice, this list of conditions and the following disclaimer.
11##
12## 2. Redistributions in binary form must reproduce the above copyright
13##    notice, this list of conditions and the following disclaimer in
14##    the documentation and/or other materials provided with the
15##    distribution.
16##
17## 3. All advertising materials mentioning features or use of this
18##    software must display the following acknowledgment:
19##    "This product includes software developed by
20##     Ralf S. Engelschall <rse@engelschall.com>."
21##
22## 4. Redistributions of any form whatsoever must retain the following
23##    acknowledgment:
24##    "This product includes software developed by
25##     Ralf S. Engelschall <rse@engelschall.com>."
26##
27## THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
28## EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30## PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL RALF S. ENGELSCHALL OR
31## ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
33## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36## STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
38## OF THE POSSIBILITY OF SUCH DAMAGE.
39## ====================================================================
40
41##
42## mm.pod -- Manpage
43##
44
45=pod
46
47=head1 NAME
48
49B<OSSP mm> - B<Shared Memory Allocation>
50
51=head1 VERSION
52
53OSSP mm MM_VERSION_STR
54
55=head1 SYNOPSIS
56
57 #include "mm.h"
58
59B< Global Malloc-Replacement API>
60
61 int     MM_create(size_t size, const char *file);
62 int     MM_permission(mode_t mode, uid_t owner, gid_t group);
63 void    MM_reset(void);
64 void    MM_destroy(void);
65 int     MM_lock(mm_lock_mode mode);
66 int     MM_unlock(void);
67 void   *MM_malloc(size_t size);
68 void   *MM_realloc(void *ptr, size_t size);
69 void    MM_free(void *ptr);
70 void   *MM_calloc(size_t number, size_t size);
71 char   *MM_strdup(const char *str);
72 size_t  MM_sizeof(void *ptr);
73 size_t  MM_maxsize(void);
74 size_t  MM_available(void);
75 char   *MM_error(void);
76
77B< Standard Malloc-Style API>
78
79 MM     *mm_create(size_t size, char *file);
80 int     mm_permission(MM *mm, mode_t mode, uid_t owner, gid_t group);
81 void    mm_reset(MM *mm);
82 void    mm_destroy(MM *mm);
83 int     mm_lock(MM *mm, mm_lock_mode mode);
84 int     mm_unlock(MM *mm);
85 void   *mm_malloc(MM *mm, size_t size);
86 void   *mm_realloc(MM *mm, void *ptr, size_t size);
87 void    mm_free(MM *mm, void *ptr);
88 void   *mm_calloc(MM *mm, size_t number, size_t size);
89 char   *mm_strdup(MM *mm, const char *str);
90 size_t  mm_sizeof(MM *mm, void *ptr);
91 size_t  mm_maxsize(void);
92 size_t  mm_available(MM *mm);
93 char   *mm_error(void);
94 void    mm_display_info(MM *mm);
95
96B< Low-level Shared Memory API>
97
98 void   *mm_core_create(size_t size, char *file);
99 int     mm_core_permission(void *core, mode_t mode, uid_t owner, gid_t group);
100 void    mm_core_delete(void *core);
101 int     mm_core_lock(void *core, mm_lock_mode mode);
102 int     mm_core_unlock(void *core);
103 size_t  mm_core_size(void *core);
104 size_t  mm_core_maxsegsize(void);
105 size_t  mm_core_align2page(size_t size);
106 size_t  mm_core_align2click(size_t size);
107
108B< Internal Library API>
109
110 void    mm_lib_error_set(unsigned int, const char *str);
111 char   *mm_lib_error_get(void);
112 int     mm_lib_version(void);
113
114=head1 DESCRIPTION
115
116The B<OSSP mm> library is a 2-layer abstraction library which simplifies the usage
117of shared memory between forked (and this way strongly related) processes
118under Unix platforms. On the first (lower) layer it hides all platform
119dependent implementation details (allocation and locking) when dealing with
120shared memory segments and on the second (higher) layer it provides a
121high-level malloc(3)-style API for a convenient and well known way to work
122with data-structures inside those shared memory segments.
123
124The abbreviation B<OSSP mm> is historically and originally comes from the phrase
125``I<memory mapped>'' as used by the POSIX.1 mmap(2) function. Because this
126facility is internally used by this library on most platforms to establish the
127shared memory segments.
128
129=head2 LIBRARY STRUCTURE
130
131This library is structured into three main APIs which are internally based on
132each other:
133
134=over 4
135
136=item B<Global Malloc-Replacement API>
137
138This is the most high-level API which directly can be used as replacement API
139for the POSIX.1 memory allocation API (malloc(2) and friends). This is
140useful when converting I<heap> based data structures to I<shared memory>
141based data structures without the need to change the code dramatically.  All
142which is needed is to prefix the POSIX.1 memory allocation functions with
143`C<MM_>', i.e. `C<malloc>' becomes `C<MM_malloc>', `C<strdup>' becomes
144`C<MM_strdup>', etc. This API internally uses just a global `C<MM *>' pool for
145calling the corresponding functions (those with prefix `C<mm_>') of the
146I<Standard Malloc-Style API>.
147
148=item B<Standard Malloc-Style API>
149
150This is the standard high-level memory allocation API. Its interface is
151similar to the I<Global Malloc-Replacement API> but it uses an explicit `C<MM *>'
152pool to operate on. That is why every function of this API has an argument of
153type `C<MM *>' as its first argument. This API provides a comfortable way to
154work with small dynamically allocated shared memory chunks inside large
155statically allocated shared memory segments. It is internally based on the
156I<Low-Level Shared Memory API> for creating the underlying shared memory
157segment.
158
159=item B<Low-Level Shared Memory API>
160
161This is the basis of the whole B<OSSP mm> library. It provides low-level functions
162for creating shared memory segments with mutual exclusion (in short I<mutex>)
163capabilities in a portable way. Internally the shared memory and mutex
164facility is implemented in various platform-dependent ways. A list of
165implementation variants follows under the next topic.
166
167=back
168
169=head2 SHARED MEMORY IMPLEMENTATION
170
171Internally the shared memory facility is implemented in various
172platform-dependent ways. Each way has its own advantages and disadvantages
173(in addition to the fact that some variants aren't available at all on some
174platforms). The B<OSSP mm> library's configuration procedure tries hard to make a
175good decision. The implemented variants are now given for overview and
176background reasons with their advantages and disadvantages and in an ascending
177order, i.e. the B<OSSP mm> configuration mechanism chooses the last available one
178in the list as the preferred variant.
179
180=over 4
181
182=item Classical mmap(2) on temporary file (MMFILE)
183
184I<Advantage:> maximum portable.
185I<Disadvantage:> needs a temporary file on the filesystem.
186
187=item mmap(2) via POSIX.1 shm_open(3) on temporary file (MMPOSX)
188
189I<Advantage:> standardized by POSIX.1 and theoretically portable.
190I<Disadvantage:> needs a temporary file on the filesystem and is
191is usually not available on existing Unix platform.
192
193=item SVR4-style mmap(2) on C</dev/zero> device (MMZERO)
194
195I<Advantage:> widely available and mostly portable on SVR4 platforms.
196I<Disadvantage:> needs the C</dev/zero> device and a mmap(2)
197which supports memory mapping through this device.
198
199=item SysV IPC shmget(2) (IPCSHM)
200
201I<Advantage:> does not need a temporary file or external device.
202I<Disadvantage:> although available on mostly all modern Unix platforms, it has
203strong restrictions like the maximum size of a single shared memory segment (can
204be as small as 100KB, but depends on the platform).
205
206=item 4.4BSD-style mmap(2) via C<MAP_ANON> facility (MMANON)
207
208I<Advantage:> does not need a temporary file or external device.
209I<Disadvantage:> usually only available on BSD platforms and derivatives.
210
211=back
212
213=head2 LOCKING IMPLEMENTATION
214
215As for the shared memory facility, internally the locking facility is
216implemented in various platform-dependent ways. They are again listed
217in ascending order, i.e. the B<OSSP mm> configuration mechanism chooses the
218last available one in the list as the preferred variant. The list of
219implemented variants is:
220
221=over 4
222
223=item 4.2BSD-style flock(2) on temporary file (FLOCK)
224
225I<Advantage:> exists on a lot of platforms, especially on older Unix
226derivatives. I<Disadvantage:> needs a temporary file on the filesystem and has
227to re-open file-descriptors to it in each(!) fork(2)'ed child process.
228
229=item SysV IPC semget(2) (IPCSEM)
230
231I<Advantage:> exists on a lot of platforms and does not need a temporary file.
232I<Disadvantage:> an unmeant termination of the application leads to a
233semaphore leak because the facility does not allow a ``remove in advance''
234trick (as the IPC shared memory facility does) for safe cleanups.
235
236=item SVR4-style fcntl(2) on temporary file (FCNTL)
237
238I<Advantage:> exists on a lot of platforms and is also the most powerful
239variant (although not always the fastest one). I<Disadvantage:> needs a
240temporary file.
241
242=back
243
244=head2 MEMORY ALLOCATION STRATEGY
245
246The memory allocation strategy the I<Standard Malloc-Style API> functions use
247internally is the following:
248
249=over 4
250
251=item B<Allocation>
252
253If a chunk of memory has to be allocated, the internal list of free chunks
254is searched for a minimal-size chunk which is larger or equal than the size of
255the to be allocated chunk (a I<best fit> strategy).
256
257If a chunk is found which matches this best-fit criteria, but is still a lot
258larger than the requested size, it is split into two chunks: One with exactly
259the requested size (which is the resulting chunk given back) and one with the
260remaining size (which is immediately re-inserted into the list of free
261chunks).
262
263If no fitting chunk is found at all in the list of free chunks, a new one is
264created from the spare area of the shared memory segment until the segment is
265full (in which case an I<out of memory> error occurs).
266
267=item B<Deallocation>
268
269If a chunk of memory has to be deallocated, it is inserted in sorted manner
270into the internal list of free chunks. The insertion operation automatically
271merges the chunk with a previous and/or a next free chunk if possible, i.e.
272if the free chunks stay physically seamless (one after another) in memory, to
273automatically form larger free chunks out of smaller ones.
274
275This way the shared memory segment is automatically defragmented when memory
276is deallocated.
277
278=back
279
280This strategy reduces memory waste and fragmentation caused by small and
281frequent allocations and deallocations to a minimum.
282
283The internal implementation of the list of free chunks is not specially
284optimized (for instance by using binary search trees or even I<splay> trees,
285etc), because it is assumed that the total amount of entries in the list of
286free chunks is always small (caused both by the fact that shared memory
287segments are usually a lot smaller than heaps and the fact that we always
288defragment by merging the free chunks if possible).
289
290=head1 API FUNCTIONS
291
292In the following, all API functions are described in detail. The order
293directly follows the one in the B<SYNOPSIS> section above.
294
295=head2 Global Malloc-Replacement API
296
297=over 4
298
299=item int B<MM_create>(size_t I<size>, const char *I<file>);
300
301This initializes the global shared memory pool with I<size> and I<file> and
302has to be called I<before> any fork(2) operations are performed by the
303application.
304
305=item int B<MM_permission>(mode_t I<mode>, uid_t I<owner>, gid_t I<group>);
306
307This sets the filesystem I<mode>, I<owner> and I<group> for the global shared
308memory pool (has effects only if the underlying shared memory segment
309implementation is actually based on external auxiliary files).  The arguments
310are directly passed through to chmod(2) and chown(2).
311
312=item void B<MM_reset>(void);
313
314This resets the global shared memory pool: all chunks that have been
315allocated in the pool are marked as free and are eligible for reuse. The
316global memory pool itself is not destroyed.
317
318=item void B<MM_destroy>(void);
319
320This destroys the global shared memory pool and should be called I<after> all
321child processes were killed.
322
323=item int B<MM_lock>(mm_lock_mode I<mode>);
324
325This locks the global shared memory pool for the current process in order to
326perform either shared/read-only (I<mode> is C<MM_LOCK_RD>) or
327exclusive/read-write (I<mode> is C<MM_LOCK_RW>) critical operations inside the
328global shared memory pool.
329
330=item int B<MM_unlock>(void);
331
332This unlocks the global shared memory pool for the current process after the
333critical operations were performed inside the global shared memory pool.
334
335=item void *B<MM_malloc>(size_t I<size>);
336
337Identical to the POSIX.1 malloc(3) function but instead of allocating
338memory from the I<heap> it allocates it from the global shared memory pool.
339
340=item void B<MM_free>(void *I<ptr>);
341
342Identical to the POSIX.1 free(3) function but instead of deallocating
343memory in the I<heap> it deallocates it in the global shared memory pool.
344
345=item void *B<MM_realloc>(void *I<ptr>, size_t I<size>);
346
347Identical to the POSIX.1 realloc(3) function but instead of reallocating
348memory in the I<heap> it reallocates it inside the global shared memory pool.
349
350=item void *B<MM_calloc>(size_t I<number>, size_t I<size>);
351
352Identical to the POSIX.1 calloc(3) function but instead of allocating and
353initializing memory from the I<heap> it allocates and initializes it from the
354global shared memory pool.
355
356=item char *B<MM_strdup>(const char *I<str>);
357
358Identical to the POSIX.1 strdup(3) function but instead of creating the
359string copy in the I<heap> it creates it in the global shared memory pool.
360
361=item size_t B<MM_sizeof>(const void *I<ptr>);
362
363This function returns the size in bytes of the chunk starting at I<ptr> when
364I<ptr> was previously allocated with MM_malloc(3). The result is undefined
365if I<ptr> was not previously allocated with MM_malloc(3).
366
367=item size_t B<MM_maxsize>(void);
368
369This function returns the maximum size which is allowed
370as the first argument to the MM_create(3) function.
371
372=item size_t B<MM_available>(void);
373
374Returns the amount in bytes of still available (free) memory in the global
375shared memory pool.
376
377=item char *B<MM_error>(void);
378
379Returns the last error message which occurred inside the B<OSSP mm> library.
380
381=back
382
383=head2 Standard Malloc-Style API
384
385=over 4
386
387=item MM *B<mm_create>(size_t I<size>, const char *I<file>);
388
389This creates a shared memory pool which has space for approximately a total of
390I<size> bytes with the help of I<file>. Here I<file> is a filesystem path to a
391file which need not to exist (and perhaps is never created because this
392depends on the platform and chosen shared memory and mutex implementation).
393The return value is a pointer to a C<MM> structure which should be treated as
394opaque by the application. It describes the internals of the created shared
395memory pool. In case of an error C<NULL> is returned.  A I<size> of 0 means to
396allocate the maximum allowed size which is platform dependent and is between a
397few KB and the soft limit of 64MB.
398
399=item int B<mm_permission>(MM *I<mm>, mode_t I<mode>, uid_t I<owner>, gid_t I<group>);
400
401This sets the filesystem I<mode>, I<owner> and I<group> for the shared memory
402pool I<mm> (has effects only when the underlying shared memory segment
403implementation is actually based on external auxiliary files).  The arguments
404are directly passed through to chmod(2) and chown(2).
405
406=item void B<mm_reset>(MM *I<mm>);
407
408This resets the shared memory pool I<mm>: all chunks that have been
409allocated in the pool are marked as free and are eligible for reuse. The
410memory pool itself is not destroyed.
411
412=item void B<mm_destroy>(MM *I<mm>);
413
414This destroys the complete shared memory pool I<mm> and with it all chunks
415which were allocated in this pool. Additionally any created files on the
416filesystem corresponding to the shared memory pool are unlinked.
417
418=item int B<mm_lock>(MM *I<mm>, mm_lock_mode I<mode>);
419
420This locks the shared memory pool I<mm> for the current process in order to
421perform either shared/read-only (I<mode> is C<MM_LOCK_RD>) or
422exclusive/read-write (I<mode> is C<MM_LOCK_RW>) critical operations inside the
423global shared memory pool.
424
425=item int B<mm_unlock>(MM *I<mm>);
426
427This unlocks the shared memory pool I<mm> for the current process after
428critical operations were performed inside the global shared memory pool.
429
430=item void *B<mm_malloc>(MM *I<mm>, size_t I<size>);
431
432This function allocates I<size> bytes from the shared memory pool I<mm> and
433returns either a (virtual memory word aligned) pointer to it or C<NULL> in
434case of an error (out of memory). It behaves like the POSIX.1 malloc(3)
435function but instead of allocating memory from the I<heap> it allocates it
436from the shared memory segment underlying I<mm>.
437
438=item void B<mm_free>(MM *I<mm>, void *I<ptr>);
439
440This deallocates the chunk starting at I<ptr> in the shared memory pool I<mm>.
441It behaves like the POSIX.1 free(3) function but instead of deallocating
442memory from the I<heap> it deallocates it from the shared memory segment
443underlying I<mm>.
444
445=item void *B<mm_realloc>(MM *I<mm>, void *I<ptr>, size_t I<size>);
446
447This function reallocates the chunk starting at I<ptr> inside the shared
448memory pool I<mm> with the new size of I<size> bytes.  It behaves like the
449POSIX.1 realloc(3) function but instead of reallocating memory in the
450I<heap> it reallocates it in the shared memory segment underlying I<mm>.
451
452=item void *B<mm_calloc>(MM *I<mm>, size_t I<number>, size_t I<size>);
453
454This is similar to mm_malloc(3), but additionally clears the chunk. It behaves
455like the POSIX.1 calloc(3) function.  It allocates space for I<number>
456objects, each I<size> bytes in length from the shared memory pool I<mm>.  The
457result is identical to calling mm_malloc(3) with an argument of ``I<number> *
458I<size>'', with the exception that the allocated memory is initialized to nul
459bytes.
460
461=item char *B<mm_strdup>(MM *I<mm>, const char *I<str>);
462
463This function behaves like the POSIX.1 strdup(3) function.  It allocates
464sufficient memory inside the shared memory pool I<mm> for a copy of the string
465I<str>, does the copy, and returns a pointer to it.  The pointer may
466subsequently be used as an argument to the function mm_free(3). If
467insufficient shared memory is available, C<NULL> is returned.
468
469=item size_t B<mm_sizeof>(MM *I<mm>, const void *I<ptr>);
470
471This function returns the size in bytes of the chunk starting at I<ptr>
472when I<ptr> was previously allocated with mm_malloc(3) inside the
473shared memory pool I<mm>. The result is undefined when I<ptr> was not
474previously allocated with mm_malloc(3).
475
476=item size_t B<mm_maxsize>(void);
477
478This function returns the maximum size which is allowed as the first argument
479to the mm_create(3) function.
480
481=item size_t B<mm_available>(MM *I<mm>);
482
483Returns the amount in bytes of still available (free) memory in the
484shared memory pool I<mm>.
485
486=item char *B<mm_error>(void);
487
488Returns the last error message which occurred inside the B<OSSP mm> library.
489
490=item void B<mm_display_info>(MM *I<mm>);
491
492This is debugging function which displays a summary page for the shared memory
493pool I<mm> describing various internal sizes and counters.
494
495=back
496
497=head2 Low-Level Shared Memory API
498
499=over 4
500
501=item void *B<mm_core_create>(size_t I<size>, const char *I<file>);
502
503This creates a shared memory area which is at least I<size> bytes in size with
504the help of I<file>. The value I<size> has to be greater than 0 and less or
505equal the value returned by mm_core_maxsegsize(3). Here I<file> is a
506filesystem path to a file which need not to exist (and perhaps is never
507created because this depends on the platform and chosen shared memory and
508mutex implementation).  The return value is either a (virtual memory word
509aligned) pointer to the shared memory segment or C<NULL> in case of an error.
510The application is guaranteed to be able to access the shared memory segment
511from byte 0 to byte I<size>-1 starting at the returned address.
512
513=item int B<mm_core_permission>(void *I<core>, mode_t I<mode>, uid_t I<owner>, gid_t I<group>);
514
515This sets the filesystem I<mode>, I<owner> and I<group> for the shared memory
516segment I<code> (has effects only when the underlying shared memory segment
517implementation is actually based on external auxiliary files).  The arguments
518are directly passed through to chmod(2) and chown(2).
519
520=item void B<mm_core_delete>(void *I<core>);
521
522This deletes a shared memory segment I<core> (as previously returned by a
523mm_core_create(3) call). After this operation, accessing the segment starting
524at I<core> is no longer allowed and will usually lead to a segmentation fault.
525
526=item int B<mm_core_lock>(const void *I<core>, mm_lock_mode I<mode>);
527
528This function acquires an advisory lock for the current process on the shared
529memory segment I<core> for either shared/read-only (I<mode> is C<MM_LOCK_RD>)
530or exclusive/read-write (I<mode> is C<MM_LOCK_RW>) critical operations between
531fork(2)'ed child processes.
532
533=item int B<mm_core_unlock>(const void *I<core>);
534
535This function releases a previously acquired advisory lock for the current
536process on the shared memory segment I<core>.
537
538=item size_t B<mm_core_size>(const void *I<core>);
539
540This returns the size in bytes of I<core>. This size is exactly the size which
541was used for creating the shared memory area via mm_core_create(3). The
542function is provided just for convenience reasons to not require the
543application to remember the memory size behind I<core> itself.
544
545=item size_t B<mm_core_maxsegsize>(void);
546
547This returns the number of bytes of a maximum-size shared memory segment which
548is allowed to allocate via the MM library. It is between a few KB and the soft
549limit of 64MB.
550
551=item size_t B<mm_core_align2page>(size_t I<size>);
552
553This is just a utility function which can be used to align the number I<size>
554to the next virtual memory I<page> boundary used by the underlying platform.
555The memory page boundary under Unix platforms is usually somewhere between
5562048 and 16384 bytes. You do not have to align the I<size> arguments of other
557B<OSSP mm> library functions yourself, because this is already done internally.
558This function is exported by the B<OSSP mm> library just for convenience reasons in
559case an application wants to perform similar calculations for other purposes.
560
561=item size_t B<mm_core_align2word>(size_t I<size>);
562
563This is another utility function which can be used to align the number I<size>
564to the next virtual memory I<word> boundary used by the underlying platform.
565The memory word boundary under Unix platforms is usually somewhere between 4
566and 16 bytes.  You do not have to align the I<size> arguments of other B<OSSP mm>
567library functions yourself, because this is already done internally.  This
568function is exported by the B<OSSP mm> library just for convenience reasons in case
569an application wants to perform similar calculations for other purposes.
570
571=back
572
573=head2 Low-Level Shared Memory API
574
575=over 4
576
577=item void B<mm_lib_error_set>(unsigned int, const char *str);
578
579This is a function which is used internally by the various MM function to set
580an error string. It's usually not called directly from applications.
581
582=item char *B<mm_lib_error_get>(void);
583
584This is a function which is used internally by MM_error(3) and mm_error(3)
585functions to get the current error string. It is usually not called directly
586from applications.
587
588=item int B<mm_lib_version>(void);
589
590This function returns a hex-value ``0xI<V>I<RR>I<T>I<LL>'' which describes the
591current B<OSSP mm> library version. I<V> is the version, I<RR> the revisions, I<LL>
592the level and I<T> the type of the level (alphalevel=0, betalevel=1,
593patchlevel=2, etc). For instance B<OSSP mm> version 1.0.4 is encoded as 0x100204.
594The reason for this unusual mapping is that this way the version number is
595steadily I<increasing>.
596
597=back
598
599=head1 RESTRICTIONS
600
601The maximum size of a continuous shared memory segment one can allocate
602depends on the underlying platform. This cannot be changed, of course.  But
603currently the high-level malloc(3)-style API just uses a single shared memory
604segment as the underlying data structure for an C<MM> object which means that
605the maximum amount of memory an C<MM> object represents also depends on the
606platform.
607
608This could be changed in later versions by allowing at least the
609high-level malloc(3)-style API to internally use multiple shared memory
610segments to form the C<MM> object. This way C<MM> objects could have
611arbitrary sizes, although the maximum size of an allocatable continuous
612chunk still is bounded by the maximum size of a shared memory segment.
613
614=head1 SEE ALSO
615
616mm-config(1).
617
618malloc(3), calloc(3), realloc(3), strdup(3), free(3), mmap(2), shmget(2),
619shmctl(2), flock(2), fcntl(2), semget(2), semctl(2), semop(2).
620
621=head1 HOME
622
623http://www.ossp.org/pkg/lib/mm/
624
625=head1 HISTORY
626
627This library was originally written in January 1999 by I<Ralf S.
628Engelschall> <rse@engelschall.com> for use in the B<Extended API> (EAPI)
629of the B<Apache> HTTP server project (see http://www.apache.org/), which
630was originally invented for B<mod_ssl> (see http://www.modssl.org/).
631
632Its base idea (a malloc-style API for handling shared memory) was originally
633derived from the non-publically available I<mm_malloc> library written in
634October 1997 by I<Charles Randall> <crandall@matchlogic.com> for MatchLogic,
635Inc.
636
637In 2000 this library joined the B<OSSP> project where all other software
638development projects of I<Ralf S. Engelschall> are located.
639
640=head1 AUTHOR
641
642 Ralf S. Engelschall
643 rse@engelschall.com
644 www.engelschall.com
645
646=cut
647
648