From ef909b9ab354c1252a15e2ee268fbe00d8378e58 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sun, 8 Jun 2003 12:31:21 +0000 Subject: [PATCH] Added pools. --- lib/Makefile | 2 +- lib/pools.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/pools.h | 63 +++++++++++++++++++++++++++++ 3 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 lib/pools.c create mode 100644 lib/pools.h diff --git a/lib/Makefile b/lib/Makefile index 1bf3eb8..bbac101 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,7 +1,7 @@ DIRS+=lib LIBSH=obj/lib/libsh.a -LIBSH_MODS=alloc assert prime +LIBSH_MODS=alloc assert prime pools LIBSH_MOD_PATHS=$(addprefix obj/lib/,$(LIBSH_MODS)) $(LIBSH): $(addsuffix .o,$(LIBSH_MOD_PATHS)) diff --git a/lib/pools.c b/lib/pools.c new file mode 100644 index 0000000..8b7c372 --- /dev/null +++ b/lib/pools.c @@ -0,0 +1,111 @@ +/* + * Sherlock Library -- Memory Pools (One-Time Allocation) + * + * (c) 1997--2001 Martin Mares + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. + */ + +#include "lib/lib.h" +#include "lib/pools.h" + +#include +#include + +struct memchunk { + struct memchunk *next; + byte data[0]; +}; + +struct mempool * +mp_new(uns size) +{ + struct mempool *p = xmalloc(sizeof(struct mempool)); + + size -= sizeof(struct memchunk); + p->free = p->last = NULL; + p->first = p->current = p->first_large = NULL; + p->plast = &p->first; + p->chunk_size = size; + p->threshold = size / 3; + return p; +} + +void +mp_delete(struct mempool *p) +{ + struct memchunk *c, *d; + + for(d=p->first; d; d = c) + { + c = d->next; + xfree(d); + } + for(d=p->first_large; d; d = c) + { + c = d->next; + xfree(d); + } + xfree(p); +} + +void +mp_flush(struct mempool *p) +{ + struct memchunk *c; + + p->free = p->last = NULL; + p->current = p->first; + while (c = p->first_large) + { + p->first_large = c->next; + xfree(c); + } +} + +void * +mp_alloc(struct mempool *p, uns s) +{ + if (s <= p->threshold) + { + byte *x = (byte *)(((uns) p->free + POOL_ALIGN - 1) & ~(POOL_ALIGN - 1)); + if (x + s > p->last) + { + struct memchunk *c; + + if (p->current) + { + /* Still have free chunks from previous incarnation */ + c = p->current; + p->current = c->next; + } + else + { + c = xmalloc(sizeof(struct memchunk) + p->chunk_size); + *p->plast = c; + p->plast = &c->next; + c->next = NULL; + } + x = c->data; + p->last = x + p->chunk_size; + } + p->free = x + s; + return x; + } + else + { + struct memchunk *c = xmalloc(sizeof(struct memchunk) + s); + c->next = p->first_large; + p->first_large = c; + return c->data; + } +} + +void * +mp_alloc_zero(struct mempool *p, uns s) +{ + void *x = mp_alloc(p, s); + bzero(x, s); + return x; +} diff --git a/lib/pools.h b/lib/pools.h new file mode 100644 index 0000000..a055ef2 --- /dev/null +++ b/lib/pools.h @@ -0,0 +1,63 @@ +/* + * Sherlock Library -- Memory Pools + * + * (c) 1997--2003 Martin Mares + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. + */ + +#ifndef _SHERLOCK_POOLS_H +#define _SHERLOCK_POOLS_H + +#ifndef POOL_ALIGN +#define POOL_ALIGN CPU_STRUCT_ALIGN +#endif + +struct mempool { + byte *free, *last; + struct memchunk *first, *current, **plast; + struct memchunk *first_large; + uns chunk_size, threshold; +}; + +struct mempool *mp_new(uns); +void mp_delete(struct mempool *); +void mp_flush(struct mempool *); +void *mp_alloc(struct mempool *, uns); +void *mp_alloc_zero(struct mempool *, uns); + +static inline void *mp_alloc_fast(struct mempool *p, uns l) +{ + byte *f = (void *) (((uns) p->free + POOL_ALIGN - 1) & ~(POOL_ALIGN - 1)); + byte *ee = f + l; + if (ee > p->last) + return mp_alloc(p, l); + p->free = ee; + return f; +} + +static inline void *mp_alloc_fast_noalign(struct mempool *p, uns l) +{ + byte *f = p->free; + byte *ee = f + l; + if (ee > p->last) + return mp_alloc(p, l); + p->free = ee; + return f; +} + +static inline void * +mp_start_string(struct mempool *p, uns l) +{ + ASSERT(l <= p->chunk_size); + return mp_alloc(p, l); +} + +static inline void +mp_end_string(struct mempool *p, void *stop) +{ + p->free = stop; +} + +#endif -- 2.39.2