summaryrefslogtreecommitdiffstats
path: root/lib/mempool.c
diff options
context:
space:
mode:
authorMartin Mares <mj@ucw.cz>1998-05-03 18:43:39 +0200
committerMartin Mares <mj@ucw.cz>1998-05-03 18:43:39 +0200
commit18c8241a91bd9208879666f1a1a13f454e66d75b (patch)
tree8bdc5f3e384b6b9198d5ab834d869c8d1fb261a7 /lib/mempool.c
parenta8b6038225d18155883e330c96b2bc2e44153e1e (diff)
downloadbird-18c8241a91bd9208879666f1a1a13f454e66d75b.tar
bird-18c8241a91bd9208879666f1a1a13f454e66d75b.zip
BIRD library: The story continues.
Complete resource manages and IP address handling.
Diffstat (limited to 'lib/mempool.c')
-rw-r--r--lib/mempool.c133
1 files changed, 133 insertions, 0 deletions
diff --git a/lib/mempool.c b/lib/mempool.c
new file mode 100644
index 0000000..d2f2c09
--- /dev/null
+++ b/lib/mempool.c
@@ -0,0 +1,133 @@
+/*
+ * BIRD Resource Manager -- Memory Pools
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "nest/bird.h"
+#include "lib/resource.h"
+
+struct mp_chunk {
+ struct mp_chunk *next;
+ byte data[0];
+};
+
+struct mempool {
+ resource r;
+ byte *ptr, *end;
+ struct mp_chunk *first, **plast;
+ unsigned chunk_size, threshold, total;
+};
+
+void mp_free(resource *);
+void mp_dump(resource *);
+
+struct resclass mp_class = {
+ "MemPool",
+ sizeof(struct mempool),
+ mp_free,
+ mp_dump
+};
+
+mempool
+*mp_new(pool *p, unsigned blk)
+{
+ mempool *m = ralloc(p, &mp_class);
+ m->ptr = m->end = NULL;
+ m->first = NULL;
+ m->plast = &m->first;
+ m->chunk_size = blk;
+ m->threshold = 3*blk/4;
+ m->total = 0;
+ return m;
+}
+
+void *
+mp_alloc(mempool *m, unsigned size)
+{
+ byte *a = (byte *) ALIGN((unsigned long) m->ptr, CPU_STRUCT_ALIGN);
+ byte *e = a + size;
+
+ if (e <= m->end)
+ {
+ m->ptr = e;
+ return a;
+ }
+ else
+ {
+ struct mp_chunk *c;
+ if (size >= m->threshold)
+ {
+ c = xmalloc(sizeof(struct mp_chunk) + size);
+ m->total += size;
+ }
+ else
+ {
+ c = xmalloc(sizeof(struct mp_chunk) + m->chunk_size);
+ m->ptr = c->data + size;
+ m->end = c->data + m->chunk_size;
+ m->total += m->chunk_size;
+ }
+ *m->plast = c;
+ m->plast = &c->next;
+ c->next = NULL;
+ return c->data;
+ }
+}
+
+void *
+mp_allocu(mempool *m, unsigned size)
+{
+ byte *a = m->ptr;
+ byte *e = a + size;
+
+ if (e <= m->end)
+ {
+ m->ptr = e;
+ return a;
+ }
+ return mp_alloc(m, size);
+}
+
+void *
+mp_allocz(mempool *m, unsigned size)
+{
+ void *z = mp_alloc(m, size);
+
+ bzero(z, size);
+ return z;
+}
+
+void
+mp_free(resource *r)
+{
+ mempool *m = (mempool *) r;
+ struct mp_chunk *c, *d;
+
+ for(d=m->first; d; d = c)
+ {
+ c = d->next;
+ xfree(d);
+ }
+}
+
+void
+mp_dump(resource *r)
+{
+ mempool *m = (mempool *) r;
+ struct mp_chunk *c;
+ int cnt;
+
+ for(cnt=0, c=m->first; c; c=c->next, cnt++)
+ ;
+ debug("(chunk=%d threshold=%d count=%d total=%d)\n",
+ m->chunk_size,
+ m->threshold,
+ cnt,
+ m->total);
+}