get_mapping_size_needed_by_shm, get_shm_max_allocatable_size, get_shm_min_allocatable_size, get_sizeof_block_header, get_shm_user_base, ptr_calloc, ptr_free, ptr_malloc, shm_calloc, shm_deinit, shm_free, shm_init, shm_malloc -- shared memory allocation
#include "shm_alloc.h"
size_t
get_mapping_size_needed_by_shm
(void);
size_t
get_shm_max_allocatable_size
(void);
size_t
get_shm_min_allocatable_size
(void);
size_t
get_sizeof_block_header
(void);
void *
get_shm_user_base
(void)
void *
ptr_calloc
(size_t count, size_t size);
void
ptr_free
(void *ptr);
void *
ptr_malloc
(size_t size);
shm_offt
shm_calloc
(size_t count, size_t size);
void
shm_free
(shm_offt shm_ptr);
shm_offt
shm_malloc
(size_t size);
bool
shm_init
(void *optional_addr, const char *shm_filename);
void
shm_deinit
(void);
SHM_OFFT_TO_ADDR (offset)
SHM_ADDR_TO_OFFT (address)
- It is used to hold an offset in shared memory.
- It is an unsigned type.
- It is always atomic.
-
Format specifier for printing it is
PRIu_shm_offt
e.g.,printf("%" PRIu_shm_offt "\n", offset);
It returns the mapping space that would be required by the shared memory. It can be called before shm_init()
.
It returns the maximum size that can be allocated via shm_malloc()
/shm_calloc()
/ptr_malloc()
/ptr_calloc()
.
IMPORTANT: shm_malloc()
/shm_calloc()
/ptr_malloc()
/ptr_calloc()
allocate extra space for
the header as well which can be obtained by get_sizeof_block_header()
.
It returns the minimun size that will be allocated via shm_malloc()
/shm_calloc()
/ptr_malloc()
/ptr_calloc()
.
The implementation uses a buddy system for allocation, so generally the memory allocated is the next power of 2 of what was
requested. But if that next power of 2 is smaller than the min allocatable size, then memory allocated is equal to
min allocatable size.
Returns the extra size that is allocated by shm_malloc()
/shm_calloc()
/ptr_malloc()
/ptr_calloc()
for the header.
Returns the shared memory base for the current process where the allocations are done. Its return value should be casted to
uint8_t *
and added to an offset returned by shm_malloc()
or shm_calloc()
to access it.
Prefer using macros SHM_OFFT_TO_ADDR(offset)
and SHM_ADDR_TO_OFFT(address)
for clarity.
The macros are defined as follows:
#define SHM_OFFT_TO_ADDR(offset) ((void *)((uint8_t *)get_shm_user_base() + offset))
#define SHM_ADDR_TO_OFFT(address) ((shm_offt)((uint8_t *)address - (uint8_t *)get_shm_user_base()))
Sets up the shared memory for the current process.
-
param1: void *optional_addr
First argument toshm_init()
, which is an optional address is used as first argument ofmmap(2)
withMAP_FIXED
. IfNULL
is passed,mmap(2)
chooses an address by itself(which is recommended). This maybe useful if all processes map the memory at the same location. Then you can useptr_malloc()
just as regularmalloc(2)
without getting into complexities. Also, it is NOT the same as what is returned byget_shm_user_base()
. -
param2: const char *shm_filename
The filename of which is used as shared memory. ifNULL
is passed here, then environment variableSHM_FILE
will be checked for filename. -
Thread safety and return value: It can be called in multiple threads.
If calling it in multiple threads, it maybe possible that one thread returns
true
while the other returnsfalse
. If any one thread in the current process returned true, setup is done. A clean way to check for success in such cases would be to callget_shm_user_base()
aftershm_init()
and if it returnsNULL
, shared memory initialization has failed. -
On fork():
No need to call it in
fork(2)
'd processes ifshm_init()
was called successfully in parent. But no harm if you do call it in children, it will simply returntrue
-
Signal Safety:
It isn't aync-signal-safe
as it calls
mmap(2)
. Well ifmmap(2)
becomes signal safe in future, then this function is signal safe aswell.
It will release all recources held for shared memory for the current process.
Allocates memory in shared memory. Some extra memory is allocated for header aswell. That extra size can be obtained by get_sizeof_block_header()
-
param1: size_t size
The amount of memory to be allocated. This should be less than or equal to the return value ofget_shm_max_allocatable_size()
. If it exceeds the max allocatable size,SHM_NULL
is returned. -
To access the allocated memory, the returned offset needs to be added to the shared memory base for the process, which
is retuned by
get_shm_user_base()
.
Allocates memory in shared memory and sets it to all zero. That extra size can be obtained by get_sizeof_block_header()
-
params: size_t count, size_t size
count * size
= The amount of memory to be allocated. This should be less than or equal to the return value ofget_shm_max_allocatable_size()
. If it exceeds the max allocatable size,SHM_NULL
is returned. -
To access the allocated memory, the returned offset needs to be added to the shared memory base for the process, which
is retuned by
get_shm_user_base()
. -
It sets the allocated memory to all zero via
memset(3)
.
Frees memory in shared memory.
-
param1: shm_offt shm_ptr
param1 defines the offset of the memory in the shared memory that needs to be freed.
Allocates memory in shared memory. Some extra memory is allocated for header aswell. That extra size can be obtained by get_sizeof_block_header()
It is just a wrapper around shm_malloc()
.
It allocates via shm_malloc()
in the shared memory, and returns the location of allocated memory in the current process,
i.e., it uses SHM_OFFT_TO_ADDR(offset)
internally to compute address as per the offset.
If shm_malloc()
returns SHM_NULL
, then ptr_malloc()
returns NULL
.
Allocates memory in shared memory and sets it to all zero. Some extra memory is allocated for header aswell. That extra size can be obtained by get_sizeof_block_header()
It is just a wrapper around shm_calloc()
.
It allocates via shm_calloc()
in the shared memory, and returns the location of allocated memory in the current process,
i.e., it uses SHM_OFFT_TO_ADDR(offset)
internally to compute address as per the offset.
If shm_calloc()
returns SHM_NULL
, then ptr_calloc()
returns NULL
.
Frees memory in shared memory.
It is just a wrapper around shm_free()
. It computes the offset in shared memory by SHM_ADDR_TO_OFFT(address)
and calls shm_free()
.
shm_malloc()
and shm_calloc()
return SHM_NULL
on failure.
ptr_malloc()
and ptr_calloc()
return NULL
on failure.
shm_init()
returns true on success else false. If calling it in multiple threads, see it's description
for more information on its return value in multiple threads.