summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2023-03-24 22:51:12 +0100
committerMitya Selivanov <automainint@guattari.tech>2023-03-24 22:51:12 +0100
commitb6179af210b0ed92224506dce0978c20d8d6fba7 (patch)
tree8368f703914c83490be519099a03c1274f1034be /source
parente071aa5408ca617172923214aaf61b4cd3733483 (diff)
downloadkit-b6179af210b0ed92224506dce0978c20d8d6fba7.zip
Custom alloc dispatch mode
Diffstat (limited to 'source')
-rw-r--r--source/kit/allocator.c48
-rw-r--r--source/kit/allocator.h22
-rw-r--r--source/kit/dynamic_array.c13
-rw-r--r--source/kit/dynamic_array.h10
-rw-r--r--source/kit/input_buffer.c8
-rw-r--r--source/kit/input_stream.c7
-rw-r--r--source/kit/thread.posix.c9
7 files changed, 79 insertions, 38 deletions
diff --git a/source/kit/allocator.c b/source/kit/allocator.c
index 4a31d2f..b07cca8 100644
--- a/source/kit/allocator.c
+++ b/source/kit/allocator.c
@@ -1,26 +1,54 @@
#include "allocator.h"
+#include <assert.h>
+
#ifndef KIT_DISABLE_SYSTEM_MALLOC
# include <stdlib.h>
#endif
-static void *allocate(void *_, size_t size) {
+static void *allocate(int request, void *state, ptrdiff_t size,
+ ptrdiff_t previous_size, void *pointer) {
#ifndef KIT_DISABLE_SYSTEM_MALLOC
- return malloc(size);
+ switch (request) {
+ case KIT_ALLOCATE:
+ assert(previous_size == 0);
+ assert(pointer == NULL);
+ return malloc(size);
+
+ case KIT_DEALLOCATE:
+ assert(size == 0);
+ assert(pointer != NULL);
+ free(pointer);
+ return NULL;
+
+ case KIT_REALLOCATE:
+ /* FIXME
+ * Not implemented.
+ */
+ assert(0);
+ return NULL;
+
+ default: assert(0);
+ }
#else
- return NULL;
+ assert(0);
#endif
+ return NULL;
}
-static void deallocate(void *_, void *pointer) {
-#ifndef KIT_DISABLE_SYSTEM_MALLOC
- free(pointer);
-#endif
+#ifndef KIT_ENABLE_CUSTOM_ALLOC_DISPATCH
+void *kit_alloc_dispatch(kit_allocator_t alloc, int request,
+ ptrdiff_t size, ptrdiff_t previous_size,
+ void *pointer) {
+ assert(alloc.allocate != NULL);
+ if (alloc.allocate == NULL)
+ return NULL;
+ return alloc.allocate(request, alloc.state, size, previous_size,
+ pointer);
}
+#endif
kit_allocator_t kit_alloc_default(void) {
- kit_allocator_t alloc = { .state = NULL,
- .allocate = allocate,
- .deallocate = deallocate };
+ kit_allocator_t alloc = { .state = NULL, .allocate = allocate };
return alloc;
}
diff --git a/source/kit/allocator.h b/source/kit/allocator.h
index 73eaa38..7126901 100644
--- a/source/kit/allocator.h
+++ b/source/kit/allocator.h
@@ -7,15 +7,27 @@
extern "C" {
#endif
-typedef void *(*kit_allocate_fn)(void *state, size_t size);
-typedef void (*kit_deallocate_fn)(void *state, void *pointer);
+enum { KIT_ALLOCATE, KIT_DEALLOCATE, KIT_REALLOCATE };
+
+typedef void *(*kit_allocate_fn)(int request, void *state,
+ ptrdiff_t size,
+ ptrdiff_t previous_size,
+ void *pointer);
typedef struct {
- void *state;
- kit_allocate_fn allocate;
- kit_deallocate_fn deallocate;
+ void *state;
+ kit_allocate_fn allocate;
} kit_allocator_t;
+/* Application should implement this function if custom allocator
+ * dispatch is enabled.
+ *
+ * See KIT_ENABLE_CUSTOM_ALLOC_DISPATCH
+ */
+void *kit_alloc_dispatch(kit_allocator_t alloc, int request,
+ ptrdiff_t size, ptrdiff_t previous_size,
+ void *pointer);
+
kit_allocator_t kit_alloc_default(void);
#ifdef __cplusplus
diff --git a/source/kit/dynamic_array.c b/source/kit/dynamic_array.c
index 1829c45..d3eaf29 100644
--- a/source/kit/dynamic_array.c
+++ b/source/kit/dynamic_array.c
@@ -9,12 +9,12 @@ void kit_da_init(kit_da_void_t *array, ptrdiff_t element_size,
assert(element_size > 0);
assert(size >= 0);
assert(alloc.allocate != NULL);
- assert(alloc.deallocate != NULL);
memset(array, 0, sizeof(kit_da_void_t));
if (size > 0)
- array->values = alloc.allocate(alloc.state, element_size * size);
+ array->values = kit_alloc_dispatch(alloc, KIT_ALLOCATE,
+ element_size * size, 0, NULL);
if (array->values != NULL) {
array->capacity = size;
@@ -45,15 +45,16 @@ void kit_da_resize(kit_da_void_t *array, ptrdiff_t element_size,
ptrdiff_t capacity = eval_capacity(array->capacity, size);
assert(array->alloc.allocate != NULL);
- assert(array->alloc.deallocate != NULL);
- void *bytes = array->alloc.allocate(array->alloc.state,
- element_size * capacity);
+ void *bytes = kit_alloc_dispatch(
+ array->alloc, KIT_ALLOCATE, element_size * capacity, 0, NULL);
+
if (bytes != NULL) {
if (array->size > 0)
memcpy(bytes, array->values, element_size * array->size);
if (array->values != NULL)
- array->alloc.deallocate(array->alloc.state, array->values);
+ kit_alloc_dispatch(array->alloc, KIT_DEALLOCATE, 0, 0,
+ array->values);
array->capacity = capacity;
array->size = size;
array->values = bytes;
diff --git a/source/kit/dynamic_array.h b/source/kit/dynamic_array.h
index b571c75..35dddb3 100644
--- a/source/kit/dynamic_array.h
+++ b/source/kit/dynamic_array.h
@@ -44,11 +44,11 @@ void kit_da_resize(kit_da_void_t *array, ptrdiff_t element_size,
/* Destroy dynamic array.
*/
-#define KIT_DA_DESTROY(array_) \
- do { \
- if ((array_).values != NULL) \
- (array_).alloc.deallocate((array_).alloc.state, \
- (array_).values); \
+#define KIT_DA_DESTROY(array_) \
+ do { \
+ if ((array_).values != NULL) \
+ kit_alloc_dispatch((array_).alloc, KIT_DEALLOCATE, 0, 0, \
+ (array_).values); \
} while (0)
/* Resize dynamic array.
diff --git a/source/kit/input_buffer.c b/source/kit/input_buffer.c
index 8ac7755..1ea9e94 100644
--- a/source/kit/input_buffer.c
+++ b/source/kit/input_buffer.c
@@ -13,8 +13,8 @@ typedef struct {
static internal_buffer_t *buf_init(kit_is_handle_t upstream,
kit_allocator_t alloc) {
assert(alloc.allocate != NULL);
- internal_buffer_t *const buf = alloc.allocate(alloc.state,
- sizeof *buf);
+ internal_buffer_t *const buf = kit_alloc_dispatch(
+ alloc, KIT_ALLOCATE, sizeof *buf, 0, NULL);
if (buf != NULL) {
memset(buf, 0, sizeof *buf);
@@ -46,9 +46,7 @@ static void buf_release(void *p) {
if (--buf->ref_count == 0) {
DA_DESTROY(buf->data);
-
- assert(buf->alloc.deallocate != NULL);
- buf->alloc.deallocate(buf->alloc.state, buf);
+ kit_alloc_dispatch(buf->alloc, KIT_DEALLOCATE, 0, 0, buf);
}
}
diff --git a/source/kit/input_stream.c b/source/kit/input_stream.c
index 89be44c..df31c1d 100644
--- a/source/kit/input_stream.c
+++ b/source/kit/input_stream.c
@@ -41,8 +41,9 @@ kit_is_handle_t kit_is_wrap_string(kit_str_t string,
kit_allocator_t alloc) {
kit_is_handle_t in;
memset(&in, 0, sizeof in);
- kit_is_state_str_t *state = (kit_is_state_str_t *) alloc.allocate(
- alloc.state, sizeof(kit_is_state_str_t));
+ kit_is_state_str_t *state = (kit_is_state_str_t *)
+ kit_alloc_dispatch(alloc, KIT_ALLOCATE,
+ sizeof(kit_is_state_str_t), 0, NULL);
if (state != NULL) {
memset(state, 0, sizeof *state);
state->type = input_stream_str;
@@ -57,5 +58,5 @@ kit_is_handle_t kit_is_wrap_string(kit_str_t string,
void kit_is_destroy(kit_is_handle_t in) {
kit_is_state_basic_t *basic = (kit_is_state_basic_t *) in.state;
if (basic != NULL)
- basic->alloc.deallocate(basic->alloc.state, in.state);
+ kit_alloc_dispatch(basic->alloc, KIT_DEALLOCATE, 0, 0, in.state);
}
diff --git a/source/kit/thread.posix.c b/source/kit/thread.posix.c
index 192dca4..ee5d439 100644
--- a/source/kit/thread.posix.c
+++ b/source/kit/thread.posix.c
@@ -44,7 +44,7 @@ typedef struct {
static void *impl_thrd_routine(void *p) {
impl_thrd_param_t pack = *((impl_thrd_param_t *) p);
- pack.alloc.deallocate(pack.alloc.state, p);
+ kit_alloc_dispatch(pack.alloc, KIT_DEALLOCATE, 0, 0, p);
return (void *) (intptr_t) pack.func(pack.arg);
}
@@ -214,8 +214,9 @@ int thrd_create_with_stack(thrd_t *thr, thrd_start_t func, void *arg,
attr_p = &attr;
}
kit_allocator_t alloc = kit_alloc_default();
- pack = (impl_thrd_param_t *) alloc.allocate(
- alloc.state, sizeof(impl_thrd_param_t));
+
+ pack = (impl_thrd_param_t *) kit_alloc_dispatch(
+ alloc, KIT_ALLOCATE, sizeof(impl_thrd_param_t), 0, NULL);
if (!pack) {
if (attr_p)
pthread_attr_destroy(attr_p);
@@ -225,7 +226,7 @@ int thrd_create_with_stack(thrd_t *thr, thrd_start_t func, void *arg,
pack->arg = arg;
pack->alloc = alloc;
if (pthread_create(thr, attr_p, impl_thrd_routine, pack) != 0) {
- alloc.deallocate(alloc.state, pack);
+ kit_alloc_dispatch(alloc, KIT_DEALLOCATE, 0, 0, pack);
if (attr_p)
pthread_attr_destroy(attr_p);
return thrd_error;