Skip to content

Latest commit

 

History

History
274 lines (200 loc) · 8.96 KB

man.md

File metadata and controls

274 lines (200 loc) · 8.96 KB

NAME

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


SYNOPSIS

#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)


DESCRIPTION


shm_offt

  • 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);

get_mapping_size_needed_by_shm():

It returns the mapping space that would be required by the shared memory. It can be called before shm_init().


get_shm_max_allocatable_size():

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().


get_shm_min_allocatable_size():

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.


get_sizeof_block_header():

Returns the extra size that is allocated by shm_malloc()/shm_calloc()/ptr_malloc()/ptr_calloc() for the header.


get_shm_user_base():

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()))

shm_init():

Sets up the shared memory for the current process.

  • param1: void *optional_addr
    First argument to shm_init(), which is an optional address is used as first argument of mmap(2) with MAP_FIXED. If NULL 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 use ptr_malloc() just as regular malloc(2) without getting into complexities. Also, it is NOT the same as what is returned by get_shm_user_base().
  • param2: const char *shm_filename
    The filename of which is used as shared memory. if NULL is passed here, then environment variable SHM_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 returns false. 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 call get_shm_user_base() after shm_init() and if it returns NULL, shared memory initialization has failed.
  • On fork(): No need to call it in fork(2)'d processes if shm_init() was called successfully in parent. But no harm if you do call it in children, it will simply return true
  • Signal Safety: It isn't aync-signal-safe as it calls mmap(2). Well if mmap(2) becomes signal safe in future, then this function is signal safe aswell.

shm_deinit():

It will release all recources held for shared memory for the current process.


shm_malloc():

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 of get_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().

shm_calloc():

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 of get_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).

shm_free():

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.

ptr_malloc():

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.


ptr_calloc():

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.


ptr_free():

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().

RETURN VALUES

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.