summaryrefslogtreecommitdiff
path: root/shmem/unix/mm/mm.h
blob: f97ab660705dbb42ac36c26153c3d02150e1e117 (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
/* ====================================================================
 * Copyright (c) 1999 Ralf S. Engelschall. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by
 *     Ralf S. Engelschall <rse@engelschall.com>."
 *
 * 4. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by
 *     Ralf S. Engelschall <rse@engelschall.com>."
 *
 * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL RALF S. ENGELSCHALL OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 */

/*
**
**  mm.h -- Shared Memory library API header
**
*/

#ifndef MM_H 
#define MM_H 1

#ifdef __cplusplus
extern "C" {
#endif

/*
**  ____ Public Part (I) of the API ________________________
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

/*
**  ____ Private Part of the API ___________________________
*/

#if defined(MM_PRIVATE)

#include "mm_conf.h"

#include <errno.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

#ifdef MM_OS_SUNOS
#include <memory.h>
/* SunOS lacks prototypes */
extern int getpagesize(void);
extern int munmap(caddr_t addr, int len);
extern int ftruncate(int fd, off_t length);
extern int flock(int fd, int operation);
extern char *strerror (int err);
#endif

#if !defined(FALSE)
#define FALSE 0
#endif
#if !defined(TRUE)
#define TRUE !FALSE
#endif
#if !defined(NULL)
#define NULL (void *)0
#endif
#if !defined(NUL)
#define NUL '\0'
#endif
#if !defined(min_of)
#define min_of(a,b) ((a) < (b) ? (a) : (b))
#endif
#if !defined(max_of)
#define max_of(a,b) ((a) > (b) ? (a) : (b))
#endif
#if !defined(absof)
#define abs_of(a) ((a) < 0 ? -(a) : (a))
#endif
#if !defined(offset_of)
#define offset_of(type,member) ((size_t)(&((type *)0)->member))
#endif

#if !defined(HAVE_MEMCPY) 
#if defined(HAVE_BCOPY)
#define memcpy(to,from,len) bcopy(from,to,len)
#else
#define memcpy(to,from,len) \
        { int i; for (i = 0; i < (len); i++) *((to)+i) = *((from)+i); }
#endif
#endif
#if !defined(HAVE_MEMSET)
#define memset(to,ch,len) \
        { int i; for (i = 0; i < (len); i++) *((to)+i) = (ch); }
#endif

#define ERR(type,str)   mm_lib_error_set(type,str)
#define FAIL(type,str)  { ERR(type,str); goto cus; }
#define BEGIN_FAILURE   cus:
#define END_FAILURE   

#if defined(HAVE_PATH_MAX)
#define MM_MAXPATH PATH_MAX
#elif defined(HAVE__POSIX_PATH_MAX)
#define MM_MAXPATH _POSIX_PATH_MAX
#elif defined(HAVE_MAXPATHLEN)
#define MM_MAXPATH MAXPATHLEN
#else
#define MM_MAXPATH 2048
#endif

#if defined(HAVE_CHILD_MAX)
#define MM_MAXCHILD CHILD_MAX
#elif defined(HAVE__POSIX_CHILD_MAX)
#define MM_MAXCHILD _POSIX_CHILD_MAX
#else
#define MM_MAXCHILD 512
#endif

#if defined(MM_SHMT_MMANON) || defined(MM_SHMT_MMPOSX) ||\
    defined(MM_SHMT_MMZERO) || defined(MM_SHMT_MMFILE)
#include <sys/mman.h>
#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
#define MAP_ANON MAP_ANONYMOUS
#endif
#if !defined(MAP_FAILED)
#define MAP_FAILED ((void *)-1)
#endif
#endif

#if defined(MM_SHMT_IPCSHM) || defined(MM_SEMT_IPCSEM)
#include <sys/ipc.h>
#endif

#if defined(MM_SHMT_IPCSHM)
#include <sys/shm.h>
#endif

#if defined(MM_SEMT_IPCSEM)
#include <sys/sem.h>
#ifndef HAVE_UNION_SEMUN
union semun {
    int val;
    struct semid_ds *buf;
    u_short *array;
};
#endif
#endif

#ifdef MM_SEMT_FLOCK
#include <sys/file.h>
#endif

#define MM_ALLOC_MINSIZE         (1024*8) 
#define MM_CORE_FILEMODE         (S_IRUSR|S_IWUSR)
#define MM_CORE_DEFAULT_PAGESIZE (1024*8)
#define MM_CORE_DEFAULT_FILE     "/tmp/mm.core.%d"  /* %d is PID */

#define MM_ERR_ALLOC    1
#define MM_ERR_CORE     2
#define MM_ERR_SYSTEM   4

/* 
 * Define a union with types which are likely to have the longest
 * *relevant* CPU-specific memory word alignment restrictions...
 */
union mem_word {
    void  *mw_vp;
    void (*mw_fp)(void);
    char  *mw_cp;
    long   mw_l;
    double mw_d;
};
typedef union mem_word mem_word;
#define SIZEOF_mem_word (sizeof(mem_word))

/*
 * Define the structure used for memory chunks
 */
union mem_chunk_mc_u {
    struct mem_chunk *mc_next; /* really used when it's free         */
    mem_word          mc_base; /* virtually used when it's allocated */
};
struct mem_chunk {
    size_t mc_size;      /* physical size   */
    size_t mc_usize;     /* user known size */
    union mem_chunk_mc_u mc_u;
};
typedef struct mem_chunk mem_chunk;
#define SIZEOF_mem_chunk (sizeof(mem_chunk)-sizeof(union mem_chunk_mc_u))

/*
 * Define the structure describing a memory pool
 */
struct mem_pool {
   size_t     mp_size;
   size_t     mp_offset;
   mem_chunk  mp_freechunks;
   mem_word   mp_base;
};
typedef struct mem_pool mem_pool;
#define SIZEOF_mem_pool (sizeof(mem_pool)-SIZEOF_mem_word)

/*
 * Define the structure holding per-process filedescriptors
 */
#if defined(MM_SEMT_FLOCK)
struct mem_core_fd {
    pid_t pid;
    int fd;
};
typedef struct mem_core_fd mem_core_fd;
#define SIZEOF_mem_core_fd (sizeof(mem_core_fd)
#endif

/*
 * Define the structure describing a shared memory core area
 * (the actual contents depends on the shared memory and
 * semaphore/mutex type and is stripped down to a minimum
 * required)
 */
struct mem_core {
   size_t       mc_size;
   size_t       mc_usize;
   pid_t        mc_pid;
   int          mc_fdmem;
#if defined(MM_SHMT_MMFILE)
   char         mc_fnmem[MM_MAXPATH];
#endif
#if !defined(MM_SEMT_FLOCK)
   int          mc_fdsem;
#endif
#if defined(MM_SEMT_FLOCK)
   mem_core_fd  mc_fdsem[MM_MAXCHILD];
#endif
#if defined(MM_SEMT_IPCSEM)
   int          mc_fdsem_rd;
   int          mc_readers;
   mm_lock_mode mc_lockmode;
#endif
#if defined(MM_SEMT_FLOCK) || defined(MM_SEMT_FCNTL)
   char         mc_fnsem[MM_MAXPATH];
#endif
   mem_word     mc_base;
};
typedef struct mem_core mem_core;
#define SIZEOF_mem_core (sizeof(mem_core)-SIZEOF_mem_word)

#endif /* MM_PRIVATE */

/*
**  ____ Public Part (II) of the API _______________________
*/

#if defined(MM_PRIVATE)
typedef mem_pool MM;
#else
typedef void MM;
#endif

typedef enum { 
    MM_LOCK_RD, MM_LOCK_RW
} mm_lock_mode;

/* Global Malloc-Replacement API */
int     MM_create(size_t size, const char *file);
int     MM_permission(mode_t mode, uid_t owner, gid_t group);
void    MM_destroy(void);
int     MM_lock(mm_lock_mode mode);
int     MM_unlock(void);
void   *MM_malloc(size_t size);
void   *MM_realloc(void *ptr, size_t size);
void    MM_free(void *ptr);
void   *MM_calloc(size_t number, size_t size);
char   *MM_strdup(const char *str);
size_t  MM_sizeof(const void *ptr);
size_t  MM_maxsize(void);
size_t  MM_available(void);
char   *MM_error(void);

/* Standard Malloc-Style API */
MM     *mm_create(size_t size, const char *file);
int     mm_permission(MM *mm, mode_t mode, uid_t owner, gid_t group);
void    mm_destroy(MM *mm);
int     mm_lock(MM *mm, mm_lock_mode mode);
int     mm_unlock(MM *mm);
void   *mm_malloc(MM *mm, size_t size);
void   *mm_realloc(MM *mm, void *ptr, size_t size);
void    mm_free(MM *mm, void *ptr);
void   *mm_calloc(MM *mm, size_t number, size_t size);
char   *mm_strdup(MM *mm, const char *str);
size_t  mm_sizeof(MM *mm, const void *ptr);
size_t  mm_maxsize(void);
size_t  mm_available(MM *mm);
char   *mm_error(void);
void    mm_display_info(MM *mm);

/* Low-Level Shared Memory API */
void   *mm_core_create(size_t size, const char *file);
int     mm_core_permission(void *core, mode_t mode, uid_t owner, gid_t group);
void    mm_core_delete(void *core);
size_t  mm_core_size(const void *core);
int     mm_core_lock(const void *core, mm_lock_mode mode);
int     mm_core_unlock(const void *core);
size_t  mm_core_maxsegsize(void);
size_t  mm_core_align2page(size_t size);
size_t  mm_core_align2word(size_t size);

/* Internal Library API */
void    mm_lib_error_set(unsigned int, const char *str);
char   *mm_lib_error_get(void);
int     mm_lib_version(void);

#ifdef __cplusplus
}
#endif

#endif /* MM_H */