Commit 92424e23 authored by Witold Krecicki's avatar Witold Krecicki

Special, for-tests-only, mode with atomics emulated by a mutex-locked variable...

Special, for-tests-only, mode with atomics emulated by a mutex-locked variable - useful for finding atomics congestions
parent 5aeb9978
......@@ -480,6 +480,9 @@
/* 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
......
......@@ -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
......
......@@ -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
......
......@@ -11,11 +11,15 @@
#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
......
/*
* 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)
......@@ -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 "
......
......@@ -2182,6 +2182,7 @@
./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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment