From cc6f7b00bf358fa9f6203f714e0466b436d7e028 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Tue, 28 Jan 2014 17:31:28 +0100 Subject: [PATCH] Gary: Added growing arrays over mempools --- ucw/Makefile | 4 +-- ucw/gary-mp.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++ ucw/gary.h | 5 ++++ ucw/gary.t | 10 +++++++ 4 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 ucw/gary-mp.c diff --git a/ucw/Makefile b/ucw/Makefile index 4ac61ccc..faef00e9 100644 --- a/ucw/Makefile +++ b/ucw/Makefile @@ -30,7 +30,7 @@ LIBUCW_MODS= \ base64 base224 \ io-careful io-sync io-mmap io-size \ string str-esc str-split str-match str-imatch str-hex str-fix \ - bbuf gary \ + bbuf gary gary-mp \ getopt \ strtonum \ resource trans res-fd res-mem res-subpool res-mempool res-eltpool \ @@ -165,7 +165,7 @@ $(o)/ucw/strtonum-test.test: $(o)/ucw/strtonum-test $(addprefix $(o)/ucw/fb-,file.test grow.test pool.test socket.test atomic.test \ limfd.test temp.test mem.test buffer.test mmap.test multi.test): %.test: %-t $(o)/ucw/url.test: $(o)/ucw/url-t -$(o)/ucw/gary.test: $(o)/ucw/gary-t +$(o)/ucw/gary.test: $(o)/ucw/gary-t $(o)/ucw/gary-mp-t $(o)/ucw/time.test: $(o)/ucw/time-conf-t $(o)/ucw/crc.test: $(o)/ucw/crc-t $(o)/ucw/signames.test: $(o)/ucw/signames-t diff --git a/ucw/gary-mp.c b/ucw/gary-mp.c new file mode 100644 index 00000000..77e30aab --- /dev/null +++ b/ucw/gary-mp.c @@ -0,0 +1,77 @@ +/* + * UCW Library -- Growing arrays over mempools + * + * (c) 2014 Martin Mares + */ + +#include +#include +#include + +#include + +static void *gary_mp_alloc(struct gary_allocator *a, size_t size) +{ + return mp_alloc(a->data, size); +} + +static void *gary_mp_realloc(struct gary_allocator *a, void *ptr, size_t old_size, size_t new_size) +{ + if (new_size <= old_size) + return ptr; + + /* + * In the future, we might want to do something like mp_realloc(), + * but we have to check that it is indeed the last block in the pool. + */ + void *new = mp_alloc(a->data, new_size); + memcpy(new, ptr, old_size); + return new; +} + +static void gary_mp_free(struct gary_allocator *a UNUSED, void *ptr UNUSED) +{ +} + +struct gary_allocator *gary_new_allocator_mp(struct mempool *mp) +{ + struct gary_allocator *a = mp_alloc(mp, sizeof(*a)); + *a = (struct gary_allocator) { + .alloc = gary_mp_alloc, + .realloc = gary_mp_realloc, + .free = gary_mp_free, + .data = mp, + }; + return a; +} + +#ifdef TEST + +#include + +int main(void) +{ + struct mempool *mp = mp_new(4096); + struct gary_allocator *alloc = gary_new_allocator_mp(mp); + int *a; + GARY_INIT_ALLOC(a, 5, alloc); + + for (int i=0; i<5; i++) + a[i] = i+1; + + GARY_PUSH(a); + *GARY_PUSH(a) = 10; + *GARY_PUSH(a) = 20; + *GARY_PUSH(a) = 30; + GARY_POP(a); + GARY_FIX(a); + + for (int i=0; i<(int)GARY_SIZE(a); i++) + printf("%d\n", a[i]); + + GARY_FREE(a); + mp_delete(mp); + return 0; +} + +#endif diff --git a/ucw/gary.h b/ucw/gary.h index 53e2e6c4..1c5a647a 100644 --- a/ucw/gary.h +++ b/ucw/gary.h @@ -77,4 +77,9 @@ static inline void gary_free(void *ptr) } } +/* gary-mp.c */ + +struct mempool; +struct gary_allocator *gary_new_allocator_mp(struct mempool *mp); + #endif diff --git a/ucw/gary.t b/ucw/gary.t index 0ae5f866..3df10f52 100644 --- a/ucw/gary.t +++ b/ucw/gary.t @@ -9,3 +9,13 @@ Out: 1 0 10 20 + +Run: ../obj/ucw/gary-mp-t +Out: 1 + 2 + 3 + 4 + 5 + 0 + 10 + 20 -- 2.39.2