From bd4bf4734cf190c494caa3d283f2d9c3377e5dfa Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Thu, 29 Mar 2007 10:48:06 +0200 Subject: [PATCH] Added a new mempool primitive mp_spread(). Gradual construction of strings via the growing mempool interface was still too complicated, so I have introduced a new primitive for this case and also modified mp_end() to return a pointer to the beginning of the just closed block (which gets optimized out if unused). This allows to write: byte *p = mp_start(pool, 1); for (...) { p = mp_spread(pool, p, 2); *p++ = ...; } *p++ = 0; return mp_end(pool); Pavel, if you agree, I will merge this into mainline. --- lib/mempool.c | 8 ++++++++ lib/mempool.h | 15 +++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/lib/mempool.c b/lib/mempool.c index 7201c44c..658f5384 100644 --- a/lib/mempool.c +++ b/lib/mempool.c @@ -294,6 +294,14 @@ mp_realloc_zero(struct mempool *pool, void *ptr, uns size) return ptr; } +void * +mp_spread_internal(struct mempool *pool, void *p, uns size) +{ + void *old = mp_ptr(pool); + void *new = mp_grow_internal(pool, p-old+size); + return p-old+new; +} + void mp_restore(struct mempool *pool, struct mempool_state *state) { diff --git a/lib/mempool.h b/lib/mempool.h index c95b8ade..4575d871 100644 --- a/lib/mempool.h +++ b/lib/mempool.h @@ -104,6 +104,7 @@ mp_alloc_fast_noalign(struct mempool *pool, uns size) /* For internal use only, do not call directly */ void *mp_start_internal(struct mempool *pool, uns size) LIKE_MALLOC; void *mp_grow_internal(struct mempool *pool, uns size); +void *mp_spread_internal(struct mempool *pool, void *p, uns size); static inline uns mp_idx(struct mempool *pool, void *ptr) @@ -186,12 +187,22 @@ mp_expand(struct mempool *pool) return mp_grow_internal(pool, mp_avail(pool) + 1); } +/* Ensure that there is at least bytes free after

, if not, reallocate and adjust

. */ +static inline void * +mp_spread(struct mempool *pool, void *p, uns size) +{ + return (((uns)(pool->state.last[pool->idx] - p) >= size) ? p : mp_spread_internal(pool, p, size)); +} + /* Close the growing buffer. The must point just behind the data, you want to keep - * allocated (so it can be in the interval [mp_ptr(pool), mp_ptr(pool) + mp_avail(pool)]). */ -static inline void + * allocated (so it can be in the interval [mp_ptr(pool), mp_ptr(pool) + mp_avail(pool)]). + * Returns a pointer to the beginning of the just closed block. */ +static inline void * mp_end(struct mempool *pool, void *end) { + void *p = mp_ptr(pool); pool->state.free[pool->idx] = pool->state.last[pool->idx] - end; + return p; } /* Return size in bytes of the last allocated memory block (with mp_alloc*() or mp_end()). */ -- 2.39.2