]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Use system allocator when jemalloc is unavailable
authorOndřej Surý <ondrej@sury.org>
Tue, 25 May 2021 10:46:00 +0000 (12:46 +0200)
committerOndřej Surý <ondrej@sury.org>
Fri, 9 Jul 2021 13:58:02 +0000 (15:58 +0200)
This commit adds support for systems where the jemalloc library is not
available as a package, here's the quick summary:

  * On Linux - the jemalloc is usually available as a package, if
    configured --without-jemalloc, the shim would be used around
    malloc(), free(), realloc() and malloc_usable_size()

  * On macOS - the jemalloc is available from homebrew or macports, if
    configured --without-jemalloc, the shim would be used around
    malloc(), free(), realloc() and malloc_size()

  * On FreeBSD - the jemalloc is *the* system allocator, we just need
    to check for <malloc_np.h> header to get access to non-standard API

  * On NetBSD - the jemalloc is *the* system allocator, we just need to
    check for <jemalloc/jemalloc.h> header to get access to non-standard
    API

  * On a system hostile to users and developers (read OpenBSD) - the
    jemalloc API is emulated by using ((size_t *)ptr)[-1] field to hold
    the size information.  The OpenBSD developers care only for
    themselves, so why should we care about speed on OpenBSD?

configure.ac
lib/isc/Makefile.am
lib/isc/jemalloc_shim.h [new file with mode: 0644]
lib/isc/mem.c
m4/ax_jemalloc.m4 [new file with mode: 0644]
util/copyrights

index 7ada1b61eed9efbc17fd24de66d23c91aebfc8ab..3aa9cc57cb9790f2160cf5ccdf76e2c7a4908871 100644 (file)
@@ -1377,15 +1377,26 @@ AC_SUBST([CMOCKA_LIBS])
 AM_CONDITIONAL([HAVE_CMOCKA], [test "$with_cmocka" = "yes"])
 
 #
+# Compile with jemalloc (either provided as package or wired in the system on FreeBSD and NetBSD)
 #
-#
-AC_MSG_CHECKING([for jemalloc])
-PKG_CHECK_MODULES([JEMALLOC], [jemalloc >= 5], []
-                 [AC_MSG_WARN([Using jemalloc 5 is recommended])
-                  PKG_CHECK_MODULES([JEMALLOC], [jemalloc], [],
-                                    [AC_MSG_ERROR([jemalloc not found])])])
-AC_SUBST([JEMALLOC_CFLAGS])
-AC_SUBST([JEMALLOC_LIBS])
+# [pairwise: --with-jemalloc=detect, --with-jemalloc=yes, --without-jemalloc]
+AC_ARG_WITH([jemalloc],
+           [AS_HELP_STRING([--with-jemalloc=detect],[enable jemalloc memory allocator (default is detect)])],
+           [],[with_jemalloc=detect])
+
+AS_CASE([$with_jemalloc],
+       [no],[],
+       [yes],[AX_CHECK_JEMALLOC(
+                [AC_DEFINE([HAVE_JEMALLOC], [1], [Define to 1 if jemalloc is available])],
+                [AC_MSG_ERROR([jemalloc not found])])],
+       [AX_CHECK_JEMALLOC(
+          [AC_DEFINE([HAVE_JEMALLOC], [1], [Define to 1 if jemalloc is available])
+           with_jemalloc=yes],
+          [AC_MSG_WARN([jemalloc not found; performance will be reduced])
+           with_jemalloc=no])])
+
+AS_IF([test "$with_jemalloc" = "no"],
+      [AC_CHECK_FUNCS([malloc_size malloc_usable_size])])
 
 #
 # was --with-tuning specified?
@@ -1698,6 +1709,9 @@ report() {
     echo "Configuration summary:"
     echo "-------------------------------------------------------------------------------"
     echo "Optional features enabled:"
+    if test "yes" = "$with_jemalloc"; then
+       echo "    Memory allocator: jemalloc"
+    fi
     if test "yes" = "$enable_full_report" -o "standard" = "$with_locktype"; then
        echo "    Mutex lock type: $with_locktype"
     fi
@@ -1754,6 +1768,14 @@ report() {
     echo "-------------------------------------------------------------------------------"
 
     echo "Features disabled or unavailable on this platform:"
+    if test "no" = "$with_jemalloc"; then
+      echo "    Memory allocator: system"
+      echo "    WARNING: This is not a recommended configuration"
+      echo "    WARNING: Using system memory allocator causes"
+      echo "    WARNING: reduced performance and increased memory"
+      echo "    WARNING: fragmentation.  Installing jemalloc >= 4.0.0"
+      echo "    WARNING: memory allocator is strongly recommended."
+    fi
     test "small" = "$with_tuning" || echo "    Small-system tuning (--with-tuning)"
 
     test "no" = "$enable_dnstap" && \
index 1b5898817bf4d1ffa7a5832a57b2454f1b1bec5f..5f90634b3a11e98abe3fdf18cc0f337fe4523928 100644 (file)
@@ -167,6 +167,7 @@ libisc_la_SOURCES =         \
        httpd.c                 \
        interfaceiter.c         \
        iterated_hash.c         \
+       jemalloc_shim.h         \
        lex.c                   \
        lib.c                   \
        log.c                   \
diff --git a/lib/isc/jemalloc_shim.h b/lib/isc/jemalloc_shim.h
new file mode 100644 (file)
index 0000000..11f8099
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#pragma once
+
+#if !defined(HAVE_JEMALLOC)
+
+#include <isc/util.h>
+
+const char *malloc_conf = NULL;
+
+#if defined(HAVE_MALLOC_SIZE) || defined(HAVE_MALLOC_USABLE_SIZE)
+
+#include <stdlib.h>
+
+static inline void *
+mallocx(size_t size, int flags) {
+       UNUSED(flags);
+       void *__ptr = malloc(size);
+       REQUIRE(__ptr != NULL);
+       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) {
+       UNUSED(flags);
+       REQUIRE(size != 0);
+
+       void *__ptr = realloc(ptr, size);
+       REQUIRE(__ptr != NULL);
+
+       return (__ptr);
+}
+
+#ifdef HAVE_MALLOC_SIZE
+
+#include <malloc/malloc.h>
+
+static inline size_t
+sallocx(void *ptr, int flags) {
+       UNUSED(flags);
+
+       return (malloc_size(ptr));
+}
+
+#elif HAVE_MALLOC_USABLE_SIZE
+
+#include <malloc.h>
+
+static inline size_t
+sallocx(void *ptr, int flags) {
+       UNUSED(flags);
+
+       return (malloc_usable_size(ptr));
+}
+
+#endif /* HAVE_MALLOC_SIZE */
+
+#else /* defined(HAVE_MALLOC_SIZE) || defined (HAVE_MALLOC_USABLE_SIZE) */
+
+#include <stdlib.h>
+
+static inline void *
+mallocx(size_t size, int flags) {
+       UNUSED(flags);
+
+       size_t *__ptr = malloc(size + sizeof(size_t));
+       REQUIRE(__ptr != NULL);
+       __ptr[0] = size;
+
+       return (&__ptr[1]);
+}
+
+static inline void
+sdallocx(void *ptr, size_t size, int flags) {
+       UNUSED(size);
+       UNUSED(flags);
+
+       free(&((size_t *)ptr)[-1]);
+}
+
+static inline size_t
+sallocx(void *ptr, int flags) {
+       UNUSED(flags);
+
+       return (((size_t *)ptr)[-1]);
+}
+
+static inline void *
+rallocx(void *ptr, size_t size, int flags) {
+       UNUSED(flags);
+
+       size_t *__ptr = realloc(&((size_t *)ptr)[-1], size);
+       REQUIRE(__ptr != NULL);
+       __ptr[0] = size;
+
+       return (&__ptr[1]);
+}
+
+#endif /* defined(HAVE_MALLOC_SIZE) || defined (HAVE_MALLOC_USABLE_SIZE) */
+
+#endif /* !defined(HAVE_JEMALLOC) */
index ed30d1aa2b426b8ba8e4fe24c89c0d283aadb641..f023737098ee57182ba05fbce59d6c3e25ee0f8a 100644 (file)
 #include <json_object.h>
 #endif /* HAVE_JSON_C */
 
+#if defined(HAVE_MALLOC_NP_H)
+#include <malloc_np.h>
+#elif defined(HAVE_JEMALLOC)
 #include <jemalloc/jemalloc.h>
 
+#if JEMALLOC_VERSION_MAJOR < 4
+#define sdallocx(ptr, size, flags) dallocx(ptr, flags)
+#endif /* JEMALLOC_VERSION_MAJOR < 4 */
+
+#else
+#include "jemalloc_shim.h"
+#endif
+
 #include "mem_p.h"
 
 #define MCTXLOCK(m)   LOCK(&m->lock)
diff --git a/m4/ax_jemalloc.m4 b/m4/ax_jemalloc.m4
new file mode 100644 (file)
index 0000000..3d7b463
--- /dev/null
@@ -0,0 +1,53 @@
+# ===========================================================================
+#      https://gitlab.isc.org/isc-projects/autoconf-archive/ax_jemalloc.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CHECK_JEMALLOC([, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+#
+# DESCRIPTION
+#
+#   Test for the jemalloc library in a path
+#
+# LICENSE
+#
+#   Copyright (c) 2021 Internet Systems Consortium
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 1
+
+#
+AC_DEFUN([AX_CHECK_JEMALLOC], [
+     found=false
+     PKG_CHECK_MODULES(
+       [JEMALLOC], [jemalloc],
+       [
+           found=true
+       ], [
+           AC_CHECK_HEADERS([malloc_np.h jemalloc/jemalloc.h],
+               [
+                   save_LIBS="$LIBS"
+                   save_LDFLAGS="$LDFLAGS"
+                   save_CPPFLAGS="$CPPFLAGS"
+                   AC_SEARCH_LIBS([mallocx], [jemalloc],
+                       [
+                           found=true
+                           AS_IF([test "$ac_cv_search_mallocx" != "none required"],
+                               [JEMALLOC_LIBS="$ac_cv_search_mallocx"])
+                       ])
+                   CPPFLAGS="$save_CPPFLAGS"
+                   LDFLAGS="$save_LDFLAGS"
+                   LIBS="$save_LIBS"
+               ])
+       ])
+
+    AS_IF([$found], [$1], [$2])
+
+    AC_SUBST([JEMALLOC_CFLAGS])
+    AC_SUBST([JEMALLOC_LIBS])
+])
index f982fbae206710c2fda4404bdbf3fe24fdc56500..68aede72b4b77d1b4ef1bf939a81d668108b7adc 100644 (file)
 ./lib/isc/include/pkcs11/pkcs11.h              X       2019,2020,2021
 ./lib/isc/interfaceiter.c                      C       1999,2000,2001,2002,2003,2004,2005,2007,2008,2014,2016,2017,2018,2019,2020,2021
 ./lib/isc/iterated_hash.c                      C       2006,2008,2009,2016,2018,2019,2020,2021
+./lib/isc/jemalloc_shim.h                      C       2021
 ./lib/isc/lex.c                                        C       1998,1999,2000,2001,2002,2003,2004,2005,2007,2013,2014,2015,2016,2017,2018,2019,2020,2021
 ./lib/isc/lib.c                                        C       1999,2000,2001,2004,2005,2007,2009,2013,2014,2015,2016,2018,2019,2020,2021
 ./lib/isc/log.c                                        C       1999,2000,2001,2002,2003,2004,2005,2006,2007,2009,2011,2012,2013,2014,2016,2017,2018,2019,2020,2021