summaryrefslogtreecommitdiff
path: root/src/base/allocator.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/allocator.c')
-rw-r--r--src/base/allocator.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/base/allocator.c b/src/base/allocator.c
new file mode 100644
index 0000000..3a5c515
--- /dev/null
+++ b/src/base/allocator.c
@@ -0,0 +1,107 @@
+#define TINY_ALLOCATOR_IMPLEMENTATION
+#include "base/allocator.h"
+
+#include <stdint.h>
+#include <stdlib.h>
+
+static size_t fail_index = SIZE_MAX;
+static size_t calls;
+static size_t outstanding;
+
+static int
+should_fail(void)
+{
+ return calls++ == fail_index;
+}
+
+void *
+tiny_alloc(size_t size)
+{
+ void *result;
+ if (should_fail())
+ {
+ return NULL;
+ }
+ result = malloc(size);
+ if (result != NULL)
+ {
+ outstanding++;
+ }
+ return result;
+}
+
+void *
+tiny_calloc(size_t count, size_t size)
+{
+ void *result;
+ if ((size != 0 && count > SIZE_MAX / size) || should_fail())
+ {
+ return NULL;
+ }
+ result = calloc(count, size);
+ if (result != NULL)
+ {
+ outstanding++;
+ }
+ return result;
+}
+
+void *
+tiny_realloc(void *memory, size_t size)
+{
+ void *result;
+ if (size == 0)
+ {
+ tiny_free(memory);
+ return NULL;
+ }
+ if (should_fail())
+ {
+ return NULL;
+ }
+ result = realloc(memory, size);
+ if (result != NULL && memory == NULL)
+ {
+ outstanding++;
+ }
+ return result;
+}
+
+void
+tiny_free(void *memory)
+{
+ if (memory != NULL)
+ {
+ free(memory);
+ if (outstanding > 0)
+ {
+ outstanding--;
+ }
+ }
+}
+
+void
+tiny_allocator_reset(void)
+{
+ fail_index = SIZE_MAX;
+ calls = 0;
+}
+
+void
+tiny_allocator_fail_after(size_t allocation_index)
+{
+ fail_index = allocation_index;
+ calls = 0;
+}
+
+size_t
+tiny_allocator_call_count(void)
+{
+ return calls;
+}
+
+size_t
+tiny_allocator_outstanding(void)
+{
+ return outstanding;
+}