summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/resource.c37
-rw-r--r--lib/resource.h8
-rw-r--r--lib/xmalloc.c20
3 files changed, 63 insertions, 2 deletions
diff --git a/lib/resource.c b/lib/resource.c
index 9e626815..289af933 100644
--- a/lib/resource.c
+++ b/lib/resource.c
@@ -328,6 +328,42 @@ mb_allocz(pool *p, unsigned size)
}
/**
+ * mb_realloc - reallocate a memory block
+ * @p: pool
+ * @m: memory block
+ * @size: new size of the block
+ *
+ * mb_realloc() changes the size of the memory block @m to a given size.
+ * The contents will be unchanged to the minimum of the old and new sizes;
+ * newly allocated memory will be uninitialized. If @m is NULL, the call
+ * is equivalent to mb_alloc(@p, @size).
+ *
+ * Like mb_alloc(), mb_realloc() also returns a pointer to the memory
+ * chunk , not to the resource, hence you have to free it using
+ * mb_free(), not rfree().
+ */
+void *
+mb_realloc(pool *p, void *m, unsigned size)
+{
+ struct mblock *ob = NULL;
+
+ if (m)
+ {
+ ob = SKIP_BACK(struct mblock, data, m);
+ if (ob->r.n.next)
+ rem_node(&ob->r.n);
+ }
+
+ struct mblock *b = xrealloc(ob, sizeof(struct mblock) + size);
+
+ b->r.class = &mb_class;
+ add_tail(&p->inside, &b->r.n);
+ b->size = size;
+ return b->data;
+}
+
+
+/**
* mb_free - free a memory block
* @m: memory block
*
@@ -339,3 +375,4 @@ mb_free(void *m)
struct mblock *b = SKIP_BACK(struct mblock, data, m);
rfree(b);
}
+
diff --git a/lib/resource.h b/lib/resource.h
index 42ed26ed..8dd441f0 100644
--- a/lib/resource.h
+++ b/lib/resource.h
@@ -47,6 +47,7 @@ extern pool root_pool;
void *mb_alloc(pool *, unsigned size);
void *mb_allocz(pool *, unsigned size);
+void *mb_realloc(pool *p, void *m, unsigned size);
void mb_free(void *);
/* Memory pools with linear allocation */
@@ -75,12 +76,13 @@ void sl_free(slab *, void *);
#ifdef HAVE_LIBDMALLOC
/*
* The standard dmalloc macros tend to produce lots of namespace
- * conflicts and we use only xmalloc and xfree, so we can define
- * the stubs ourselves.
+ * conflicts and we use only xmalloc, xrealloc and xfree, so we
+ * can define the stubs ourselves.
*/
#define DMALLOC_DISABLE
#include <dmalloc.h>
#define xmalloc(size) _xmalloc_leap(__FILE__, __LINE__, size)
+#define xrealloc(size) _xrealloc_leap(__FILE__, __LINE__, size)
#define xfree(ptr) _xfree_leap(__FILE__, __LINE__, ptr)
#else
/*
@@ -89,7 +91,9 @@ void sl_free(slab *, void *);
* the renaming.
*/
#define xmalloc bird_xmalloc
+#define xrealloc bird_xrealloc
void *xmalloc(unsigned);
+void *xrealloc(void *, unsigned);
#define xfree(x) free(x)
#endif
diff --git a/lib/xmalloc.c b/lib/xmalloc.c
index bc386c83..da2f0941 100644
--- a/lib/xmalloc.c
+++ b/lib/xmalloc.c
@@ -32,4 +32,24 @@ xmalloc(unsigned size)
die("Unable to allocate %d bytes of memory", size);
}
+/**
+ * xrealloc - realloc with checking
+ * @ptr: original memory block
+ * @size: block size
+ *
+ * This function is equivalent to realloc() except that in case of
+ * failure it calls die() to quit the program instead of returning
+ * a %NULL pointer.
+ *
+ * Wherever possible, please use the memory resources instead.
+ */
+void *
+xrealloc(void *ptr, unsigned size)
+{
+ void *p = realloc(ptr, size);
+ if (p)
+ return p;
+ die("Unable to allocate %d bytes of memory", size);
+}
+
#endif