From dcd887eb8326ec195149c7fd6711ddb715c4ad1f Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 15 Sep 2021 23:07:06 -0400 Subject: Add a simple bump pointer allocator --- include/zix/bump_allocator.h | 52 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 include/zix/bump_allocator.h (limited to 'include/zix') diff --git a/include/zix/bump_allocator.h b/include/zix/bump_allocator.h new file mode 100644 index 0000000..712ea46 --- /dev/null +++ b/include/zix/bump_allocator.h @@ -0,0 +1,52 @@ +// Copyright 2021 David Robillard +// SPDX-License-Identifier: ISC + +#ifndef ZIX_BUMP_ALLOCATOR_H +#define ZIX_BUMP_ALLOCATOR_H + +#include "zix/allocator.h" +#include "zix/attributes.h" + +#include + +/** + A simple bump-pointer allocator that never frees. + + This is about the simplest possible allocator that is useful in practice. + It uses a user-provided memory buffer with a fixed size, and allocates by + simply "bumping" the top offset like a stack. This approach is simple, + extremely fast, and hard real-time safe, but at the cost of being limited to + narrow use cases since there is (almost) no support for deallocation. + + Using this allocator requires knowing up-front the total amount of memory + that will be allocated (without reuse). Typically this makes sense in short + scopes like a function call. + + This allocator adheres to standard C semantics as much as possible, but is + much more restrictive. Specifically: + + - All allocations are aligned to sizeof(uintmax_t). + + - Both free() and realloc() only work on the most recently allocated + pointer, essentially serving as a cheap pop and pop-push, respectively. + + - Calling free() means that realloc() will fail and free() will do nothing + until the next allocation. In other words, free() can not be used twice + in a row. + + - There is no relocation: realloc() always returns either the input pointer, + or null. +*/ +typedef struct { + ZixAllocator base; ///< Base allocator instance + void* ZIX_NONNULL buffer; ///< User-owned memory buffer + size_t last; ///< Last allocation offset in bytes + size_t top; ///< Stack top/end offset in bytes + size_t capacity; ///< Size of buffer in bytes (the maximum top) +} ZixBumpAllocator; + +ZIX_API +ZixBumpAllocator +zix_bump_allocator(size_t capacity, void* ZIX_NONNULL buffer); + +#endif // ZIX_BUMP_ALLOCATOR_H -- cgit v1.2.1