]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Replace isc_mem_*_aligned(..., alignment) with isc_mem_*x(..., flags)
authorOndřej Surý <ondrej@isc.org>
Fri, 3 Jun 2022 10:23:49 +0000 (12:23 +0200)
committerOndřej Surý <ondrej@isc.org>
Wed, 5 Oct 2022 14:44:05 +0000 (16:44 +0200)
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.

lib/isc/include/isc/mem.h
lib/isc/jemalloc_shim.h
lib/isc/mem.c
lib/isc/tls.c
tests/isc/mem_test.c

index 0121f560b93df03a8bb4b1799184da452916463c..0249979eec8b445dff7f953acb0fedcb083ae92b 100644 (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.
+ */
+
+/*%
+ * 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)
@@ -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)
index 8d99c7b776e76f4cfb99f567b7d0aae7a6da3396..c1b6f9c9aae888a1ffef56b2270d58d6148c589e 100644 (file)
 #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];
 
index a68d7d67661a4c4faa765c0886ede64d84f9dca9..50da4c2832c7f3ac37ff6bb424df3e17eed59649 100644 (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);
 
index ca2788e391a92d263e702011bdf5aea876764bbf..aa81068fd10c50337c656fa70367e5816a4f5f46 100644 (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 */
index 183b2e7891207295bcb89840ff2a7df18f0eaf70..5badf1a10c9e7396bbeb19aea6cc720971db3abd 100644 (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)