libdvec-c

C memory vector library
git clone https://git.sinitax.com/sinitax/libdvec-c
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

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:
A.gitmodules | 3+++
MMakefile | 8++++++--
Minclude/dvec.h | 14++++++++++----
Alib/liballoc | 1+
Msrc/dvec.c | 67+++++++++++++++++++++++++++++++++++++++----------------------------
Msrc/test.c | 3++-
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++) {