diff options
Diffstat (limited to 'test/failing_allocator.c')
-rw-r--r-- | test/failing_allocator.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/test/failing_allocator.c b/test/failing_allocator.c new file mode 100644 index 00000000..89c19bad --- /dev/null +++ b/test/failing_allocator.c @@ -0,0 +1,104 @@ +// Copyright 2021 David Robillard <d@drobilla.net> +// SPDX-License-Identifier: ISC + +#include "failing_allocator.h" + +#include "zix/attributes.h" + +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +static bool +attempt(SerdFailingAllocator* const allocator) +{ + ++allocator->n_allocations; + + if (!allocator->n_remaining) { + return false; + } + + --allocator->n_remaining; + return true; +} + +ZIX_MALLOC_FUNC static void* +serd_failing_malloc(SerdAllocator* const allocator, const size_t size) +{ + SerdFailingAllocator* const state = (SerdFailingAllocator*)allocator; + SerdAllocator* const base = serd_default_allocator(); + + return attempt(state) ? base->malloc(base, size) : NULL; +} + +ZIX_MALLOC_FUNC static void* +serd_failing_calloc(SerdAllocator* const allocator, + const size_t nmemb, + const size_t size) +{ + SerdFailingAllocator* const state = (SerdFailingAllocator*)allocator; + SerdAllocator* const base = serd_default_allocator(); + + return attempt(state) ? base->calloc(base, nmemb, size) : NULL; +} + +static void* +serd_failing_realloc(SerdAllocator* const allocator, + void* const ptr, + const size_t size) +{ + SerdFailingAllocator* const state = (SerdFailingAllocator*)allocator; + SerdAllocator* const base = serd_default_allocator(); + + return attempt(state) ? base->realloc(base, ptr, size) : NULL; +} + +static void +serd_failing_free(SerdAllocator* const allocator, void* const ptr) +{ + (void)allocator; + + SerdAllocator* const base = serd_default_allocator(); + + base->free(base, ptr); +} + +ZIX_MALLOC_FUNC static void* +serd_failing_aligned_alloc(SerdAllocator* const allocator, + const size_t alignment, + const size_t size) +{ + SerdFailingAllocator* const state = (SerdFailingAllocator*)allocator; + SerdAllocator* const base = serd_default_allocator(); + + return attempt(state) ? base->aligned_alloc(base, alignment, size) : NULL; +} + +static void +serd_failing_aligned_free(SerdAllocator* const allocator, void* const ptr) +{ + (void)allocator; + + SerdAllocator* const base = serd_default_allocator(); + + base->aligned_free(base, ptr); +} + +ZIX_CONST_FUNC SerdFailingAllocator +serd_failing_allocator(void) +{ + SerdFailingAllocator failing_allocator = { + { + serd_failing_malloc, + serd_failing_calloc, + serd_failing_realloc, + serd_failing_free, + serd_failing_aligned_alloc, + serd_failing_aligned_free, + }, + 0, + SIZE_MAX, + }; + + return failing_allocator; +} |