]> mj.ucw.cz Git - libucw.git/commitdiff
Added a new mempool primitive mp_spread().
authorMartin Mares <mj@ucw.cz>
Thu, 29 Mar 2007 08:48:06 +0000 (10:48 +0200)
committerMartin Mares <mj@ucw.cz>
Thu, 29 Mar 2007 08:48:06 +0000 (10:48 +0200)
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
lib/mempool.h

index 7201c44ca000bbf66c7e3d082f6cdb903a189c21..658f53845a99b73605d1fc6a3475318e82793056 100644 (file)
@@ -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)
 {
index c95b8ade2b5affc174e088acd50a03efd1f63c1c..4575d8718d42d40f3b15c339b6f1e84a0cff9e7f 100644 (file)
@@ -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 <size> bytes free after <p>, if not, reallocate and adjust <p>. */
+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 <end> 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()). */