sig_alloc.h

include/sig/base/sig_alloc.h

sig_allocator_t

typedef struct {
    void *(*alloc)(size_t size);
    void *(*calloc)(size_t count, size_t size);
    void *(*realloc)(void *ptr, size_t size);
    void (*free)(void *ptr);
} sig_allocator_t;

sig_alloc_init

void sig_alloc_init()

Sets up the default allocator (libc pass-through, or the cmocka test allocator when built with SIG_TEST). Call once before any other sig_alloc_* function.

sig_alloc_shutdown

void sig_alloc_shutdown()

shared with sig_alloc_init

Sets up the default allocator (libc pass-through, or the cmocka test allocator when built with SIG_TEST). Call once before any other sig_alloc_* function.

sig_alloc_set_allocator

void sig_alloc_set_allocator(const sig_allocator_t * allocator)
ParameterType
allocatorconst sig_allocator_t *

Overrides the active allocator. Passing NULL restores the default chosen by sig_alloc_init(). Any function pointer in `allocator` may be NULL if that operation is not needed by the caller of this override (e.g. a test that only exercises sig_alloc()): a NULL pointer for any operation falls back to the libc implementation for that operation only, so sig_calloc/sig_realloc/sig_free (and their SIG_DEBUG counterparts) never dereference a NULL function pointer even if the override only sets `alloc`.

_sig_alloc_debug

void * _sig_alloc_debug(size_t size, const char * file, int line)
ParameterType
sizesize_t
fileconst char *
lineint

_sig_calloc_debug

void * _sig_calloc_debug(size_t count, size_t size, const char * file, int line)
ParameterType
countsize_t
sizesize_t
fileconst char *
lineint

_sig_realloc_debug

void * _sig_realloc_debug(void * ptr, size_t size, const char * file, int line)
ParameterType
ptrvoid *
sizesize_t
fileconst char *
lineint

_sig_free_debug

void _sig_free_debug(void * ptr, const char * file, int line)
ParameterType
ptrvoid *
fileconst char *
lineint

sig_alloc

#define sig_alloc(size)         _sig_alloc_debug((size), __FILE__, __LINE__)

sig_calloc

#define sig_calloc(count, size) _sig_calloc_debug((count), (size), __FILE__, __LINE__)

sig_realloc

#define sig_realloc(ptr, size)  _sig_realloc_debug((ptr), (size), __FILE__, __LINE__)

sig_free

#define sig_free(ptr)           _sig_free_debug((ptr), __FILE__, __LINE__)

sig_alloc

void * sig_alloc(size_t size)
ParameterType
sizesize_t

sig_calloc

void * sig_calloc(size_t count, size_t size)
ParameterType
countsize_t
sizesize_t

sig_realloc

void * sig_realloc(void * ptr, size_t size)
ParameterType
ptrvoid *
sizesize_t

sig_free

void sig_free(void * ptr)
ParameterType
ptrvoid *

sig_alloc_stats

typedef struct {
    uint64_t allocs;
    uint64_t frees;
    uint64_t reallocs;
    uint64_t bytes_requested; /* cumulative, never decreases */
    uint64_t live_blocks;     /* allocs - frees */
    bool live_bytes_tracked;
    uint64_t live_bytes; /* 0 unless live_bytes_tracked */
} sig_alloc_stats;

Allocation counters, maintained (atomically) in every build. Counts only successful calls: sig_realloc(NULL, n) is an alloc, a realloc of an existing block is a realloc (the live block count is unchanged), and sig_free(NULL) is ignored. Counters restart at sig_alloc_init(). live_bytes needs per-block size tracking, which only a SIG_DEBUG build has: live_bytes_tracked says whether live_bytes is meaningful.

sig_alloc_get_stats

void sig_alloc_get_stats(sig_alloc_stats * out)
ParameterType
outsig_alloc_stats *

sig_alloc_dump_sites

void sig_alloc_dump_sites(FILE * out, size_t top_n)
ParameterType
outFILE *
top_nsize_t

Writes the `top_n` allocation sites (file:line) holding the most live bytes, one per line, to `out`.

sig_strdup

sig_status_t sig_strdup(const char * s, char ** out)
ParameterType
sconst char *
outchar **