* (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_<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.
+ * 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)
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) \
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 { \
/*
* 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)
#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>
#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>
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);
}
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];
s = ZERO_ALLOCATION_SIZE; \
}
-#define MEM_ALIGN(a) ((a) ? MALLOCX_ALIGN(a) : 0)
-
/*!
* Perform a malloc, doing memory filling and overrun detection as necessary.
*/
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". */
}
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) {
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;
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){
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
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));
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);
}
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);
}
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);
}
}
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);
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);
}
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);
}
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);
}
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);
len = size;
}
- ns = isc__mem_allocate(mctx, len FLARG_PASS);
+ ns = isc__mem_allocate(mctx, len, 0 FLARG_PASS);
strlcpy(ns, s, len);
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));
}
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
if (ptr == NULL) {
return;
}
- isc__mem_free(isc__tls_mctx, ptr);
+ isc__mem_free(isc__tls_mctx, ptr, 0);
}
#endif /* ISC_MEM_TRACKLINES */
#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>
#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;
unsigned int i, j;
int rval;
- UNUSED(state);
-
isc_mempool_create(mctx, 24, &mp1);
isc_mempool_create(mctx, 31, &mp2);
#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;
ssize_t diff;
int i;
- UNUSED(state);
-
/* Local alloc, free */
mctx2 = NULL;
isc_mem_create(&mctx2);
ssize_t diff;
void *ptr;
- UNUSED(state);
-
mctx2 = NULL;
isc_mem_create(&mctx2);
ISC_RUN_TEST_IMPL(isc_mem_zeroget) {
uint8_t *data = NULL;
- UNUSED(state);
data = isc_mem_get(mctx, 0);
assert_non_null(data);
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);
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 */
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);
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);
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);
double t;
isc_result_t result;
- UNUSED(state);
-
atomic_init(&mem_size, ITEM_SIZE);
result = isc_time_now(&ts1);
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)