/* 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 #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