X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/mLib/blobdiff_plain/18c831dcd0ae4d660c70ccac69d27ed2a97851be..d04c0e00da3a27693bbf9cc4f2d5c88e56d80f20:/mem/alloc.h?ds=inline diff --git a/mem/alloc.h b/mem/alloc.h index 2349181..8a5c364 100644 --- a/mem/alloc.h +++ b/mem/alloc.h @@ -42,18 +42,39 @@ /*----- Functions and macros ----------------------------------------------*/ -/* --- @x_alloc@ --- * +/* --- @x_alloc@, @x_allocv@ --- * * * Arguments: @arena *a@ = pointer to underlying arena - * @size_t sz@ = size of block to allocate + * @size_t n@ = number of elements to allocate (for @x_allocv@) + * @size_t sz@ = size of elements to allocate * * Returns: Pointer to allocated block. * - * Use: Allocates memory. If there's not enough memory, the - * exception @EXC_NOMEM@ is thrown. + * Use: The @x_allocv@ function allocates memory for @n@ elements of + * @sz@ bytes each (or, perhaps, %%\emph{vice versa}). The + * @x_alloc@ function is the same, but with @n@ fixed equal + * to 1. If there's not enough memory, the exception + * @EXC_NOMEM@ is thrown. */ extern void *x_alloc(arena */*a*/, size_t /*sz*/); +extern void *x_allocv(arena */*a*/, size_t /*n*/, size_t /*sz*/); + +/* --- @X_NEW@, @X_NEWV@ --- * + * + * Arguments: @type *p@ = a pointer to allocate + * @arena *a@ = pointer to underlying arena + * @size_t n@ = number of elements + * + * Returns: --- + * + * Use: Set @p@ to point to a freshly allocate block large enough for + * @n@ elements each of the type pointed to by @p@. + */ + +#define X_NEW(p, a) do { (p) = x_alloc((a), sizeof(*(p))); } while (0) +#define X_NEWV(p, a, n) \ + do { (p) = x_allocv((a), (n), sizeof(*(p))); } while (0) /* --- @x_strdup@ --- * * @@ -69,22 +90,51 @@ extern void *x_alloc(arena */*a*/, size_t /*sz*/); extern char *x_strdup(arena */*a*/, const char */*s*/); -/* --- @x_realloc@ --- * +/* --- @x_realloc@, @x_reallocv@ --- * * * Arguments: @arena *a@ = pointer to underlying arena * @void *p@ = pointer to a block of memory - * @size_t sz@ = new size desired for the block - * @size_t osz@ = size of the old block + * @size_t n@ = new number of elements (for @x_reallocv@) + * @size_t on@ = old number of elements (for @x_reallocv@) + * @size_t sz@ = size of elements (for @x_reallocv@) or new + * block size (for @x_realloc@) + * @size_t osz@ = size of the old block (for @x_realloc@) * * Returns: Pointer to the resized memory block (which is almost * certainly not in the same place any more). * * Use: Resizes a memory block. If there's not enough memory, the * exception @EXC_NOMEM@ is thrown. + * + * The @x_reallocv@ function adjusts a block which currently has + * space for @on@ elements each of size @sz@, so that it now has + * enough space for @n@ elements, preserving the initial @min(n, + * on)@ elements. The @x_realloc@ function is the same, but + * with @sz@ fixed equal to 1, and @n@ and @on@ renamed to @sz@ + * and @osz@ for historical reasons. */ extern void *x_realloc(arena */*a*/, void */*p*/, size_t /*sz*/, size_t /*osz*/); +extern void *x_reallocv(arena */*a*/, void */*p*/, + size_t /*n*/, size_t /*on*/, size_t /*sz*/); + +/* --- @X_RENEWV@ --- * + * + * Arguments: @type *p@ = a pointer to allocate + * @arena *a@ = pointer to underlying arena + * @size_t n, on@ = new and existing numbers of elements + * + * Returns: --- + * + * Use: Adjust @p@ to point to a new block of memory with space for + * @n@ elements of the type pointed to by @p@, on the assumption + * that @p@ is either null or currently points to a block with + * space for @on@ elements. + */ + +#define X_RENEWV(p, a, n, on) \ + do { (p) = x_reallocv((a), (p), (n), (on), sizeof(*(p))); } while (0) /* --- @x_free@ --- * * @@ -101,18 +151,36 @@ extern void x_free(arena */*a*/, void */*p*/); /*----- Old functions for the standard arena ------------------------------*/ -/* --- @xmalloc@ --- * +/* --- @xmalloc@, @xmallocv@ --- * * - * Arguments: @size_t sz@ = size of block to allocate + * Arguments: @size_t n@ = number of elements to allocate (for @xmallocv@) + * @size_t sz@ = size of block to allocate * * Returns: Pointer to allocated block. * - * Use: Allocates memory. If there's not enough memory, the - * exception @EXC_NOMEM@ is thrown. + * Use: Allocates memory for @n@ elements each of size @sz@. For + * @xmalloc@, @n@ is fixed equal to 1. If there's not enough + * memory, the exception @EXC_NOMEM@ is thrown. */ extern void *xmalloc(size_t /*sz*/); +extern void *xmallocv(size_t /*n*/, size_t /*sz*/); #define xmalloc(sz) x_alloc(arena_global, (sz)) +#define xmallocv(n, sz) x_allocv(arena_global, (n), (sz)) + +/* --- @XNEW@, @XNEWV@ --- * + * + * Arguments: @type *p@ = a pointer to allocate + * @size_t n@ = number of elements + * + * Returns: --- + * + * Use: Set @p@ to point to a freshly allocate block large enough for + * @n@ elements each of the type pointed to by @p@. + */ + +#define XNEW(p) X_NEW(p, arena_global); +#define XNEWV(p, n) X_NEWV(p, arena_global, n); /* --- @xstrdup@ --- * * @@ -128,21 +196,50 @@ extern void *xmalloc(size_t /*sz*/); extern char *xstrdup(const char */*s*/); #define xstrdup(p) x_strdup(arena_global, (p)) -/* --- @xrealloc@ --- * +/* --- @xrealloc@, @xreallocv@ --- * * * Arguments: @void *p@ = pointer to a block of memory - * @size_t sz@ = new size desired for the block - * @size_t osz@ = size of the old block + * @size_t n@ = new number of elements (for @xreallocv@) + * @size_t on@ = old number of elements (for @xreallocv@) + * @size_t sz@ = size of elements (for @xreallocv@) or new + * block size (for @xrealloc@) + * @size_t osz@ = size of the old block (for @xrealloc@) * * Returns: Pointer to the resized memory block (which is almost * certainly not in the same place any more). * * Use: Resizes a memory block. If there's not enough memory, the * exception @EXC_NOMEM@ is thrown. + * + * The @xreallocv@ function adjusts a block which currently has + * space for @on@ elements each of size @sz@, so that it now has + * enough space for @n@ elements, preserving the initial @min(n, + * on)@ elements. The @xrealloc@ function is the same, but + * with @sz@ fixed equal to 1, and @n@ and @on@ renamed to @sz@ + * and @osz@ for historical reasons. */ extern void *xrealloc(void */*p*/, size_t /*sz*/, size_t /*osz*/); +extern void *xreallocv(void */*p*/, + size_t /*n*/, size_t /*on*/, size_t /*sz*/); #define xrealloc(p, sz, osz) x_realloc(arena_global, (p), (sz), (osz)) +#define xreallocv(p, sz, osz, n) x_reallocv(arena_global, \ + (p), (sz), (osz), (n)) + +/* --- @XRENEWV@ --- * + * + * Arguments: @type *p@ = a pointer to allocate + * @size_t n, on@ = new and existing numbers of elements + * + * Returns: --- + * + * Use: Adjust @p@ to point to a new block of memory with space for + * @n@ elements of the type pointed to by @p@, on the assumption + * that @p@ is either null or currently points to a block with + * space for @on@ elements. + */ + +#define XRENEWV(p, n, on) X_RENEWV((p), arena_global, (n), (on)) /* --- @xfree@ --- * *