Skip to content

Latest commit

 

History

History
117 lines (83 loc) · 3.9 KB

File metadata and controls

117 lines (83 loc) · 3.9 KB

Memory Allocation

Header: libxs_malloc.h

Pool-based memory allocator designed for steady-state performance: after an initial warm-up phase, allocations are served from a recycled pool without system calls.

Types

typedef struct libxs_malloc_info_t {
  size_t size;  /* allocated size in bytes */
} libxs_malloc_info_t;
typedef struct libxs_malloc_pool_info_t {
  size_t used;      /* memory currently in use (sum of requested sizes) */
  size_t size;      /* total allocated memory (sum of actual chunk sizes) */
  size_t peak;      /* peak memory consumption */
  size_t nactive;   /* pending (not yet freed) allocations */
  size_t nmallocs;  /* total allocation count */
} libxs_malloc_pool_info_t;
typedef struct libxs_malloc_pool_t libxs_malloc_pool_t; /* opaque */
typedef void* (*libxs_malloc_fn)(size_t size);
typedef void  (*libxs_free_fn)(void* pointer);
typedef void* (*libxs_malloc_xfn)(size_t size, const void* extra);
typedef void  (*libxs_free_xfn)(void* pointer, const void* extra);

Pool Management

libxs_malloc_pool_t* libxs_malloc_pool(libxs_malloc_fn malloc_fn, libxs_free_fn free_fn);

Create a memory pool. If malloc_fn and free_fn are both NULL, the standard malloc/free are used. Both must be NULL or both must be non-NULL.

libxs_malloc_pool_t* libxs_malloc_xpool(libxs_malloc_xfn malloc_fn, libxs_free_xfn free_fn,
  int max_nthreads);

Create a memory pool with extended allocator functions that receive a per-thread extra argument (see libxs_malloc_arg). The max_nthreads parameter determines the size of the internal per-thread argument table (indexed by libxs_tid). Both function pointers must be non-NULL and max_nthreads must be positive; otherwise NULL is returned.

void libxs_malloc_arg(libxs_malloc_pool_t* pool, const void* extra);

Set the per-thread extra argument for an extended pool (created by libxs_malloc_xpool). The pointer is stored at the calling thread's slot (libxs_tid() % max_nthreads) and passed to the registered malloc_xfn/free_xfn on subsequent allocations and frees from this thread. No-op for standard pools. Access is lock-free since each thread writes only its own slot.

void libxs_free_pool(libxs_malloc_pool_t* pool);

Destroy the pool and release all associated memory. Accepts NULL.

int libxs_malloc_pool_info(const libxs_malloc_pool_t* pool, libxs_malloc_pool_info_t* info);

Query aggregate pool statistics.

General Allocation

void* libxs_malloc(libxs_malloc_pool_t* pool, size_t size, int alignment);

Allocate size bytes from the given pool. LIBXS_MALLOC_AUTO uses automatic alignment with inline metadata. LIBXS_MALLOC_NATIVE preserves the allocator's native pointer (out-of-band metadata via registry). Values greater than 1 are interpreted as explicit alignment in Bytes (inline metadata). Returns NULL on failure or if pool is NULL.

void libxs_free(void* pointer);

Return memory to its originating pool (derived internally). Accepts NULL.

int libxs_malloc_info(const void* pointer, libxs_malloc_info_t* info);

Query the size of an allocation made with libxs_malloc. The pool is derived internally.

Fixed-Size Pool

A lightweight fixed-size pool for scenarios where the element size is known at initialization time.

void libxs_pmalloc_init(size_t size, size_t* num,
  void* pool[], void* storage);

Partition storage into *num chunks of size bytes and register them in pool.

void* libxs_pmalloc(void* pool[], size_t* num);
void* libxs_pmalloc_lock(void* pool[], size_t* num,
  libxs_lock_t* lock);

Pop one chunk from the pool. The _lock variant uses a caller-provided lock; the plain variant uses an internal lock.

void libxs_pfree(void* pointer, void* pool[], size_t* num);
void libxs_pfree_lock(void* pointer, void* pool[],
  size_t* num, libxs_lock_t* lock);

Push a chunk back into the pool.