Skip to content

Memory Management

FastQueue supports pluggable allocators for memory-constrained environments.

Default Allocator

By default, FastQueue uses the system malloc/free:

c
fq_thread_pool_t *pool = NULL;
fq_thread_pool_create_ex(&pool, 4); // Uses default allocator

Custom Allocator

c
#include <fastqueue/fastqueue.h>
#include <stdio.h>
#include <stdlib.h>

static void *my_alloc(size_t size, void *ctx)
{
    (void)ctx;
    printf("Allocating %zu bytes\n", size);
    return malloc(size);
}

static void my_free(void *ptr, void *ctx)
{
    (void)ctx;
    free(ptr);
}

static void *my_realloc(void *ptr, size_t new_size, void *ctx)
{
    (void)ctx;
    return realloc(ptr, new_size);
}

int main(void)
{
    fq_allocator_t alloc = {
        .alloc   = my_alloc,
        .realloc = my_realloc,
        .free    = my_free,
        .ctx     = NULL
    };

    fq_scheduler_config_t cfg;
    fq_scheduler_config_default(&cfg);
    cfg.allocator = &alloc;
    cfg.thread_count = 4;

    fq_scheduler_t *scheduler = NULL;
    fq_scheduler_create(&scheduler, &cfg);

    // Use scheduler...

    fq_scheduler_shutdown(scheduler);
    return 0;
}

Arena Allocator Example

For high-throughput scenarios, an arena allocator can reduce allocation overhead:

c
#include <fastqueue/fastqueue.h>
#include <stdlib.h>
#include <string.h>

#define ARENA_SIZE (1024 * 1024)

typedef struct {
    char buffer[ARENA_SIZE];
    size_t offset;
} arena_t;

static void *arena_alloc(size_t size, void *ctx)
{
    arena_t *arena = (arena_t *)ctx;
    size_t aligned = (size + 7) & ~(size_t)7;
    if (arena->offset + aligned > ARENA_SIZE) return NULL;
    void *ptr = arena->buffer + arena->offset;
    arena->offset += aligned;
    return ptr;
}

static void arena_free(void *ptr, void *ctx)
{
    (void)ptr;
    (void)ctx;
}

static void *arena_realloc(void *ptr, size_t new_size, void *ctx)
{
    (void)ptr;
    (void)ctx;
    return NULL;
}

int main(void)
{
    static arena_t arena = {0};

    fq_allocator_t alloc = {
        .alloc   = arena_alloc,
        .realloc = arena_realloc,
        .free    = arena_free,
        .ctx     = &arena
    };

    fq_thread_pool_t *pool = NULL;
    fq_scheduler_config_t cfg;
    fq_scheduler_config_default(&cfg);
    cfg.allocator = &alloc;
    cfg.thread_count = 4;

    fq_thread_pool_create_configured(&pool, &cfg);

    for (int i = 0; i < 1000; ++i) {
        int *val = arena_alloc(sizeof(int), &arena);
        if (val) {
            *val = i;
            fq_thread_pool_submit_fn(pool, my_task, val);
        }
    }

    fq_thread_pool_wait_idle(pool);
    fq_thread_pool_shutdown(pool);
    return 0;
}

API Reference

c
typedef struct fq_allocator_t {
    void *(*alloc)(size_t size, void *ctx);
    void *(*realloc)(void *ptr, size_t size, void *ctx);
    void  (*free)(void *ptr, void *ctx);
    void  *ctx;
} fq_allocator_t;

const fq_allocator_t *fq_default_allocator(void);

Released under the MIT License.