]> mj.ucw.cz Git - libucw.git/commitdiff
Gary: Added growing arrays over mempools
authorMartin Mares <mj@ucw.cz>
Tue, 28 Jan 2014 16:31:28 +0000 (17:31 +0100)
committerMartin Mares <mj@ucw.cz>
Tue, 28 Jan 2014 16:31:28 +0000 (17:31 +0100)
ucw/Makefile
ucw/gary-mp.c [new file with mode: 0644]
ucw/gary.h
ucw/gary.t

index 4ac61cccd6858142cb2840f85544ab5c637ee34e..faef00e9cd40627a48de26867bf75492916403c2 100644 (file)
@@ -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 (file)
index 0000000..77e30aa
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ *     UCW Library -- Growing arrays over mempools
+ *
+ *     (c) 2014 Martin Mares <mj@ucw.cz>
+ */
+
+#include <ucw/lib.h>
+#include <ucw/gary.h>
+#include <ucw/mempool.h>
+
+#include <string.h>
+
+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 <stdio.h>
+
+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
index 53e2e6c4b471313dd74554db61e347ee7c0c3729..1c5a647a0bf1bea36eff92bbf3047d7c637d01de 100644 (file)
@@ -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
index 0ae5f8664fdee632cab8a0f1545dea53eca6ec75..3df10f52a1075cf2c7117c8a4b5cd319193f864b 100644 (file)
@@ -9,3 +9,13 @@ Out:   1
        0
        10
        20
+
+Run:   ../obj/ucw/gary-mp-t
+Out:   1
+       2
+       3
+       4
+       5
+       0
+       10
+       20