commit 32aac6a034f347c9adcba320bf998212779855bd
parent d5facb4fb6bace7e23ce97831adcecdd19aa0ad6
Author: Louis Burda <quent.burda@gmail.com>
Date: Fri, 17 Mar 2023 21:03:32 +0100
Use liballoc for allocations
Diffstat:
6 files changed, 61 insertions(+), 35 deletions(-)
diff --git a/.gitmodules b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "lib/liballoc"]
+ path = lib/liballoc
+ url = git@sinitax.com:snx/liballoc
diff --git a/Makefile b/Makefile
@@ -2,7 +2,8 @@ PREFIX ?= /usr/local
LIBDIR ?= /lib
INCLDIR ?= /include
-CFLAGS = -I include -Wno-prototype -Wunused-function -Wunused-variable
+CFLAGS = -I include -I lib/liballoc/include
+CFLAGS += -Wno-prototype -Wunused-function -Wunused-variable
ifeq "$(DEBUG)" "1"
CFLAGS += -g -DLIBDVEC_CHECK_ENABLE=1
@@ -16,6 +17,9 @@ clean:
build:
mkdir build
+lib/liballoc/build/liballoc.a:
+ make -C lib/liballoc build/liballoc.a
+
build/libdvec.a: src/dvec.c include/dvec.h libdvec.api | build
$(CC) -o build/tmp.o src/dvec.c $(CFLAGS) -r
objcopy --keep-global-symbols=libdvec.api build/tmp.o build/fixed.o
@@ -25,7 +29,7 @@ build/libdvec.so: src/dvec.c include/dvec.h libdvec.lds | build
$(CC) -o $@ src/dvec.c -fPIC $(CFLAGS) \
-shared -Wl,-version-script libdvec.lds
-build/test: src/test.c build/libdvec.a
+build/test: src/test.c build/libdvec.a lib/liballoc/build/liballoc.a
$(CC) -o $@ $^ $(CFLAGS)
install:
diff --git a/include/dvec.h b/include/dvec.h
@@ -1,5 +1,7 @@
#pragma once
+#include "allocator.h"
+
#include <stdbool.h>
#include <stdlib.h>
@@ -8,13 +10,17 @@ struct dvec {
size_t len, cap;
void *data;
+
+ const struct allocator *allocator;
};
-int dvec_init(struct dvec *dvec, size_t dsize, size_t cap);
-void dvec_deinit(struct dvec *dvec);
+int dvec_init(struct dvec *dvec, size_t dsize, size_t cap,
+ const struct allocator *allocator);
+int dvec_deinit(struct dvec *dvec);
-int dvec_alloc(struct dvec **dvec, size_t dsize, size_t cap);
-void dvec_free(struct dvec *dvec);
+int dvec_alloc(struct dvec **dvec, size_t dsize, size_t cap,
+ const struct allocator *allocator);
+int dvec_free(struct dvec *dvec);
int dvec_copy(struct dvec *dst, struct dvec *src);
void dvec_swap(struct dvec *dst, struct dvec *src);
diff --git a/lib/liballoc b/lib/liballoc
@@ -0,0 +1 @@
+Subproject commit 22d274eb7a43de119af51cf46a892aa6be6a7d91
diff --git a/src/dvec.c b/src/dvec.c
@@ -1,6 +1,5 @@
#include "dvec.h"
-#include <errno.h>
#include <string.h>
#include <stdlib.h>
@@ -24,57 +23,69 @@ libdvec_assert(int cond, const char *file, int line, const char *condstr)
#endif
int
-dvec_init(struct dvec *dvec, size_t dsize, size_t cap)
+dvec_init(struct dvec *dvec, size_t dsize, size_t cap,
+ const struct allocator *allocator)
{
- LIBDVEC_CHECK(dvec != NULL && dsize > 0 && cap >= 0);
+ int rc;
+
+ LIBDVEC_CHECK(dvec != NULL && dsize > 0
+ && cap >= 0 && allocator != NULL);
+ dvec->allocator = allocator;
dvec->dsize = dsize;
dvec->cap = cap;
-
dvec->len = 0;
dvec->data = NULL;
if (dvec->cap) {
- dvec->data = calloc(cap, dsize);
- if (!dvec->data) return -errno;
+ rc = allocator->alloc(&dvec->data, cap * dsize);
+ if (rc) return -rc;
}
return 0;
}
-void
+int
dvec_deinit(struct dvec *dvec)
{
LIBDVEC_CHECK(dvec != NULL);
- free(dvec->data);
+ return dvec->allocator->free(dvec->data);
}
int
-dvec_alloc(struct dvec **dvec, size_t dsize, size_t cap)
+dvec_alloc(struct dvec **dvec, size_t dsize, size_t cap,
+ const struct allocator *allocator)
{
int rc;
LIBDVEC_CHECK(dvec != NULL && dsize > 0 && cap > 0);
- *dvec = malloc(sizeof(struct dvec));
- if (!*dvec) return -errno;
+ rc = allocator->alloc((void **)dvec, sizeof(struct dvec));
+ if (!*dvec) return -rc;
- rc = dvec_init(*dvec, dsize, cap);
- if (rc) {
- free(dvec);
- return rc;
- }
+ rc = dvec_init(*dvec, dsize, cap, allocator);
+ if (rc) return rc;
return 0;
}
-void
+int
dvec_free(struct dvec *dvec)
{
+ const struct allocator *allocator;
+ int rc;
+
LIBDVEC_CHECK(dvec != NULL);
- dvec_deinit(dvec);
- free(dvec);
+ allocator = dvec->allocator;
+
+ rc = dvec_deinit(dvec);
+ if (rc) return rc;
+
+ rc = allocator->free(dvec);
+ if (rc) return -rc;
+
+ return 0;
}
int
@@ -82,10 +93,10 @@ dvec_copy(struct dvec *dst, struct dvec *src)
{
int rc;
+ dst->dsize = src->dsize;
rc = dvec_reserve(dst, src->len);
if (rc) return rc;
- dst->dsize = src->dsize;
dst->len = src->len;
memcpy(dst->data, src->data, src->len * src->dsize);
@@ -113,15 +124,15 @@ dvec_clear(struct dvec *dvec)
int
dvec_reserve(struct dvec *dvec, size_t len)
{
- void *alloc;
+ int rc;
if (len <= dvec->cap) return 0;
dvec->cap *= 2;
if (len > dvec->cap) dvec->cap = len;
- alloc = realloc(dvec->data, dvec->cap * dvec->dsize);
- if (!alloc) return -errno;
- dvec->data = alloc;
+
+ rc = dvec->allocator->realloc(&dvec->data, dvec->cap * dvec->dsize);
+ if (rc) return rc;
return 0;
}
@@ -129,7 +140,7 @@ dvec_reserve(struct dvec *dvec, size_t len)
int
dvec_shrink(struct dvec *dvec)
{
- void *alloc;
+ int rc;
LIBDVEC_CHECK(dvec != NULL);
@@ -140,9 +151,9 @@ dvec_shrink(struct dvec *dvec)
}
dvec->cap = dvec->len;
- alloc = realloc(dvec->data, dvec->cap * dvec->dsize);
- if (!alloc) return -errno;
- dvec->data = alloc;
+
+ rc = dvec->allocator->realloc(&dvec->data, dvec->cap * dvec->dsize);
+ if (rc) return -rc;
return 0;
}
diff --git a/src/test.c b/src/test.c
@@ -1,3 +1,4 @@
+#include "allocator.h"
#include "dvec.h"
#include <err.h>
@@ -14,7 +15,7 @@ main(int argc, const char **argv)
int i, rc;
int *val;
- rc = dvec_init(&dvec, sizeof(int), 10);
+ rc = dvec_init(&dvec, sizeof(int), 10, &stdlib_heap_allocator);
if (rc) LIBDVEC_ERR(rc);
for (i = 1; i < argc; i++) {