mempool: simple memory pool
authorMarko Kreen <markokr@gmail.com>
Mon, 21 Dec 2009 10:58:31 +0000 (12:58 +0200)
committerMarko Kreen <markokr@gmail.com>
Mon, 21 Dec 2009 13:15:46 +0000 (15:15 +0200)
Targeted at related variable-sized allocations,
to be freed all together.

Simple variant of gnu's obstack.

usual/mempool.c [new file with mode: 0644]
usual/mempool.h [new file with mode: 0644]

diff --git a/usual/mempool.c b/usual/mempool.c
new file mode 100644 (file)
index 0000000..27e2f5c
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Simple memory pool for variable-length allocations.
+ *
+ * Copyright (c) 2009 Marko Kreen
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <usual/mempool.h>
+
+/*
+ * Allows allocation of several variable-sized objects,
+ * freeing them all together.
+ *
+ * ToDo: make it more 'obstack'-like (???)
+ * - free_last
+ * - resize_last
+ * - append
+ */
+
+struct MemPool {
+       struct MemPool *prev;
+       unsigned size;
+       unsigned used;
+};
+
+void *mempool_alloc(struct MemPool **pool, unsigned size)
+{
+       struct MemPool *cur = *pool;
+       void *ptr;
+       unsigned nsize;
+
+       size = (size + sizeof(long) - 1) & ~(sizeof(long) - 1);
+       if (cur && cur->used + size <= cur->size) {
+               ptr = (char *)(cur + 1) + cur->used;
+               cur->used += size;
+               return ptr;
+       } else {
+               nsize = cur ? (2 * cur->size) : 512;
+               while (nsize < size)
+                       nsize *= 2;
+               cur = calloc(1, sizeof(*cur) + nsize);
+               if (cur == NULL)
+                       return NULL;
+               cur->used = size;
+               cur->size = nsize;
+               cur->prev = *pool;
+               *pool = cur;
+               return (char *)(cur + 1);
+       }
+}
+
+void mempool_destroy(struct MemPool **pool)
+{
+       struct MemPool *cur;
+       while ((cur = *pool) != NULL) {
+               *pool = cur->prev;
+               free(cur);
+       }
+}
+
diff --git a/usual/mempool.h b/usual/mempool.h
new file mode 100644 (file)
index 0000000..183e4ef
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Simple memory pool for variable-length allocations.
+ *
+ * Copyright (c) 2009 Marko Kreen
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _USUAL_MEMPOOL_H_
+#define _USUAL_MEMPOOL_H_
+
+#include <usual/base.h>
+
+struct MemPool;
+
+void *mempool_alloc(struct MemPool **pool, unsigned size) _MALLOC;
+void mempool_destroy(struct MemPool **pool);
+
+#endif
+