infix
A JIT-Powered FFI Library for C
Loading...
Searching...
No Matches
813_custom_allocator.c File Reference

Unit test for the runtime pluggable allocator API (infix_set_allocator). More...

#include "common/compat_c23.h"
#include "common/double_tap.h"
#include "common/infix_internals.h"
#include <infix/infix.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
Include dependency graph for 813_custom_allocator.c:

Classes

struct  tracked_record_t
 

Macros

#define DBLTAP_IMPLEMENTATION
 
#define TRACKED_MAX_LIVE   4096
 

Functions

static int add_ints (int a, int b)
 
static void tracked_reset (void)
 
static size_t tracked_find (void *ptr)
 
static void tracked_add (void *ptr)
 
static void tracked_remove (void *ptr)
 
static void * tracked_malloc (size_t size)
 
static void * tracked_calloc (size_t nelem, size_t size)
 
static void * tracked_realloc (void *ptr, size_t new_size)
 
static void tracked_free (void *ptr)
 
static size_t tracked_total_alloc (void)
 Total blocks handed out by the tracking allocator (malloc + calloc).
 
static void ok_libc_defaults (const char *label)
 
 subtest ("installing and restoring the allocator")
 
 subtest ("full lifecycle routed through the custom allocator")
 
 subtest ("switching allocators between objects, never mid-lifecycle")
 

Variables

static tracked_record_t tracked_live [TRACKED_MAX_LIVE]
 
static size_t tracked_live_count
 
static size_t tracked_alloc_count
 
static size_t tracked_calloc_count
 
static size_t tracked_realloc_count
 
static size_t tracked_free_count
 
static bool tracked_unmatched_free
 
static const infix_allocator_t tracked_allocator
 
 TEST
 

Detailed Description

Unit test for the runtime pluggable allocator API (infix_set_allocator).

infix routes every internal heap allocation through the infix_allocator callback table, which hosts replace at runtime with infix_set_allocator(). This test installs a tracking allocator and verifies that a realistic infix lifecycle (registry creation, bulk type registration, signature parsing, JIT emission, an actual FFI call, and teardown) allocates and frees exclusively through the installed callbacks, that calloc and realloc reach the table too, that nothing leaks, and that passing NULL restores the libc defaults.

This is the regression test for the "wrong pool" scenario that bit Affix: memory handed to one allocator must always be released through the same allocator. tracked_free flags any pointer it never allocated (which would mean an allocation escaped the table), and the balance check flags any block still live after teardown (which would mean a free escaped the table).

Note on the trampoline cache: infix_forward_create deduplicates identical trampolines in a process-wide, refcounted cache, and infix_forward_destroy only releases the caller's reference, so a destroyed trampoline stays alive until _infix_cache_clear(). The test flushes that cache (through the currently installed allocator) so the balance check measures a complete lifecycle.

Unlike 811_fault_injection.c (which overrides infix's allocator at compile time with #define infix_malloc ...), this test uses the public runtime API and links the real library, exercising exactly the table indirection that consumers of a prebuilt libinfix rely on.

Macro Definition Documentation

◆ DBLTAP_IMPLEMENTATION

#define DBLTAP_IMPLEMENTATION

◆ TRACKED_MAX_LIVE

#define TRACKED_MAX_LIVE   4096

Function Documentation

◆ add_ints()

static int add_ints ( int  a,
int  b 
)
static

◆ ok_libc_defaults()

static void ok_libc_defaults ( const char *  label)
static

◆ subtest() [1/3]

subtest ( "full lifecycle routed through the custom allocator"  )

◆ subtest() [2/3]

subtest ( "installing and restoring the allocator"  )

◆ subtest() [3/3]

subtest ( "switching allocators between  objects,
never mid-lifecycle"   
)

◆ tracked_add()

static void tracked_add ( void *  ptr)
static

◆ tracked_calloc()

static void * tracked_calloc ( size_t  nelem,
size_t  size 
)
static

◆ tracked_find()

static size_t tracked_find ( void *  ptr)
static

◆ tracked_free()

static void tracked_free ( void *  ptr)
static

◆ tracked_malloc()

static void * tracked_malloc ( size_t  size)
static

◆ tracked_realloc()

static void * tracked_realloc ( void *  ptr,
size_t  new_size 
)
static

◆ tracked_remove()

static void tracked_remove ( void *  ptr)
static

◆ tracked_reset()

static void tracked_reset ( void  )
static

◆ tracked_total_alloc()

static size_t tracked_total_alloc ( void  )
static

Total blocks handed out by the tracking allocator (malloc + calloc).

Variable Documentation

◆ TEST

TEST
Initial value:
{
plan(3)
#define plan(count)
Definition double_tap.h:192

◆ tracked_alloc_count

size_t tracked_alloc_count
static

◆ tracked_allocator

const infix_allocator_t tracked_allocator
static
Initial value:
= {
.malloc = tracked_malloc, .calloc = tracked_calloc, .realloc = tracked_realloc, .free = tracked_free}
static void tracked_free(void *ptr)
Definition 813_custom_allocator.c:127
static void * tracked_malloc(size_t size)
Definition 813_custom_allocator.c:96
static void * tracked_realloc(void *ptr, size_t new_size)
Definition 813_custom_allocator.c:110
static void * tracked_calloc(size_t nelem, size_t size)
Definition 813_custom_allocator.c:103

◆ tracked_calloc_count

size_t tracked_calloc_count
static

◆ tracked_free_count

size_t tracked_free_count
static

◆ tracked_live

tracked_record_t tracked_live[TRACKED_MAX_LIVE]
static

◆ tracked_live_count

size_t tracked_live_count
static

◆ tracked_realloc_count

size_t tracked_realloc_count
static

◆ tracked_unmatched_free

bool tracked_unmatched_free
static