aoc-2025/libguf/guf_alloc_libc.h
2025-12-23 21:13:41 +01:00

121 lines
3.4 KiB
C
Executable File

/*
is parametrized: no
*/
#if defined(GUF_ALLOC_LIBC_IMPL_STATIC)
#define GUF_ALLOC_LIBC_KWRDS static inline
#else
#define GUF_ALLOC_LIBC_KWRDS
#endif
#ifndef GUF_ALLOC_LIBC_H
#define GUF_ALLOC_LIBC_H
#include <memory.h>
#include "guf_alloc.h"
#define GUF_ALLOC_TRACKER_IMPL_STATIC
#include "guf_alloc_tracker.h"
typedef struct guf_libc_alloc_ctx {
guf_alloc_tracker tracker;
bool zero_init;
} guf_libc_alloc_ctx;
#if !defined(GUF_ALLOC_LIBC_IMPL_STATIC) && !defined(GUF_ALLOC_LIBC_IMPL)
GUF_ALLOC_LIBC_KWRDS void *guf_libc_alloc(ptrdiff_t size, void *ctx);
GUF_ALLOC_LIBC_KWRDS void *guf_libc_realloc(void *ptr, ptrdiff_t old_size, ptrdiff_t new_size, void *ctx);
GUF_ALLOC_LIBC_KWRDS void guf_libc_free(void *ptr, ptrdiff_t size, void *ctx);
GUF_ALLOC_LIBC_KWRDS guf_allocator *guf_libc_allocator_init(guf_allocator *a, guf_libc_alloc_ctx *ctx);
GUF_ALLOC_LIBC_KWRDS guf_allocator guf_libc_allocator_new(guf_libc_alloc_ctx *ctx);
#endif
#if defined(GUF_ALLOC_LIBC_IMPL_STATIC) || defined(GUF_ALLOC_LIBC_IMPL)
GUF_ALLOC_LIBC_KWRDS void *guf_libc_alloc(ptrdiff_t size, void *ctx)
{
GUF_ASSERT_RELEASE(size >= 0);
guf_libc_alloc_ctx *alloc_ctx = (guf_libc_alloc_ctx*)ctx;
void *res = NULL;
if (size == 0) {
res = NULL;
} else if (alloc_ctx && alloc_ctx->zero_init) {
res = calloc(size, 1);
} else {
res = malloc(size);
}
if (alloc_ctx && alloc_ctx->tracker.enabled) {
const bool succ = guf_track_alloc(&alloc_ctx->tracker, size);
GUF_ASSERT(succ);
(void)succ;
}
return res;
}
GUF_ALLOC_LIBC_KWRDS void *guf_libc_realloc(void *ptr, ptrdiff_t old_size, ptrdiff_t new_size, void *ctx)
{
GUF_ASSERT_RELEASE(ptr);
GUF_ASSERT_RELEASE(old_size >= 0 && new_size >= 0);
if (old_size == new_size) {
return ptr;
}
guf_libc_alloc_ctx *alloc_ctx = (guf_libc_alloc_ctx*)ctx;
void *new_ptr = realloc(ptr, new_size);
if (!new_ptr || new_size == 0) {
new_ptr = NULL;
} else if (alloc_ctx && alloc_ctx->zero_init && new_size > old_size) {
const ptrdiff_t len = new_size - old_size;
GUF_ASSERT(len > 0);
GUF_ASSERT(old_size + len == new_size);
memset((char*)new_ptr + old_size, 0, len); // TODO: sketchy
}
if (alloc_ctx && alloc_ctx->tracker.enabled) {
const bool succ = guf_track_realloc(&alloc_ctx->tracker, old_size, new_size);
GUF_ASSERT(succ);
(void)succ;
}
return new_ptr;
}
GUF_ALLOC_LIBC_KWRDS void guf_libc_free(void *ptr, ptrdiff_t size, void *ctx)
{
free(ptr);
guf_libc_alloc_ctx *alloc_ctx = (guf_libc_alloc_ctx*)ctx;
if (alloc_ctx && alloc_ctx->tracker.enabled) {
const bool succ = guf_track_free(&alloc_ctx->tracker, size);
GUF_ASSERT(succ);
(void)succ;
}
}
GUF_ALLOC_LIBC_KWRDS guf_allocator *guf_libc_allocator_init(guf_allocator *a, guf_libc_alloc_ctx *ctx)
{
GUF_ASSERT_RELEASE(a);
a->alloc = guf_libc_alloc;
a->realloc = guf_libc_realloc;
a->free = guf_libc_free;
a->ctx = ctx;
return a;
}
GUF_ALLOC_LIBC_KWRDS guf_allocator guf_libc_allocator_new(guf_libc_alloc_ctx *ctx)
{
guf_allocator a;
guf_libc_allocator_init(&a, ctx);
return a;
}
#endif /* End impl */
#endif /* End header-guard */
#undef GUF_ALLOC_LIBC_IMPL_STATIC
#undef GUF_ALLOC_LIBC_IMPL
#undef GUF_ALLOC_LIBC_KWRDS