2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 14:35:26 +00:00

Replace isc_mem_*_aligned(..., alignment) with isc_mem_*x(..., flags)

Previously, the isc_mem_get_aligned() and friends took alignment size as
one of the arguments.  Replace the specific function with more generic
extended variant that now accepts ISC_MEM_ALIGN(alignment) for aligned
allocations and ISC_MEM_ZERO for allocations that zeroes
the (re-)allocated memory before returning the pointer to the caller.
This commit is contained in:
Ondřej Surý
2022-06-03 12:23:49 +02:00
parent 4d5fd50f9a
commit dbf5672f32
5 changed files with 291 additions and 124 deletions

View File

@@ -125,26 +125,52 @@ extern unsigned int isc_mem_defaultflags;
* (two underscores). The single-underscore macros are used to pass
* __FILE__ and __LINE__, and in the case of the put functions, to
* set the pointer being freed to NULL in the calling function.
*
* Many of these functions have a further isc___mem_<function>
* (three underscores) implementation, which is called indirectly
* via the isc_memmethods structure in the mctx so that dynamically
* loaded modules can use them even if named is statically linked.
*/
/*%
* Flags that can be passed to isc_mem_*x() variants of the macros.
*
* The definitions of the macros have been pulled directly from jemalloc.h
* and checked for consistency in mem.c.
*
*\li ISC_MEM_ALIGN(alignment) - use when you need aligned allocation,
*
* NOTE: Set the matching flag, when freeing aligned memory allocation.
*
*\li ISC_MEM_ZERO - fill the memory with zeroes before returning
*/
#if defined(HAVE_MALLOC_NP_H) || defined(HAVE_JEMALLOC)
#if __SIZEOF_POINTER__ == 4
#define ISC_MEM_ALIGN(a) ((int)(ffs((int)(a)) - 1))
#else
#define ISC_MEM_ALIGN(a) \
((int)(((size_t)(a) < (size_t)INT_MAX) \
? ffs((int)(a)) - 1 \
: ffs((int)(((size_t)(a)) >> 32)) + 31))
#endif
#else
#define ISC_MEM_ALIGN(a) (a & 0)
#endif
#define ISC_MEM_ZERO ((int)0x40)
#define ISCMEMFUNC(sfx) isc__mem_##sfx
#define ISCMEMPOOLFUNC(sfx) isc__mempool_##sfx
#define isc_mem_get(c, s) ISCMEMFUNC(get)((c), (s), 0 _ISC_MEM_FILELINE)
#define isc_mem_get_aligned(c, s, a) \
ISCMEMFUNC(get)((c), (s), (a)_ISC_MEM_FILELINE)
#define isc_mem_get(c, s) ISCMEMFUNC(get)((c), (s), 0 _ISC_MEM_FILELINE)
#define isc_mem_getx(c, s, f) ISCMEMFUNC(get)((c), (s), (f)_ISC_MEM_FILELINE)
#define isc_mem_reget(c, p, o, n) \
ISCMEMFUNC(reget)((c), (p), (o), (n), 0 _ISC_MEM_FILELINE)
#define isc_mem_reget_aligned(c, p, o, n, a) \
ISCMEMFUNC(reget)((c), (p), (o), (n), (a)_ISC_MEM_FILELINE)
#define isc_mem_allocate(c, s) ISCMEMFUNC(allocate)((c), (s)_ISC_MEM_FILELINE)
#define isc_mem_regetx(c, p, o, n, f) \
ISCMEMFUNC(reget)((c), (p), (o), (n), (f)_ISC_MEM_FILELINE)
#define isc_mem_allocate(c, s) \
ISCMEMFUNC(allocate)((c), (s), 0 _ISC_MEM_FILELINE)
#define isc_mem_allocatex(c, s, f) \
ISCMEMFUNC(allocate)((c), (s), (f)_ISC_MEM_FILELINE)
#define isc_mem_reallocate(c, p, s) \
ISCMEMFUNC(reallocate)((c), (p), (s)_ISC_MEM_FILELINE)
ISCMEMFUNC(reallocate)((c), (p), (s), 0 _ISC_MEM_FILELINE)
#define isc_mem_reallocatex(c, p, s, f) \
ISCMEMFUNC(reallocate)((c), (p), (s), (f)_ISC_MEM_FILELINE)
#define isc_mem_strdup(c, p) ISCMEMFUNC(strdup)((c), (p)_ISC_MEM_FILELINE)
#define isc_mem_strndup(c, p, l) \
ISCMEMFUNC(strndup)((c), (p), (l)_ISC_MEM_FILELINE)
@@ -155,10 +181,10 @@ extern unsigned int isc_mem_defaultflags;
ISCMEMFUNC(put)((c), (p), (s), 0 _ISC_MEM_FILELINE); \
(p) = NULL; \
} while (0)
#define isc_mem_put_aligned(c, p, s, a) \
#define isc_mem_putx(c, p, s, f) \
do { \
ISCMEMFUNC(put) \
((c), (p), (s), (a)_ISC_MEM_FILELINE); \
((c), (p), (s), (f)_ISC_MEM_FILELINE); \
(p) = NULL; \
} while (0)
#define isc_mem_putanddetach(c, p, s) \
@@ -166,16 +192,21 @@ extern unsigned int isc_mem_defaultflags;
ISCMEMFUNC(putanddetach)((c), (p), (s), 0 _ISC_MEM_FILELINE); \
(p) = NULL; \
} while (0)
#define isc_mem_putanddetach_aligned(c, p, s, a) \
#define isc_mem_putanddetachx(c, p, s, f) \
do { \
ISCMEMFUNC(putanddetach) \
((c), (p), (s), (a)_ISC_MEM_FILELINE); \
((c), (p), (s), (f)_ISC_MEM_FILELINE); \
(p) = NULL; \
} while (0)
#define isc_mem_free(c, p) \
do { \
ISCMEMFUNC(free)((c), (p)_ISC_MEM_FILELINE); \
(p) = NULL; \
#define isc_mem_free(c, p) \
do { \
ISCMEMFUNC(free)((c), (p), 0 _ISC_MEM_FILELINE); \
(p) = NULL; \
} while (0)
#define isc_mem_freex(c, p, f) \
do { \
ISCMEMFUNC(free)((c), (p), (f)_ISC_MEM_FILELINE); \
(p) = NULL; \
} while (0)
#define isc_mempool_put(c, p) \
do { \
@@ -495,23 +526,22 @@ isc_mempool_setfillcount(isc_mempool_t *restrict mpctx,
/*
* Pseudo-private functions for use via macros. Do not call directly.
*/
void ISCMEMFUNC(putanddetach)(isc_mem_t **, void *, size_t,
size_t _ISC_MEM_FLARG);
void ISCMEMFUNC(put)(isc_mem_t *, void *, size_t, size_t _ISC_MEM_FLARG);
void ISCMEMFUNC(free)(isc_mem_t *, void *_ISC_MEM_FLARG);
void ISCMEMFUNC(putanddetach)(isc_mem_t **, void *, size_t, int _ISC_MEM_FLARG);
void ISCMEMFUNC(put)(isc_mem_t *, void *, size_t, int _ISC_MEM_FLARG);
void ISCMEMFUNC(free)(isc_mem_t *, void *, int _ISC_MEM_FLARG);
ISC_ATTR_MALLOC_DEALLOCATOR_IDX(ISCMEMFUNC(put), 2)
void *ISCMEMFUNC(get)(isc_mem_t *, size_t, size_t _ISC_MEM_FLARG);
void *ISCMEMFUNC(get)(isc_mem_t *, size_t, int _ISC_MEM_FLARG);
ISC_ATTR_DEALLOCATOR_IDX(ISCMEMFUNC(put), 2)
void *ISCMEMFUNC(reget)(isc_mem_t *, void *, size_t, size_t,
size_t _ISC_MEM_FLARG);
int _ISC_MEM_FLARG);
ISC_ATTR_MALLOC_DEALLOCATOR_IDX(ISCMEMFUNC(free), 2)
void *ISCMEMFUNC(allocate)(isc_mem_t *, size_t _ISC_MEM_FLARG);
void *ISCMEMFUNC(allocate)(isc_mem_t *, size_t, int _ISC_MEM_FLARG);
ISC_ATTR_DEALLOCATOR_IDX(ISCMEMFUNC(free), 2)
void *ISCMEMFUNC(reallocate)(isc_mem_t *, void *, size_t _ISC_MEM_FLARG);
void *ISCMEMFUNC(reallocate)(isc_mem_t *, void *, size_t, int _ISC_MEM_FLARG);
ISC_ATTR_RETURNS_NONNULL
ISC_ATTR_MALLOC_DEALLOCATOR_IDX(ISCMEMFUNC(free), 2)

View File

@@ -16,41 +16,18 @@
#if !defined(HAVE_JEMALLOC)
#include <stddef.h>
#include <string.h>
#include <isc/util.h>
const char *malloc_conf = NULL;
/* Without jemalloc, isc_mem_get_align() is equal to isc_mem_get() */
#define MALLOCX_ALIGN(a) (a & 0) /* Clear the flag */
#define MALLOCX_ZERO ((int)0x40)
#if defined(HAVE_MALLOC_SIZE) || defined(HAVE_MALLOC_USABLE_SIZE)
#include <stdlib.h>
static inline void *
mallocx(size_t size, int flags) {
UNUSED(flags);
return (malloc(size));
}
static inline void
sdallocx(void *ptr, size_t size, int flags) {
UNUSED(size);
UNUSED(flags);
free(ptr);
}
static inline void *
rallocx(void *ptr, size_t size, int flags) {
UNUSED(flags);
REQUIRE(size != 0);
return (realloc(ptr, size));
}
#ifdef HAVE_MALLOC_SIZE
#include <malloc/malloc.h>
@@ -75,6 +52,47 @@ sallocx(void *ptr, int flags) {
#endif /* HAVE_MALLOC_SIZE */
static inline void *
mallocx(size_t size, int flags) {
void *ptr = malloc(size);
INSIST(ptr != NULL);
if ((flags & MALLOCX_ZERO) != 0) {
memset(ptr, 0, size);
}
return (ptr);
}
static inline void
sdallocx(void *ptr, size_t size, int flags) {
UNUSED(size);
UNUSED(flags);
free(ptr);
}
static inline void *
rallocx(void *ptr, size_t size, int flags) {
void *new_ptr;
size_t old_size;
REQUIRE(size != 0);
if ((flags & MALLOCX_ZERO) != 0) {
old_size = sallocx(ptr, flags);
}
new_ptr = realloc(ptr, size);
INSIST(new_ptr != NULL);
if ((flags & MALLOCX_ZERO) != 0 && size > old_size) {
memset((uint8_t *)new_ptr + old_size, 0, size - old_size);
}
return (new_ptr);
}
#else /* defined(HAVE_MALLOC_SIZE) || defined (HAVE_MALLOC_USABLE_SIZE) */
#include <stdlib.h>
@@ -88,14 +106,16 @@ static inline void *
mallocx(size_t size, int flags) {
void *ptr = NULL;
UNUSED(flags);
size_info *si = malloc(size + sizeof(*si));
INSIST(si != NULL);
si->size = size;
ptr = &si[1];
if ((flags & MALLOCX_ZERO) != 0) {
memset(ptr, 0, size);
}
return (ptr);
}
@@ -120,13 +140,14 @@ sallocx(void *ptr, int flags) {
static inline void *
rallocx(void *ptr, size_t size, int flags) {
size_info *si = &(((size_info *)ptr)[-1]);
UNUSED(flags);
si = realloc(si, size + sizeof(*si));
size_info *si = realloc(&(((size_info *)ptr)[-1]), size + sizeof(*si));
INSIST(si != NULL);
if ((flags & MALLOCX_ZERO) != 0 && size > si->size) {
memset((uint8_t *)si + sizeof(*si) + si->size, 0,
size - si->size);
}
si->size = size;
ptr = &si[1];

View File

@@ -331,8 +331,6 @@ unlock:
s = ZERO_ALLOCATION_SIZE; \
}
#define MEM_ALIGN(a) ((a) ? MALLOCX_ALIGN(a) : 0)
/*!
* Perform a malloc, doing memory filling and overrun detection as necessary.
*/
@@ -345,7 +343,8 @@ mem_get(isc_mem_t *ctx, size_t size, int flags) {
ret = mallocx(size, flags);
INSIST(ret != NULL);
if ((ctx->flags & ISC_MEMFLAG_FILL) != 0) {
if ((flags & ISC_MEM_ZERO) == 0 && (ctx->flags & ISC_MEMFLAG_FILL) != 0)
{
memset(ret, 0xbe, size); /* Mnemonic for "beef". */
}
@@ -376,7 +375,8 @@ mem_realloc(isc_mem_t *ctx, void *old_ptr, size_t old_size, size_t new_size,
new_ptr = rallocx(old_ptr, new_size, flags);
INSIST(new_ptr != NULL);
if ((ctx->flags & ISC_MEMFLAG_FILL) != 0) {
if ((flags & ISC_MEM_ZERO) == 0 && (ctx->flags & ISC_MEMFLAG_FILL) != 0)
{
ssize_t diff_size = new_size - old_size;
void *diff_ptr = (uint8_t *)new_ptr + old_size;
if (diff_size > 0) {
@@ -434,6 +434,16 @@ mem_putstats(isc_mem_t *ctx, void *ptr, size_t size) {
static void
mem_initialize(void) {
/*
* Check if the values copied from jemalloc still match
*/
#if defined(HAVE_MALLOC_NP_H) || defined(HAVE_JEMALLOC)
RUNTIME_CHECK(ISC_MEM_ZERO == MALLOCX_ZERO);
RUNTIME_CHECK(ISC_MEM_ALIGN(0) == MALLOCX_ALIGN(0));
RUNTIME_CHECK(ISC_MEM_ALIGN(sizeof(void *)) ==
MALLOCX_ALIGN(sizeof(void *)));
#endif /* defined(HAVE_MALLOC_NP_H) || defined(HAVE_JEMALLOC) */
isc_mutex_init(&contextslock);
ISC_LIST_INIT(contexts);
totallost = 0;
@@ -462,7 +472,7 @@ mem_create(isc_mem_t **ctxp, unsigned int debugging, unsigned int flags) {
REQUIRE(ctxp != NULL && *ctxp == NULL);
ctx = mallocx(sizeof(*ctx), MALLOCX_ALIGN(isc_os_cacheline()));
ctx = mallocx(sizeof(*ctx), ISC_MEM_ALIGN(isc_os_cacheline()));
INSIST(ctx != NULL);
*ctx = (isc_mem_t){
@@ -582,7 +592,7 @@ destroy(isc_mem_t *ctx) {
if (ctx->checkfree) {
INSIST(malloced == 0);
}
sdallocx(ctx, sizeof(*ctx), MALLOCX_ALIGN(isc_os_cacheline()));
sdallocx(ctx, sizeof(*ctx), ISC_MEM_ALIGN(isc_os_cacheline()));
}
void
@@ -628,7 +638,7 @@ isc__mem_detach(isc_mem_t **ctxp FLARG) {
void
isc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size,
size_t alignment FLARG) {
int flags FLARG) {
isc_mem_t *ctx = NULL;
REQUIRE(ctxp != NULL && VALID_CONTEXT(*ctxp));
@@ -641,7 +651,7 @@ isc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size,
DELETE_TRACE(ctx, ptr, size, file, line);
mem_putstats(ctx, ptr, size);
mem_put(ctx, ptr, size, MEM_ALIGN(alignment));
mem_put(ctx, ptr, size, flags);
if (isc_refcount_decrement(&ctx->references) == 1) {
isc_refcount_destroy(&ctx->references);
@@ -756,12 +766,12 @@ lo_water(isc_mem_t *ctx) {
}
void *
isc__mem_get(isc_mem_t *ctx, size_t size, size_t alignment FLARG) {
isc__mem_get(isc_mem_t *ctx, size_t size, int flags FLARG) {
void *ptr = NULL;
REQUIRE(VALID_CONTEXT(ctx));
ptr = mem_get(ctx, size, MEM_ALIGN(alignment));
ptr = mem_get(ctx, size, flags);
mem_getstats(ctx, size);
ADD_TRACE(ctx, ptr, size, file, line);
@@ -772,13 +782,13 @@ isc__mem_get(isc_mem_t *ctx, size_t size, size_t alignment FLARG) {
}
void
isc__mem_put(isc_mem_t *ctx, void *ptr, size_t size, size_t alignment FLARG) {
isc__mem_put(isc_mem_t *ctx, void *ptr, size_t size, int flags FLARG) {
REQUIRE(VALID_CONTEXT(ctx));
DELETE_TRACE(ctx, ptr, size, file, line);
mem_putstats(ctx, ptr, size);
mem_put(ctx, ptr, size, MEM_ALIGN(alignment));
mem_put(ctx, ptr, size, flags);
CALL_LO_WATER(ctx);
}
@@ -890,15 +900,15 @@ isc_mem_stats(isc_mem_t *ctx, FILE *out) {
}
void *
isc__mem_allocate(isc_mem_t *ctx, size_t size FLARG) {
isc__mem_allocate(isc_mem_t *ctx, size_t size, int flags FLARG) {
void *ptr = NULL;
REQUIRE(VALID_CONTEXT(ctx));
ptr = mem_get(ctx, size, 0);
ptr = mem_get(ctx, size, flags);
/* Recalculate the real allocated size */
size = sallocx(ptr, 0);
size = sallocx(ptr, flags);
mem_getstats(ctx, size);
ADD_TRACE(ctx, ptr, size, file, line);
@@ -910,20 +920,19 @@ isc__mem_allocate(isc_mem_t *ctx, size_t size FLARG) {
void *
isc__mem_reget(isc_mem_t *ctx, void *old_ptr, size_t old_size, size_t new_size,
size_t alignment FLARG) {
int flags FLARG) {
void *new_ptr = NULL;
if (old_ptr == NULL) {
REQUIRE(old_size == 0);
new_ptr = isc__mem_get(ctx, new_size, alignment FLARG_PASS);
new_ptr = isc__mem_get(ctx, new_size, flags FLARG_PASS);
} else if (new_size == 0) {
isc__mem_put(ctx, old_ptr, old_size, alignment FLARG_PASS);
isc__mem_put(ctx, old_ptr, old_size, flags FLARG_PASS);
} else {
DELETE_TRACE(ctx, old_ptr, old_size, file, line);
mem_putstats(ctx, old_ptr, old_size);
new_ptr = mem_realloc(ctx, old_ptr, old_size, new_size,
MEM_ALIGN(alignment));
new_ptr = mem_realloc(ctx, old_ptr, old_size, new_size, flags);
mem_getstats(ctx, new_size);
ADD_TRACE(ctx, new_ptr, new_size, file, line);
@@ -941,25 +950,26 @@ isc__mem_reget(isc_mem_t *ctx, void *old_ptr, size_t old_size, size_t new_size,
}
void *
isc__mem_reallocate(isc_mem_t *ctx, void *old_ptr, size_t new_size FLARG) {
isc__mem_reallocate(isc_mem_t *ctx, void *old_ptr, size_t new_size,
int flags FLARG) {
void *new_ptr = NULL;
REQUIRE(VALID_CONTEXT(ctx));
if (old_ptr == NULL) {
new_ptr = isc__mem_allocate(ctx, new_size FLARG_PASS);
new_ptr = isc__mem_allocate(ctx, new_size, flags FLARG_PASS);
} else if (new_size == 0) {
isc__mem_free(ctx, old_ptr FLARG_PASS);
isc__mem_free(ctx, old_ptr, flags FLARG_PASS);
} else {
size_t old_size = sallocx(old_ptr, 0);
size_t old_size = sallocx(old_ptr, flags);
DELETE_TRACE(ctx, old_ptr, old_size, file, line);
mem_putstats(ctx, old_ptr, old_size);
new_ptr = mem_realloc(ctx, old_ptr, old_size, new_size, 0);
new_ptr = mem_realloc(ctx, old_ptr, old_size, new_size, flags);
/* Recalculate the real allocated size */
new_size = sallocx(new_ptr, 0);
new_size = sallocx(new_ptr, flags);
mem_getstats(ctx, new_size);
ADD_TRACE(ctx, new_ptr, new_size, file, line);
@@ -977,18 +987,18 @@ isc__mem_reallocate(isc_mem_t *ctx, void *old_ptr, size_t new_size FLARG) {
}
void
isc__mem_free(isc_mem_t *ctx, void *ptr FLARG) {
isc__mem_free(isc_mem_t *ctx, void *ptr, int flags FLARG) {
size_t size = 0;
REQUIRE(VALID_CONTEXT(ctx));
REQUIRE(ptr != NULL);
size = sallocx(ptr, 0);
size = sallocx(ptr, flags);
DELETE_TRACE(ctx, ptr, size, file, line);
mem_putstats(ctx, ptr, size);
mem_put(ctx, ptr, size, 0);
mem_put(ctx, ptr, size, flags);
CALL_LO_WATER(ctx);
}
@@ -1007,7 +1017,7 @@ isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) {
len = strlen(s) + 1;
ns = isc__mem_allocate(mctx, len FLARG_PASS);
ns = isc__mem_allocate(mctx, len, 0 FLARG_PASS);
strlcpy(ns, s, len);
@@ -1028,7 +1038,7 @@ isc__mem_strndup(isc_mem_t *mctx, const char *s, size_t size FLARG) {
len = size;
}
ns = isc__mem_allocate(mctx, len FLARG_PASS);
ns = isc__mem_allocate(mctx, len, 0 FLARG_PASS);
strlcpy(ns, s, len);

View File

@@ -94,13 +94,13 @@ isc__tls_set_thread_id(CRYPTO_THREADID *id) {
static void *
isc__tls_malloc_ex(size_t size, const char *file, int line) {
return (isc__mem_allocate(isc__tls_mctx, size, file,
return (isc__mem_allocate(isc__tls_mctx, size, 0, file,
(unsigned int)line));
}
static void *
isc__tls_realloc_ex(void *ptr, size_t size, const char *file, int line) {
return (isc__mem_reallocate(isc__tls_mctx, ptr, size, file,
return (isc__mem_reallocate(isc__tls_mctx, ptr, size, 0, file,
(unsigned int)line));
}
@@ -109,7 +109,7 @@ isc__tls_free_ex(void *ptr, const char *file, int line) {
if (ptr == NULL) {
return;
}
isc__mem_free(isc__tls_mctx, ptr, file, (unsigned int)line);
isc__mem_free(isc__tls_mctx, ptr, 0, file, (unsigned int)line);
}
#elif OPENSSL_VERSION_NUMBER >= 0x10100000L
@@ -135,7 +135,7 @@ isc__tls_free_ex(void *ptr, const char *file, int line) {
if (ptr == NULL) {
return;
}
isc__mem_free(isc__tls_mctx, ptr);
isc__mem_free(isc__tls_mctx, ptr, 0);
}
#endif /* ISC_MEM_TRACKLINES */

View File

@@ -29,6 +29,7 @@
#include <isc/mutex.h>
#include <isc/os.h>
#include <isc/print.h>
#include <isc/random.h>
#include <isc/result.h>
#include <isc/stdio.h>
#include <isc/thread.h>
@@ -47,7 +48,7 @@
#define MP2_FILLCNT 25
/* general memory system tests */
ISC_RUN_TEST_IMPL(isc_mem) {
ISC_RUN_TEST_IMPL(isc_mem_get) {
void *items1[50];
void *items2[50];
void *tmp;
@@ -55,8 +56,6 @@ ISC_RUN_TEST_IMPL(isc_mem) {
unsigned int i, j;
int rval;
UNUSED(state);
isc_mempool_create(mctx, 24, &mp1);
isc_mempool_create(mctx, 31, &mp2);
@@ -130,41 +129,119 @@ ISC_RUN_TEST_IMPL(isc_mem) {
#if defined(HAVE_MALLOC_NP_H) || defined(HAVE_JEMALLOC)
/* aligned memory system tests */
ISC_RUN_TEST_IMPL(isc_mem_aligned) {
ISC_RUN_TEST_IMPL(isc_mem_get_align) {
isc_mem_t *mctx2 = NULL;
void *ptr;
size_t alignment;
uintptr_t aligned;
UNUSED(state);
/* Check different alignment sizes up to the page size */
for (alignment = sizeof(void *); alignment <= 4096; alignment *= 2) {
size_t size = alignment / 2 - 1;
ptr = isc_mem_get_aligned(mctx, size, alignment);
ptr = isc_mem_getx(mctx, size, ISC_MEM_ALIGN(alignment));
/* Check if the pointer is properly aligned */
aligned = (((uintptr_t)ptr / alignment) * alignment);
assert_ptr_equal(aligned, (uintptr_t)ptr);
/* Check if we can resize to <alignment, 2*alignment> range */
ptr = isc_mem_reget_aligned(mctx, ptr, size,
size * 2 + alignment, alignment);
ptr = isc_mem_regetx(mctx, ptr, size, size * 2 + alignment,
ISC_MEM_ALIGN(alignment));
/* Check if the pointer is still properly aligned */
aligned = (((uintptr_t)ptr / alignment) * alignment);
assert_ptr_equal(aligned, (uintptr_t)ptr);
isc_mem_put_aligned(mctx, ptr, size * 2 + alignment, alignment);
isc_mem_putx(mctx, ptr, size * 2 + alignment,
ISC_MEM_ALIGN(alignment));
/* Check whether isc_mem_putanddetach_detach() also works */
isc_mem_create(&mctx2);
ptr = isc_mem_get_aligned(mctx2, size, alignment);
isc_mem_putanddetach_aligned(&mctx2, ptr, size, alignment);
ptr = isc_mem_getx(mctx2, size, ISC_MEM_ALIGN(alignment));
isc_mem_putanddetachx(&mctx2, ptr, size,
ISC_MEM_ALIGN(alignment));
}
}
/* aligned memory system tests */
ISC_RUN_TEST_IMPL(isc_mem_allocate_align) {
void *ptr;
size_t alignment;
uintptr_t aligned;
/* Check different alignment sizes up to the page size */
for (alignment = sizeof(void *); alignment <= 4096; alignment *= 2) {
size_t size = alignment / 2 - 1;
ptr = isc_mem_allocatex(mctx, size, ISC_MEM_ALIGN(alignment));
/* Check if the pointer is properly aligned */
aligned = (((uintptr_t)ptr / alignment) * alignment);
assert_ptr_equal(aligned, (uintptr_t)ptr);
/* Check if we can resize to <alignment, 2*alignment> range */
ptr = isc_mem_reallocatex(mctx, ptr, size * 2 + alignment,
ISC_MEM_ALIGN(alignment));
/* Check if the pointer is still properly aligned */
aligned = (((uintptr_t)ptr / alignment) * alignment);
assert_ptr_equal(aligned, (uintptr_t)ptr);
isc_mem_freex(mctx, ptr, ISC_MEM_ALIGN(alignment));
}
}
#endif /* defined(HAVE_MALLOC_NP_H) || defined(HAVE_JEMALLOC) */
/* zeroed memory system tests */
ISC_RUN_TEST_IMPL(isc_mem_get_zero) {
uint8_t *ptr;
bool zeroed;
uint8_t expected[4096] = { 0 };
/* Skip the test if the memory is zeroed even in normal case */
zeroed = true;
ptr = isc_mem_get(mctx, sizeof(expected));
for (size_t i = 0; i < sizeof(expected); i++) {
if (ptr[i] != expected[i]) {
zeroed = false;
break;
}
}
isc_mem_put(mctx, ptr, sizeof(expected));
if (zeroed) {
skip();
return;
}
ptr = isc_mem_getx(mctx, sizeof(expected), ISC_MEM_ZERO);
assert_memory_equal(ptr, expected, sizeof(expected));
isc_mem_put(mctx, ptr, sizeof(expected));
}
ISC_RUN_TEST_IMPL(isc_mem_allocate_zero) {
uint8_t *ptr;
bool zeroed;
uint8_t expected[4096] = { 0 };
/* Skip the test if the memory is zeroed even in normal case */
zeroed = true;
ptr = isc_mem_get(mctx, sizeof(expected));
for (size_t i = 0; i < sizeof(expected); i++) {
if (ptr[i] != expected[i]) {
zeroed = false;
break;
}
}
isc_mem_put(mctx, ptr, sizeof(expected));
if (zeroed) {
skip();
return;
}
ptr = isc_mem_allocatex(mctx, sizeof(expected), ISC_MEM_ZERO);
assert_memory_equal(ptr, expected, sizeof(expected));
isc_mem_free(mctx, ptr);
}
/* test TotalUse calculation */
ISC_RUN_TEST_IMPL(isc_mem_total) {
isc_mem_t *mctx2 = NULL;
@@ -172,8 +249,6 @@ ISC_RUN_TEST_IMPL(isc_mem_total) {
ssize_t diff;
int i;
UNUSED(state);
/* Local alloc, free */
mctx2 = NULL;
isc_mem_create(&mctx2);
@@ -218,8 +293,6 @@ ISC_RUN_TEST_IMPL(isc_mem_inuse) {
ssize_t diff;
void *ptr;
UNUSED(state);
mctx2 = NULL;
isc_mem_create(&mctx2);
@@ -237,7 +310,6 @@ ISC_RUN_TEST_IMPL(isc_mem_inuse) {
ISC_RUN_TEST_IMPL(isc_mem_zeroget) {
uint8_t *data = NULL;
UNUSED(state);
data = isc_mem_get(mctx, 0);
assert_non_null(data);
@@ -251,8 +323,6 @@ ISC_RUN_TEST_IMPL(isc_mem_zeroget) {
ISC_RUN_TEST_IMPL(isc_mem_reget) {
uint8_t *data = NULL;
UNUSED(state);
/* test that we can reget NULL */
data = isc_mem_reget(mctx, NULL, 0, REGET_INIT_SIZE);
assert_non_null(data);
@@ -290,6 +360,46 @@ ISC_RUN_TEST_IMPL(isc_mem_reget) {
isc_mem_put(mctx, data, REGET_SHRINK_SIZE);
}
ISC_RUN_TEST_IMPL(isc_mem_reallocatex) {
uint8_t *data = NULL;
/* test that we can reallocate NULL */
data = isc_mem_reallocatex(mctx, NULL, REGET_INIT_SIZE, 0);
assert_non_null(data);
isc_mem_free(mctx, data);
/* test that we can re-get a zero-length allocation */
data = isc_mem_allocatex(mctx, 0, 0);
assert_non_null(data);
data = isc_mem_reallocatex(mctx, data, REGET_INIT_SIZE, 0);
assert_non_null(data);
for (size_t i = 0; i < REGET_INIT_SIZE; i++) {
data[i] = i % UINT8_MAX;
}
data = isc_mem_reallocatex(mctx, data, REGET_GROW_SIZE, 0);
assert_non_null(data);
for (size_t i = 0; i < REGET_INIT_SIZE; i++) {
assert_int_equal(data[i], i % UINT8_MAX);
}
for (size_t i = REGET_GROW_SIZE; i > 0; i--) {
data[i - 1] = i % UINT8_MAX;
}
data = isc_mem_reallocatex(mctx, data, REGET_SHRINK_SIZE, 0);
assert_non_null(data);
for (size_t i = REGET_SHRINK_SIZE; i > 0; i--) {
assert_int_equal(data[i - 1], i % UINT8_MAX);
}
isc_mem_free(mctx, data);
}
#if ISC_MEM_TRACKLINES
/* test mem with no flags */
@@ -303,8 +413,6 @@ ISC_RUN_TEST_IMPL(isc_mem_noflags) {
result = isc_stdio_open("mem.output", "w", &f);
assert_int_equal(result, ISC_R_SUCCESS);
UNUSED(state);
isc_mem_debugging = 0;
isc_mem_create(&mctx2);
ptr = isc_mem_get(mctx2, 2048);
@@ -340,8 +448,6 @@ ISC_RUN_TEST_IMPL(isc_mem_recordflag) {
result = isc_stdio_open("mem.output", "w", &f);
assert_int_equal(result, ISC_R_SUCCESS);
UNUSED(state);
isc_mem_create(&mctx2);
ptr = isc_mem_get(mctx2, 2048);
assert_non_null(ptr);
@@ -381,8 +487,6 @@ ISC_RUN_TEST_IMPL(isc_mem_traceflag) {
f = freopen("mem.output", "w", stderr);
assert_non_null(f);
UNUSED(state);
isc_mem_debugging = ISC_MEM_DEBUGRECORD | ISC_MEM_DEBUGTRACE;
isc_mem_create(&mctx2);
ptr = isc_mem_get(mctx2, 2048);
@@ -459,8 +563,6 @@ ISC_RUN_TEST_IMPL(isc_mem_benchmark) {
double t;
isc_result_t result;
UNUSED(state);
atomic_init(&mem_size, ITEM_SIZE);
result = isc_time_now(&ts1);
@@ -489,14 +591,18 @@ ISC_RUN_TEST_IMPL(isc_mem_benchmark) {
ISC_TEST_LIST_START
ISC_TEST_ENTRY(isc_mem)
ISC_TEST_ENTRY(isc_mem_get)
#if defined(HAVE_MALLOC_NP_H) || defined(HAVE_JEMALLOC)
ISC_TEST_ENTRY(isc_mem_aligned)
ISC_TEST_ENTRY(isc_mem_get_align)
ISC_TEST_ENTRY(isc_mem_allocate_align)
#endif /* defined(HAVE_MALLOC_NP_H) || defined(HAVE_JEMALLOC) */
ISC_TEST_ENTRY(isc_mem_get_zero)
ISC_TEST_ENTRY(isc_mem_allocate_zero)
ISC_TEST_ENTRY(isc_mem_total)
ISC_TEST_ENTRY(isc_mem_inuse)
ISC_TEST_ENTRY(isc_mem_zeroget)
ISC_TEST_ENTRY(isc_mem_reget)
ISC_TEST_ENTRY(isc_mem_reallocatex)
#if ISC_MEM_TRACKLINES
ISC_TEST_ENTRY(isc_mem_noflags)