]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Special, for-tests-only, mode with atomics emulated by a mutex-locked variable -...
authorWitold Kręcicki <wpk@isc.org>
Fri, 17 May 2019 09:35:35 +0000 (11:35 +0200)
committerWitold Kręcicki <wpk@isc.org>
Tue, 9 Jul 2019 14:09:36 +0000 (16:09 +0200)
config.h.in
configure
configure.ac
lib/isc/include/isc/atomic.h
lib/isc/include/isc/mutexatomic.h [new file with mode: 0644]
lib/ns/query.c
util/copyrights

index de8d128b5b1486ece19c41cfa18a25d4cd8c1f74..1f0a9f7d782c8ee59e1b2237adf27843ce7a1eb0 100644 (file)
 /* Define to allow building of objects for dlopen(). */
 #undef ISC_DLZ_DLOPEN
 
+/* Define to emulate atomic variables with mutexes. */
+#undef ISC_MUTEX_ATOMICS
+
 /* define if the linker supports --wrap option */
 #undef LD_WRAP
 
index d1c264bca09f5aef6c3d4dc6a020763ce86ea14e..6845ea53db274bad34ad67b030bfd416dcf3da7c 100755 (executable)
--- a/configure
+++ b/configure
@@ -850,6 +850,7 @@ infodir
 docdir
 oldincludedir
 includedir
+runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -897,6 +898,7 @@ enable_warn_shadow
 enable_warn_error
 enable_developer
 enable_fuzzing
+enable_mutex_atomics
 with_python
 with_python_install_dir
 enable_kqueue
@@ -1018,6 +1020,7 @@ datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1270,6 +1273,15 @@ do
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+    ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+    runstatedir=$ac_optarg ;;
+
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1407,7 +1419,7 @@ fi
 for ac_var in  exec_prefix prefix bindir sbindir libexecdir datarootdir \
                datadir sysconfdir sharedstatedir localstatedir includedir \
                oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-               libdir localedir mandir
+               libdir localedir mandir runstatedir
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -1560,6 +1572,7 @@ Fine tuning of the installation directories:
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
@@ -1611,6 +1624,8 @@ Optional Features:
   --enable-fuzzing=<afl|libfuzzer>
                           Enable fuzzing using American Fuzzy Lop or libFuzzer
                           (default=no)
+  --enable-mutex-atomics  emulate atomics by mutex-locked variables, useful
+                          for debugging [default=no]
   --enable-kqueue         use BSD kqueue when available [default=yes]
   --enable-epoll          use Linux epoll when available [default=auto]
   --enable-devpoll        use /dev/poll when available [default=yes]
@@ -3998,7 +4013,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                       && LARGE_OFF_T % 2147483647 == 1)
                      ? 1 : -1];
@@ -4044,7 +4059,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                       && LARGE_OFF_T % 2147483647 == 1)
                      ? 1 : -1];
@@ -4068,7 +4083,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                       && LARGE_OFF_T % 2147483647 == 1)
                      ? 1 : -1];
@@ -4113,7 +4128,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                       && LARGE_OFF_T % 2147483647 == 1)
                      ? 1 : -1];
@@ -4137,7 +4152,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
                       && LARGE_OFF_T % 2147483647 == 1)
                      ? 1 : -1];
@@ -12314,6 +12329,33 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
 fi
 
+# Check whether --enable-mutex_atomics was given.
+if test "${enable_mutex_atomics+set}" = set; then :
+  enableval=$enable_mutex_atomics;
+else
+  enable_mutex_atomics=no
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to emulate atomics with mutexes" >&5
+$as_echo_n "checking whether to emulate atomics with mutexes... " >&6; }
+case "$enable_mutex_atomics" in
+yes)
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define ISC_MUTEX_ATOMICS 1" >>confdefs.h
+
+        ;;
+no)
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+        ;;
+*)
+        as_fn_error $? "\"--enable-mutex-atomics requires yes or no\"" "$LINENO" 5
+        ;;
+esac
+
 #
 # Make very sure that these are the first files processed by
 # config.status, since we use the processed output as the input for
index c50337d324108ff12260500d9f3feff4f1a9947b..63e7b30160479d8dc01559e27fd55c555047ccbb 100644 (file)
@@ -132,6 +132,27 @@ AS_IF([test "$enable_fuzzing" = "afl"],
                         [AC_MSG_ERROR([set CC=afl-<gcc|clang> when --enable-fuzzing=afl is used])])
       ])
 
+AC_ARG_ENABLE(mutex_atomics,
+             AS_HELP_STRING([--enable-mutex-atomics],
+                            [emulate atomics by mutex-locked variables, useful for debugging
+                               [default=no]]),
+             [],
+             [enable_mutex_atomics=no])
+
+AC_MSG_CHECKING([whether to emulate atomics with mutexes])
+case "$enable_mutex_atomics" in
+yes)
+        AC_MSG_RESULT(yes)
+        AC_DEFINE(ISC_MUTEX_ATOMICS, 1, [Define to emulate atomic variables with mutexes.])
+        ;;
+no)
+        AC_MSG_RESULT(no)
+        ;;
+*)
+        AC_MSG_ERROR("--enable-mutex-atomics requires yes or no")
+        ;;
+esac
+
 #
 # Make very sure that these are the first files processed by
 # config.status, since we use the processed output as the input for
index 8f09ecf8d9e1a10e06879c1091d4b3c9deda06c1..e75ada094b4b10394dabaf1a8ccca3fa97cb533f 100644 (file)
 
 #pragma once
 
+#ifdef ISC_MUTEX_ATOMICS
+#include <isc/mutexatomic.h>
+#else
 #if HAVE_STDATOMIC_H
 #include <stdatomic.h>
 #else
 #include <isc/stdatomic.h>
 #endif
+#endif
 
 /*
  * We define a few additional macros to make things easier
diff --git a/lib/isc/include/isc/mutexatomic.h b/lib/isc/include/isc/mutexatomic.h
new file mode 100644 (file)
index 0000000..31ecd3f
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * 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 http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#pragma once
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <isc/mutex.h>
+
+#if !defined(__has_feature)
+#define __has_feature(x) 0
+#endif
+
+#if !defined(__has_extension)
+#define __has_extension(x) __has_feature(x)
+#endif
+
+#if !defined(__GNUC_PREREQ__)
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
+#define __GNUC_PREREQ__(maj, min)                    \
+       ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+#define __GNUC_PREREQ__(maj, min) 0
+#endif
+#endif
+
+#if !defined(__CLANG_ATOMICS) && !defined(__GNUC_ATOMICS)
+#if __has_extension(c_atomic) || __has_extension(cxx_atomic)
+#define __CLANG_ATOMICS
+#elif __GNUC_PREREQ__(4, 7)
+#define __GNUC_ATOMICS
+#elif !defined(__GNUC__)
+#error "isc/stdatomic.h does not support your compiler"
+#endif
+#endif
+
+#ifndef __ATOMIC_RELAXED
+#define __ATOMIC_RELAXED        0
+#endif
+#ifndef __ATOMIC_CONSUME
+#define __ATOMIC_CONSUME        1
+#endif
+#ifndef __ATOMIC_ACQUIRE
+#define __ATOMIC_ACQUIRE        2
+#endif
+#ifndef __ATOMIC_RELEASE
+#define __ATOMIC_RELEASE        3
+#endif
+#ifndef __ATOMIC_ACQ_REL
+#define __ATOMIC_ACQ_REL        4
+#endif
+#ifndef __ATOMIC_SEQ_CST
+#define __ATOMIC_SEQ_CST        5
+#endif
+
+
+enum memory_order {
+       memory_order_relaxed = __ATOMIC_RELAXED,
+       memory_order_consume = __ATOMIC_CONSUME,
+       memory_order_acquire = __ATOMIC_ACQUIRE,
+       memory_order_release = __ATOMIC_RELEASE,
+       memory_order_acq_rel = __ATOMIC_ACQ_REL,
+       memory_order_seq_cst = __ATOMIC_SEQ_CST
+};
+
+typedef enum memory_order memory_order;
+
+typedef struct atomic_int_fast32 {
+       isc_mutex_t m;
+       int32_t v;
+} atomic_int_fast32_t;
+
+typedef struct atomic_int_fast64 {
+       isc_mutex_t m;
+       int64_t v;
+} atomic_int_fast64_t;
+
+typedef struct atomic_uint_fast32 {
+       isc_mutex_t m;
+       uint32_t v;
+} atomic_uint_fast32_t;
+
+typedef struct atomic_uint_fast64 {
+       isc_mutex_t m;
+       uint64_t v;
+} atomic_uint_fast64_t;
+
+
+typedef struct atomic_bool_s {
+       isc_mutex_t m;
+       bool v;
+} atomic_bool;
+
+
+#define atomic_init(obj, desired)              \
+       { isc_mutex_init(&(obj)->m); isc_mutex_lock(&(obj)->m); (obj)->v = desired; isc_mutex_unlock(&(obj)->m); }
+#define atomic_load_explicit(obj, order)       \
+       ({ typeof((obj)->v) __v; isc_mutex_lock(&(obj)->m); __v= (obj)->v; isc_mutex_unlock(&(obj)->m); __v;} )
+#define atomic_store_explicit(obj, desired, order)     \
+       {isc_mutex_lock(&(obj)->m); (obj)->v = desired; isc_mutex_unlock(&(obj)->m); }
+#define atomic_fetch_add_explicit(obj, arg, order)     \
+       ({ typeof((obj)->v) __v; isc_mutex_lock(&(obj)->m); __v= (obj)->v; (obj)->v += arg; isc_mutex_unlock(&(obj)->m); __v;} )
+#define atomic_fetch_sub_explicit(obj, arg, order)     \
+       ({ typeof((obj)->v) __v; isc_mutex_lock(&(obj)->m); __v= (obj)->v; (obj)->v -= arg; isc_mutex_unlock(&(obj)->m); __v;} )
+#define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, fail)    \
+       ({ bool __v; isc_mutex_lock(&(obj)->m); __v = ((obj)->v == *expected); *expected = (obj)->v; (obj)->v = __v ? desired : (obj)->v; isc_mutex_unlock(&(obj)->m); __v;} )
+#define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, fail)      \
+       ({ bool __v; isc_mutex_lock(&(obj)->m); __v = ((obj)->v == *expected); *expected = (obj)->v; (obj)->v = __v ? desired : (obj)->v; isc_mutex_unlock(&(obj)->m); __v;} )
+
+
+
+
+#define atomic_load(obj) \
+       atomic_load_explicit(obj, memory_order_seq_cst)
+#define atomic_store(obj, arg) \
+       atomic_store_explicit(obj, arg, memory_order_seq_cst)
+#define atomic_fetch_add(obj, arg) \
+       atomic_fetch_add_explicit(obj, arg, memory_order_seq_cst)
+#define atomic_fetch_sub(obj, arg) \
+       atomic_fetch_sub_explicit(obj, arg, memory_order_seq_cst)
+#define atomic_compare_exchange_strong(obj, expected, desired) \
+       atomic_compare_exchange_strong_explicit(obj, expected, desired, memory_order_seq_cst, memory_order_seq_cst)
+#define atomic_compare_exchange_weak(obj, expected, desired)   \
+       atomic_compare_exchange_weak_explicit(obj, expected, desired, memory_order_seq_cst, memory_order_seq_cst)
index abb88fbe3359634ffcbe88ce0e7ed706e73de3cf..39709bba83726a4fcccd35986fe6cd2bc468a60e 100644 (file)
@@ -5692,6 +5692,15 @@ recparam_update(ns_query_recparam_t *param, dns_rdatatype_t qtype,
                RUNTIME_CHECK(result == ISC_R_SUCCESS);
        }
 }
+static atomic_uint_fast32_t last_soft, last_hard;
+#ifdef ISC_MUTEX_ATOMICS
+static isc_once_t last_once = ISC_ONCE_INIT;
+static void last_init() {
+       atomic_init(&last_soft, 0);
+       atomic_init(&last_hard, 0);
+}
+#endif
+
 
 isc_result_t
 ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
@@ -5739,16 +5748,13 @@ ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
                }
 
                if  (result == ISC_R_SOFTQUOTA) {
-                       static atomic_uint_fast32_t last;
-                       static isc_once_t once = ISC_ONCE_INIT;
-                       void __ain() {
-                               atomic_init(&last, 0);
-                       }
-                       isc_once_do(&once, __ain);
+#ifdef ISC_MUTEX_ATOMICS
+                       isc_once_do(&last_once, last_init);
+#endif
                        isc_stdtime_t now;
                        isc_stdtime_get(&now);
-                       if (now != atomic_load_relaxed(&last)) {
-                               atomic_store_relaxed(&last, now);
+                       if (now != atomic_load_relaxed(&last_soft)) {
+                               atomic_store_relaxed(&last_soft, now);
                                ns_client_log(client, NS_LOGCATEGORY_CLIENT,
                                      NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
                                      "recursive-clients soft limit "
@@ -5761,17 +5767,14 @@ ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
                        ns_client_killoldestquery(client);
                        result = ISC_R_SUCCESS;
                } else if (result == ISC_R_QUOTA) {
-                       static atomic_uint_fast32_t last;
-                       static isc_once_t once = ISC_ONCE_INIT;
-                       void __ain() {
-                               atomic_init(&last, 0);
-                       }
-                       isc_once_do(&once, __ain);
+#ifdef ISC_MUTEX_ATOMICS
+                       isc_once_do(&last_once, last_init);
+#endif
                        isc_stdtime_t now;
                        isc_stdtime_get(&now);
-                       if (now != atomic_load_relaxed(&last)) {
+                       if (now != atomic_load_relaxed(&last_hard)) {
                                ns_server_t *sctx = client->sctx;
-                               atomic_store_relaxed(&last, now);
+                               atomic_store_relaxed(&last_hard, now);
                                ns_client_log(client, NS_LOGCATEGORY_CLIENT,
                                      NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
                                      "no more recursive clients "
index db7f895ff63b3afb650043a1c7dbc05b05aa2efc..acec1e8b939e2370ab329d48fd17df45d04441c8 100644 (file)
 ./lib/isc/include/isc/md.h                     C       2018,2019
 ./lib/isc/include/isc/mem.h                    C       1997,1998,1999,2000,2001,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2015,2016,2017,2018,2019
 ./lib/isc/include/isc/meminfo.h                        C       2015,2016,2018,2019
+./lib/isc/include/isc/mutexatomic.h            C       2019
 ./lib/isc/include/isc/mutexblock.h             C       1999,2000,2001,2004,2005,2006,2007,2016,2018,2019
 ./lib/isc/include/isc/netaddr.h                        C       1998,1999,2000,2001,2002,2004,2005,2006,2007,2009,2015,2016,2017,2018,2019
 ./lib/isc/include/isc/netscope.h               C       2002,2004,2005,2006,2007,2009,2016,2018,2019