From 06b49a3419f35ee8c802f1f15b52cc45b546efb3 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 10 Aug 2022 05:32:34 -0400 Subject: Update zix --- src/zix/allocator.h | 186 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 src/zix/allocator.h (limited to 'src/zix/allocator.h') diff --git a/src/zix/allocator.h b/src/zix/allocator.h new file mode 100644 index 0000000..bcffda5 --- /dev/null +++ b/src/zix/allocator.h @@ -0,0 +1,186 @@ +// Copyright 2021 David Robillard +// SPDX-License-Identifier: ISC + +#ifndef ZIX_ALLOCATOR_H +#define ZIX_ALLOCATOR_H + +#include "zix/attributes.h" + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + @addtogroup zix + @{ + @name Allocator + @{ +*/ + +struct ZixAllocatorImpl; + +/** + A memory allocator. + + This object-like structure provides an interface like the standard C + functions malloc(), calloc(), realloc(), free(), and aligned_alloc(). It + contains function pointers that differ from their standard counterparts by + taking a context parameter (a pointer to this struct), which allows the user + to implement custom stateful allocators. +*/ +typedef struct ZixAllocatorImpl ZixAllocator; + +/** + General malloc-like memory allocation function. + + This works like the standard C malloc(), except has an additional handle + parameter for implementing stateful allocators without static data. +*/ +typedef void* ZIX_ALLOCATED (*ZixMallocFunc)( // + ZixAllocator* ZIX_NULLABLE allocator, + size_t size); + +/** + General calloc-like memory allocation function. + + This works like the standard C calloc(), except has an additional handle + parameter for implementing stateful allocators without static data. +*/ +typedef void* ZIX_ALLOCATED (*ZixCallocFunc)( // + ZixAllocator* ZIX_NULLABLE allocator, + size_t nmemb, + size_t size); + +/** + General realloc-like memory reallocation function. + + This works like the standard C remalloc(), except has an additional handle + parameter for implementing stateful allocators without static data. +*/ +typedef void* ZIX_ALLOCATED (*ZixReallocFunc)( // + ZixAllocator* ZIX_NULLABLE allocator, + void* ZIX_NULLABLE ptr, + size_t size); + +/** + General free-like memory deallocation function. + + This works like the standard C remalloc(), except has an additional handle + parameter for implementing stateful allocators without static data. +*/ +typedef void (*ZixFreeFunc)( // + ZixAllocator* ZIX_NULLABLE allocator, + void* ZIX_NULLABLE ptr); + +/** + General aligned_alloc-like memory deallocation function. + + This works like the standard C aligned_alloc(), except has an additional + handle parameter for implementing stateful allocators without static data. +*/ +typedef void* ZIX_ALLOCATED (*ZixAlignedAllocFunc)( // + ZixAllocator* ZIX_NULLABLE allocator, + size_t alignment, + size_t size); + +/** + General aligned memory deallocation function. + + This works like the standard C free(), but must be used to free memory + allocated with the aligned_alloc() method of the allocator. This allows + portability to systems (like Windows) that can not use the same free function + in these cases. +*/ +typedef void (*ZixAlignedFreeFunc)( // + ZixAllocator* ZIX_NULLABLE allocator, + void* ZIX_NULLABLE ptr); + +/// Definition of ZixAllocator +struct ZixAllocatorImpl { + ZixMallocFunc ZIX_NONNULL malloc; + ZixCallocFunc ZIX_NONNULL calloc; + ZixReallocFunc ZIX_NONNULL realloc; + ZixFreeFunc ZIX_NONNULL free; + ZixAlignedAllocFunc ZIX_NONNULL aligned_alloc; + ZixAlignedFreeFunc ZIX_NONNULL aligned_free; +}; + +/// Return the default allocator which simply uses the system allocator +ZIX_CONST_API +ZixAllocator* ZIX_NONNULL +zix_default_allocator(void); + +/// Convenience wrapper that defers to malloc() if allocator is null +static inline void* ZIX_ALLOCATED +zix_malloc(ZixAllocator* const ZIX_NULLABLE allocator, const size_t size) +{ + ZixAllocator* const actual = allocator ? allocator : zix_default_allocator(); + + return actual->malloc(actual, size); +} + +/// Convenience wrapper that defers to calloc() if allocator is null +static inline void* ZIX_ALLOCATED +zix_calloc(ZixAllocator* const ZIX_NULLABLE allocator, + const size_t nmemb, + const size_t size) +{ + ZixAllocator* const actual = allocator ? allocator : zix_default_allocator(); + + return actual->calloc(actual, nmemb, size); +} + +/// Convenience wrapper that defers to realloc() if allocator is null +static inline void* ZIX_ALLOCATED +zix_realloc(ZixAllocator* const ZIX_NULLABLE allocator, + void* const ZIX_NULLABLE ptr, + const size_t size) +{ + ZixAllocator* const actual = allocator ? allocator : zix_default_allocator(); + + return actual->realloc(actual, ptr, size); +} + +/// Convenience wrapper that defers to free() if allocator is null +static inline void +zix_free(ZixAllocator* const ZIX_NULLABLE allocator, + void* const ZIX_NULLABLE ptr) +{ + ZixAllocator* const actual = allocator ? allocator : zix_default_allocator(); + + actual->free(actual, ptr); +} + +/// Convenience wrapper that defers to the system allocator if allocator is null +static inline void* ZIX_ALLOCATED +zix_aligned_alloc(ZixAllocator* const ZIX_NULLABLE allocator, + const size_t alignment, + const size_t size) +{ + ZixAllocator* const actual = allocator ? allocator : zix_default_allocator(); + + return actual->aligned_alloc(actual, alignment, size); +} + +/// Convenience wrapper that defers to the system allocator if allocator is null +static inline void +zix_aligned_free(ZixAllocator* const ZIX_NULLABLE allocator, + void* const ZIX_NULLABLE ptr) +{ + ZixAllocator* const actual = allocator ? allocator : zix_default_allocator(); + + actual->aligned_free(actual, ptr); +} + +/** + @} + @} +*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ZIX_ALLOCATOR_H */ -- cgit v1.2.1