summaryrefslogtreecommitdiff
path: root/shmem/unix/mm/mm.3
blob: e37b289339695a302b09c02839968eb28113f239 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
.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"