From: Ondřej Surý Date: Fri, 3 Jun 2022 10:23:49 +0000 (+0200) Subject: Replace isc_mem_*_aligned(..., alignment) with isc_mem_*x(..., flags) X-Git-Tag: v9.19.6~8^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dbf5672f320f26a547072786f7005309b951049b;p=thirdparty%2Fbind9.git 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. --- diff --git a/lib/isc/include/isc/mem.h b/lib/isc/include/isc/mem.h index 0121f560b93..0249979eec8 100644 --- a/lib/isc/include/isc/mem.h +++ b/lib/isc/include/isc/mem.h @@ -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. + */ + +/*% + * 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, * - * Many of these functions have a further isc___mem_ - * (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. + * 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) diff --git a/lib/isc/jemalloc_shim.h b/lib/isc/jemalloc_shim.h index 8d99c7b776e..c1b6f9c9aae 100644 --- a/lib/isc/jemalloc_shim.h +++ b/lib/isc/jemalloc_shim.h @@ -16,41 +16,18 @@ #if !defined(HAVE_JEMALLOC) #include +#include #include 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 -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 @@ -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 @@ -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]; diff --git a/lib/isc/mem.c b/lib/isc/mem.c index a68d7d67661..50da4c2832c 100644 --- a/lib/isc/mem.c +++ b/lib/isc/mem.c @@ -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); diff --git a/lib/isc/tls.c b/lib/isc/tls.c index ca2788e391a..aa81068fd10 100644 --- a/lib/isc/tls.c +++ b/lib/isc/tls.c @@ -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 */ diff --git a/tests/isc/mem_test.c b/tests/isc/mem_test.c index 183b2e78912..5badf1a10c9 100644 --- a/tests/isc/mem_test.c +++ b/tests/isc/mem_test.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -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 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 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)