Compare commits
6 Commits
include-mu
...
wpk-mutexa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
533c68ef2c | ||
|
|
863d1acd1b | ||
|
|
424f25079b | ||
|
|
be793db16c | ||
|
|
c1793dd7ec | ||
|
|
dc76725357 |
@@ -429,6 +429,28 @@ unit:asan:sid:amd64:
|
|||||||
dependencies:
|
dependencies:
|
||||||
- asan:sid:amd64
|
- asan:sid:amd64
|
||||||
|
|
||||||
|
mutexatomics:sid:amd64:
|
||||||
|
variables:
|
||||||
|
CC: gcc
|
||||||
|
CFLAGS: "-Wall -Wextra -O2 -g -DISC_MEM_USE_INTERNAL_MALLOC=0"
|
||||||
|
EXTRA_CONFIGURE: "--with-libidn2 --enable-pthread-rwlock --enable-mutex-atomics"
|
||||||
|
<<: *debian_sid_amd64_image
|
||||||
|
<<: *build_job
|
||||||
|
|
||||||
|
system:mutexatomics:sid:amd64:
|
||||||
|
<<: *debian_sid_amd64_image
|
||||||
|
<<: *system_test_job
|
||||||
|
dependencies:
|
||||||
|
- mutexatomics:sid:amd64
|
||||||
|
|
||||||
|
unit:mutexatomics:sid:amd64:
|
||||||
|
<<: *debian_sid_amd64_image
|
||||||
|
<<: *unit_test_job
|
||||||
|
dependencies:
|
||||||
|
- mutexatomics:sid:amd64
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Jobs for Clang builds on Debian Stretch (amd64)
|
# Jobs for Clang builds on Debian Stretch (amd64)
|
||||||
|
|
||||||
clang:stretch:amd64:
|
clang:stretch:amd64:
|
||||||
|
|||||||
@@ -550,6 +550,9 @@
|
|||||||
non-blocking. */
|
non-blocking. */
|
||||||
#undef USE_FIONBIO_IOCTL
|
#undef USE_FIONBIO_IOCTL
|
||||||
|
|
||||||
|
/* define if you want to use mutex-locked atomics */
|
||||||
|
#undef USE_MUTEX_ATOMICS
|
||||||
|
|
||||||
/* define if OpenSSL is used for Public-Key Cryptography */
|
/* define if OpenSSL is used for Public-Key Cryptography */
|
||||||
#undef USE_OPENSSL
|
#undef USE_OPENSSL
|
||||||
|
|
||||||
|
|||||||
48
configure
vendored
48
configure
vendored
@@ -845,6 +845,7 @@ infodir
|
|||||||
docdir
|
docdir
|
||||||
oldincludedir
|
oldincludedir
|
||||||
includedir
|
includedir
|
||||||
|
runstatedir
|
||||||
localstatedir
|
localstatedir
|
||||||
sharedstatedir
|
sharedstatedir
|
||||||
sysconfdir
|
sysconfdir
|
||||||
@@ -901,6 +902,7 @@ with_geoip
|
|||||||
with_locktype
|
with_locktype
|
||||||
with_libtool
|
with_libtool
|
||||||
enable_pthread_rwlock
|
enable_pthread_rwlock
|
||||||
|
enable_mutex_atomics
|
||||||
with_openssl
|
with_openssl
|
||||||
enable_fips_mode
|
enable_fips_mode
|
||||||
with_cc_alg
|
with_cc_alg
|
||||||
@@ -1006,6 +1008,7 @@ datadir='${datarootdir}'
|
|||||||
sysconfdir='${prefix}/etc'
|
sysconfdir='${prefix}/etc'
|
||||||
sharedstatedir='${prefix}/com'
|
sharedstatedir='${prefix}/com'
|
||||||
localstatedir='${prefix}/var'
|
localstatedir='${prefix}/var'
|
||||||
|
runstatedir='${localstatedir}/run'
|
||||||
includedir='${prefix}/include'
|
includedir='${prefix}/include'
|
||||||
oldincludedir='/usr/include'
|
oldincludedir='/usr/include'
|
||||||
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
|
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
|
||||||
@@ -1258,6 +1261,15 @@ do
|
|||||||
| -silent | --silent | --silen | --sile | --sil)
|
| -silent | --silent | --silen | --sile | --sil)
|
||||||
silent=yes ;;
|
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)
|
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
|
||||||
ac_prev=sbindir ;;
|
ac_prev=sbindir ;;
|
||||||
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
||||||
@@ -1395,7 +1407,7 @@ fi
|
|||||||
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
||||||
datadir sysconfdir sharedstatedir localstatedir includedir \
|
datadir sysconfdir sharedstatedir localstatedir includedir \
|
||||||
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
||||||
libdir localedir mandir
|
libdir localedir mandir runstatedir
|
||||||
do
|
do
|
||||||
eval ac_val=\$$ac_var
|
eval ac_val=\$$ac_var
|
||||||
# Remove trailing slashes.
|
# Remove trailing slashes.
|
||||||
@@ -1548,6 +1560,7 @@ Fine tuning of the installation directories:
|
|||||||
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
||||||
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
||||||
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
||||||
|
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
|
||||||
--libdir=DIR object code libraries [EPREFIX/lib]
|
--libdir=DIR object code libraries [EPREFIX/lib]
|
||||||
--includedir=DIR C header files [PREFIX/include]
|
--includedir=DIR C header files [PREFIX/include]
|
||||||
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
||||||
@@ -1602,6 +1615,8 @@ Optional Features:
|
|||||||
--enable-devpoll use /dev/poll when available [default=yes]
|
--enable-devpoll use /dev/poll when available [default=yes]
|
||||||
--enable-pthread-rwlock use pthread rwlock instead of internal rwlock
|
--enable-pthread-rwlock use pthread rwlock instead of internal rwlock
|
||||||
implementation (EXPERIMENTAL)
|
implementation (EXPERIMENTAL)
|
||||||
|
--enable-mutex-atomics use mutex-locked variables instead of atomics
|
||||||
|
(EXPERIMENTAL)
|
||||||
--enable-fips-mode enable FIPS mode in OpenSSL library [default=no]
|
--enable-fips-mode enable FIPS mode in OpenSSL library [default=no]
|
||||||
--enable-native-pkcs11 use native PKCS11 for public-key crypto [default=no]
|
--enable-native-pkcs11 use native PKCS11 for public-key crypto [default=no]
|
||||||
--enable-backtrace log stack backtrace on abort [default=yes]
|
--enable-backtrace log stack backtrace on abort [default=yes]
|
||||||
@@ -3942,7 +3957,7 @@ else
|
|||||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||||
since some C++ compilers masquerading as C compilers
|
since some C++ compilers masquerading as C compilers
|
||||||
incorrectly reject 9223372036854775807. */
|
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
|
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||||
&& LARGE_OFF_T % 2147483647 == 1)
|
&& LARGE_OFF_T % 2147483647 == 1)
|
||||||
? 1 : -1];
|
? 1 : -1];
|
||||||
@@ -3988,7 +4003,7 @@ else
|
|||||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||||
since some C++ compilers masquerading as C compilers
|
since some C++ compilers masquerading as C compilers
|
||||||
incorrectly reject 9223372036854775807. */
|
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
|
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||||
&& LARGE_OFF_T % 2147483647 == 1)
|
&& LARGE_OFF_T % 2147483647 == 1)
|
||||||
? 1 : -1];
|
? 1 : -1];
|
||||||
@@ -4012,7 +4027,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
|||||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||||
since some C++ compilers masquerading as C compilers
|
since some C++ compilers masquerading as C compilers
|
||||||
incorrectly reject 9223372036854775807. */
|
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
|
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||||
&& LARGE_OFF_T % 2147483647 == 1)
|
&& LARGE_OFF_T % 2147483647 == 1)
|
||||||
? 1 : -1];
|
? 1 : -1];
|
||||||
@@ -4057,7 +4072,7 @@ else
|
|||||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||||
since some C++ compilers masquerading as C compilers
|
since some C++ compilers masquerading as C compilers
|
||||||
incorrectly reject 9223372036854775807. */
|
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
|
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||||
&& LARGE_OFF_T % 2147483647 == 1)
|
&& LARGE_OFF_T % 2147483647 == 1)
|
||||||
? 1 : -1];
|
? 1 : -1];
|
||||||
@@ -4081,7 +4096,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
|||||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||||
since some C++ compilers masquerading as C compilers
|
since some C++ compilers masquerading as C compilers
|
||||||
incorrectly reject 9223372036854775807. */
|
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
|
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||||
&& LARGE_OFF_T % 2147483647 == 1)
|
&& LARGE_OFF_T % 2147483647 == 1)
|
||||||
? 1 : -1];
|
? 1 : -1];
|
||||||
@@ -15653,6 +15668,27 @@ if test "$enable_pthread_rwlock" = "yes" -a "$enable_developer" != "yes"; then :
|
|||||||
as_fn_error $? "pthread rwlock is not meant used in production and the developer mode must be enabled" "$LINENO" 5
|
as_fn_error $? "pthread rwlock is not meant used in production and the developer mode must be enabled" "$LINENO" 5
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# Do we want to emulate atomics with mutex-locked variables? (useful for debugging)
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
|
||||||
|
|
||||||
|
if test "$enable_mutex_atomics" = "yes"; then :
|
||||||
|
|
||||||
|
$as_echo "#define USE_MUTEX_ATOMICS 1" >>confdefs.h
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$enable_mutex_atomics" = "yes" -a "$enable_developer" != "yes"; then :
|
||||||
|
as_fn_error $? "mutex atomics are not meant used in production and the developer mode must be enabled" "$LINENO" 5
|
||||||
|
fi
|
||||||
|
|
||||||
CRYPTO=OpenSSL
|
CRYPTO=OpenSSL
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|||||||
14
configure.ac
14
configure.ac
@@ -750,6 +750,20 @@ AS_IF([test "$enable_pthread_rwlock" = "yes"],
|
|||||||
AS_IF([test "$enable_pthread_rwlock" = "yes" -a "$enable_developer" != "yes"],
|
AS_IF([test "$enable_pthread_rwlock" = "yes" -a "$enable_developer" != "yes"],
|
||||||
[AC_MSG_ERROR([pthread rwlock is not meant used in production and the developer mode must be enabled])])
|
[AC_MSG_ERROR([pthread rwlock is not meant used in production and the developer mode must be enabled])])
|
||||||
|
|
||||||
|
#
|
||||||
|
# Do we want to emulate atomics with mutex-locked variables? (useful for debugging)
|
||||||
|
#
|
||||||
|
AC_ARG_ENABLE([mutex_atomics],
|
||||||
|
[AS_HELP_STRING([--enable-mutex-atomics],
|
||||||
|
[use mutex-locked variables instead of atomics (EXPERIMENTAL)])],
|
||||||
|
[], [enable_mutex_atomics=no])
|
||||||
|
|
||||||
|
AS_IF([test "$enable_mutex_atomics" = "yes"],
|
||||||
|
[AC_DEFINE([USE_MUTEX_ATOMICS], [1], [define if you want to use mutex-locked atomics])])
|
||||||
|
|
||||||
|
AS_IF([test "$enable_mutex_atomics" = "yes" -a "$enable_developer" != "yes"],
|
||||||
|
[AC_MSG_ERROR([mutex atomics are not meant used in production and the developer mode must be enabled])])
|
||||||
|
|
||||||
CRYPTO=OpenSSL
|
CRYPTO=OpenSSL
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -44,9 +44,9 @@ isc_counter_create(isc_mem_t *mctx, int limit, isc_counter_t **counterp) {
|
|||||||
counter->mctx = NULL;
|
counter->mctx = NULL;
|
||||||
isc_mem_attach(mctx, &counter->mctx);
|
isc_mem_attach(mctx, &counter->mctx);
|
||||||
|
|
||||||
atomic_store(&counter->references, 1);
|
atomic_init(&counter->references, 1);
|
||||||
atomic_store(&counter->limit, limit);
|
atomic_init(&counter->limit, limit);
|
||||||
atomic_store(&counter->used, 0);
|
atomic_init(&counter->used, 0);
|
||||||
|
|
||||||
counter->magic = COUNTER_MAGIC;
|
counter->magic = COUNTER_MAGIC;
|
||||||
*counterp = counter;
|
*counterp = counter;
|
||||||
|
|||||||
@@ -11,12 +11,15 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef USE_MUTEX_ATOMICS
|
||||||
|
#include <isc/mutexatomic.h>
|
||||||
|
#else
|
||||||
#if HAVE_STDATOMIC_H
|
#if HAVE_STDATOMIC_H
|
||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
#else
|
#else
|
||||||
#include <isc/stdatomic.h>
|
#include <isc/stdatomic.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* We define a few additional macros to make things easier
|
* We define a few additional macros to make things easier
|
||||||
*/
|
*/
|
||||||
|
|||||||
178
lib/isc/include/isc/mutexatomic.h
Normal file
178
lib/isc/include/isc/mutexatomic.h
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
* 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>
|
||||||
|
#include <isc/rwlock.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_rwlock_t m;
|
||||||
|
int32_t v;
|
||||||
|
} atomic_int_fast32_t;
|
||||||
|
|
||||||
|
typedef struct atomic_int_fast64 {
|
||||||
|
isc_rwlock_t m;
|
||||||
|
int64_t v;
|
||||||
|
} atomic_int_fast64_t;
|
||||||
|
|
||||||
|
typedef struct atomic_uint_fast32 {
|
||||||
|
isc_rwlock_t m;
|
||||||
|
uint32_t v;
|
||||||
|
} atomic_uint_fast32_t;
|
||||||
|
|
||||||
|
typedef struct atomic_uint_fast64 {
|
||||||
|
isc_rwlock_t m;
|
||||||
|
uint64_t v;
|
||||||
|
} atomic_uint_fast64_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct atomic_bool_s {
|
||||||
|
isc_rwlock_t m;
|
||||||
|
bool v;
|
||||||
|
} atomic_bool;
|
||||||
|
|
||||||
|
|
||||||
|
#define atomic_init(obj, desired) \
|
||||||
|
{ \
|
||||||
|
isc_rwlock_init(&(obj)->m, 0, 0); \
|
||||||
|
isc_rwlock_lock(&(obj)->m, isc_rwlocktype_write); \
|
||||||
|
(obj)->v = desired; \
|
||||||
|
isc_rwlock_unlock(&(obj)->m, isc_rwlocktype_write); \
|
||||||
|
}
|
||||||
|
#define atomic_load_explicit(obj, order) \
|
||||||
|
({ \
|
||||||
|
typeof((obj)->v) __v; \
|
||||||
|
isc_rwlock_lock(&(obj)->m, isc_rwlocktype_read); \
|
||||||
|
__v= (obj)->v; \
|
||||||
|
isc_rwlock_unlock(&(obj)->m, isc_rwlocktype_read); \
|
||||||
|
__v; \
|
||||||
|
})
|
||||||
|
#define atomic_store_explicit(obj, desired, order) \
|
||||||
|
{ \
|
||||||
|
isc_rwlock_lock(&(obj)->m, isc_rwlocktype_write); \
|
||||||
|
(obj)->v = desired; \
|
||||||
|
isc_rwlock_unlock(&(obj)->m, isc_rwlocktype_write); \
|
||||||
|
}
|
||||||
|
#define atomic_fetch_add_explicit(obj, arg, order) \
|
||||||
|
({ \
|
||||||
|
typeof((obj)->v) __v; \
|
||||||
|
isc_rwlock_lock(&(obj)->m, isc_rwlocktype_write); \
|
||||||
|
__v= (obj)->v; \
|
||||||
|
(obj)->v += arg; \
|
||||||
|
isc_rwlock_unlock(&(obj)->m, isc_rwlocktype_write); \
|
||||||
|
__v; \
|
||||||
|
})
|
||||||
|
#define atomic_fetch_sub_explicit(obj, arg, order) \
|
||||||
|
({ \
|
||||||
|
typeof((obj)->v) __v; \
|
||||||
|
isc_rwlock_lock(&(obj)->m, isc_rwlocktype_write); \
|
||||||
|
__v= (obj)->v; \
|
||||||
|
(obj)->v -= arg; \
|
||||||
|
isc_rwlock_unlock(&(obj)->m, isc_rwlocktype_write); \
|
||||||
|
__v; \
|
||||||
|
})
|
||||||
|
#define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, fail) \
|
||||||
|
({ \
|
||||||
|
bool __v; \
|
||||||
|
isc_rwlock_lock(&(obj)->m, isc_rwlocktype_write); \
|
||||||
|
__v = ((obj)->v == *expected); \
|
||||||
|
*expected = (obj)->v; \
|
||||||
|
(obj)->v = __v ? desired : (obj)->v; \
|
||||||
|
isc_rwlock_unlock(&(obj)->m, isc_rwlocktype_write); \
|
||||||
|
__v; \
|
||||||
|
})
|
||||||
|
#define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, fail) \
|
||||||
|
({ \
|
||||||
|
bool __v; \
|
||||||
|
isc_rwlock_lock(&(obj)->m, isc_rwlocktype_write); \
|
||||||
|
__v = ((obj)->v == *expected); \
|
||||||
|
*expected = (obj)->v; \
|
||||||
|
(obj)->v = __v ? desired : (obj)->v; \
|
||||||
|
isc_rwlock_unlock(&(obj)->m, isc_rwlocktype_write); \
|
||||||
|
__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)
|
||||||
@@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
/*! \file isc/rwlock.h */
|
/*! \file isc/rwlock.h */
|
||||||
|
|
||||||
#include <isc/atomic.h>
|
|
||||||
#include <isc/condition.h>
|
#include <isc/condition.h>
|
||||||
#include <isc/lang.h>
|
#include <isc/lang.h>
|
||||||
#include <isc/platform.h>
|
#include <isc/platform.h>
|
||||||
@@ -36,10 +35,15 @@ typedef enum {
|
|||||||
|
|
||||||
struct isc_rwlock {
|
struct isc_rwlock {
|
||||||
pthread_rwlock_t rwlock;
|
pthread_rwlock_t rwlock;
|
||||||
atomic_bool downgrade;
|
/*
|
||||||
|
* We need to use bool volatile to avoid
|
||||||
|
* chicken-and-egg problem with mutex atomics.
|
||||||
|
*/
|
||||||
|
bool volatile downgrade;
|
||||||
};
|
};
|
||||||
|
|
||||||
#else /* USE_PTHREAD_RWLOCK */
|
#else /* USE_PTHREAD_RWLOCK */
|
||||||
|
#include <isc/atomic.h>
|
||||||
|
|
||||||
struct isc_rwlock {
|
struct isc_rwlock {
|
||||||
/* Unlocked. */
|
/* Unlocked. */
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
#include <synch.h> /* for smt_pause(3c) */
|
#include <synch.h> /* for smt_pause(3c) */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <isc/atomic.h>
|
|
||||||
#include <isc/magic.h>
|
#include <isc/magic.h>
|
||||||
#include <isc/platform.h>
|
#include <isc/platform.h>
|
||||||
#include <isc/print.h>
|
#include <isc/print.h>
|
||||||
@@ -31,7 +30,7 @@
|
|||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <stdatomic.h>
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
|
isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
|
||||||
unsigned int write_quota)
|
unsigned int write_quota)
|
||||||
@@ -53,10 +52,12 @@ isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
while (true) {
|
while (true) {
|
||||||
REQUIRE(pthread_rwlock_wrlock(&rwl->rwlock) == 0);
|
REQUIRE(pthread_rwlock_wrlock(&rwl->rwlock) == 0);
|
||||||
/* Unlock if in middle of downgrade operation */
|
/* Unlock if in middle of downgrade operation */
|
||||||
if (atomic_load_acquire(&rwl->downgrade)) {
|
if (atomic_load_explicit(&rwl->downgrade,
|
||||||
|
memory_order_acquire)) {
|
||||||
REQUIRE(pthread_rwlock_unlock(&rwl->rwlock)
|
REQUIRE(pthread_rwlock_unlock(&rwl->rwlock)
|
||||||
== 0);
|
== 0);
|
||||||
while (atomic_load_acquire(&rwl->downgrade));
|
while (atomic_load_explicit(&rwl->downgrade,
|
||||||
|
memory_order_acquire));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -78,7 +79,9 @@ isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
|||||||
break;
|
break;
|
||||||
case isc_rwlocktype_write:
|
case isc_rwlocktype_write:
|
||||||
ret = pthread_rwlock_trywrlock(&rwl->rwlock);
|
ret = pthread_rwlock_trywrlock(&rwl->rwlock);
|
||||||
if ((ret == 0) && atomic_load_acquire(&rwl->downgrade)) {
|
if ((ret == 0) &&
|
||||||
|
atomic_load_explicit(&rwl->downgrade,
|
||||||
|
memory_order_acquire)) {
|
||||||
isc_rwlock_unlock(rwl, type);
|
isc_rwlock_unlock(rwl, type);
|
||||||
return (ISC_R_LOCKBUSY);
|
return (ISC_R_LOCKBUSY);
|
||||||
}
|
}
|
||||||
@@ -110,10 +113,10 @@ isc_rwlock_tryupgrade(isc_rwlock_t *rwl) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
isc_rwlock_downgrade(isc_rwlock_t *rwl) {
|
isc_rwlock_downgrade(isc_rwlock_t *rwl) {
|
||||||
atomic_store_release(&rwl->downgrade, true);
|
atomic_store_explicit(&rwl->downgrade, true, memory_order_release);
|
||||||
isc_rwlock_unlock(rwl, isc_rwlocktype_write);
|
isc_rwlock_unlock(rwl, isc_rwlocktype_write);
|
||||||
isc_rwlock_lock(rwl, isc_rwlocktype_read);
|
isc_rwlock_lock(rwl, isc_rwlocktype_read);
|
||||||
atomic_store_release(&rwl->downgrade, false);
|
atomic_store_explicit(&rwl->downgrade, false, memory_order_release);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -122,6 +125,7 @@ isc_rwlock_destroy(isc_rwlock_t *rwl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
#include <isc/atomic.h>
|
||||||
|
|
||||||
#define RWLOCK_MAGIC ISC_MAGIC('R', 'W', 'L', 'k')
|
#define RWLOCK_MAGIC ISC_MAGIC('R', 'W', 'L', 'k')
|
||||||
#define VALID_RWLOCK(rwl) ISC_MAGIC_VALID(rwl, RWLOCK_MAGIC)
|
#define VALID_RWLOCK(rwl) ISC_MAGIC_VALID(rwl, RWLOCK_MAGIC)
|
||||||
|
|||||||
@@ -1237,7 +1237,7 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) {
|
|||||||
* we're stuck. Automatically drop privileges at that
|
* we're stuck. Automatically drop privileges at that
|
||||||
* point and continue with the regular ready queue.
|
* point and continue with the regular ready queue.
|
||||||
*/
|
*/
|
||||||
if (manager->mode != isc_taskmgrmode_normal &&
|
if (atomic_load_relaxed(&manager->mode) != isc_taskmgrmode_normal &&
|
||||||
atomic_load_explicit(&manager->tasks_running,
|
atomic_load_explicit(&manager->tasks_running,
|
||||||
memory_order_acquire) == 0)
|
memory_order_acquire) == 0)
|
||||||
{
|
{
|
||||||
@@ -1250,7 +1250,7 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) {
|
|||||||
* we'll end up in a deadlock over queue locks.
|
* we'll end up in a deadlock over queue locks.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
if (manager->mode != isc_taskmgrmode_normal &&
|
if (atomic_load_relaxed(&manager->mode) != isc_taskmgrmode_normal &&
|
||||||
atomic_load_explicit(&manager->tasks_running,
|
atomic_load_explicit(&manager->tasks_running,
|
||||||
memory_order_acquire) == 0)
|
memory_order_acquire) == 0)
|
||||||
{
|
{
|
||||||
@@ -1335,7 +1335,7 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
|
|||||||
RUNTIME_CHECK(manager != NULL);
|
RUNTIME_CHECK(manager != NULL);
|
||||||
manager->common.impmagic = TASK_MANAGER_MAGIC;
|
manager->common.impmagic = TASK_MANAGER_MAGIC;
|
||||||
manager->common.magic = ISCAPI_TASKMGR_MAGIC;
|
manager->common.magic = ISCAPI_TASKMGR_MAGIC;
|
||||||
atomic_store(&manager->mode, isc_taskmgrmode_normal);
|
atomic_init(&manager->mode, isc_taskmgrmode_normal);
|
||||||
manager->mctx = NULL;
|
manager->mctx = NULL;
|
||||||
isc_mutex_init(&manager->lock);
|
isc_mutex_init(&manager->lock);
|
||||||
isc_mutex_init(&manager->excl_lock);
|
isc_mutex_init(&manager->excl_lock);
|
||||||
@@ -1350,18 +1350,18 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
|
|||||||
}
|
}
|
||||||
manager->default_quantum = default_quantum;
|
manager->default_quantum = default_quantum;
|
||||||
INIT_LIST(manager->tasks);
|
INIT_LIST(manager->tasks);
|
||||||
atomic_store(&manager->tasks_count, 0);
|
atomic_init(&manager->tasks_count, 0);
|
||||||
manager->queues = isc_mem_get(mctx, workers * sizeof(isc__taskqueue_t));
|
manager->queues = isc_mem_get(mctx, workers * sizeof(isc__taskqueue_t));
|
||||||
RUNTIME_CHECK(manager->queues != NULL);
|
RUNTIME_CHECK(manager->queues != NULL);
|
||||||
|
|
||||||
manager->tasks_running = 0;
|
atomic_init(&manager->tasks_running, 0);
|
||||||
manager->tasks_ready = 0;
|
atomic_init(&manager->tasks_ready, 0);
|
||||||
manager->curq = 0;
|
atomic_init(&manager->curq, 0);
|
||||||
manager->exiting = false;
|
atomic_init(&manager->exiting, false);
|
||||||
manager->excl = NULL;
|
manager->excl = NULL;
|
||||||
manager->halted = 0;
|
manager->halted = 0;
|
||||||
atomic_store_relaxed(&manager->exclusive_req, false);
|
atomic_init(&manager->exclusive_req, false);
|
||||||
atomic_store_relaxed(&manager->pause_req, false);
|
atomic_init(&manager->pause_req, false);
|
||||||
|
|
||||||
isc_mem_attach(mctx, &manager->mctx);
|
isc_mem_attach(mctx, &manager->mctx);
|
||||||
|
|
||||||
@@ -1523,8 +1523,8 @@ void
|
|||||||
isc__taskmgr_resume(isc_taskmgr_t *manager0) {
|
isc__taskmgr_resume(isc_taskmgr_t *manager0) {
|
||||||
isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
|
isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
|
||||||
LOCK(&manager->halt_lock);
|
LOCK(&manager->halt_lock);
|
||||||
if (manager->pause_req) {
|
if (atomic_load_relaxed(&manager->pause_req)) {
|
||||||
manager->pause_req = false;
|
atomic_store_relaxed(&manager->pause_req, false);
|
||||||
while (manager->halted > 0) {
|
while (manager->halted > 0) {
|
||||||
BROADCAST(&manager->halt_cond);
|
BROADCAST(&manager->halt_cond);
|
||||||
WAIT(&manager->halt_cond, &manager->halt_lock);
|
WAIT(&manager->halt_cond, &manager->halt_lock);
|
||||||
|
|||||||
@@ -422,8 +422,8 @@ isc_app_finish(void) {
|
|||||||
void
|
void
|
||||||
isc_app_block(void) {
|
isc_app_block(void) {
|
||||||
sigset_t sset;
|
sigset_t sset;
|
||||||
REQUIRE(isc_g_appctx.running);
|
REQUIRE(atomic_load_relaxed(&isc_g_appctx.running));
|
||||||
REQUIRE(!isc_g_appctx.blocked);
|
REQUIRE(!atomic_load_relaxed(&isc_g_appctx.blocked));
|
||||||
|
|
||||||
atomic_store_release(&isc_g_appctx.blocked, true);
|
atomic_store_release(&isc_g_appctx.blocked, true);
|
||||||
blockedthread = pthread_self();
|
blockedthread = pthread_self();
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include <isc/string.h>
|
#include <isc/string.h>
|
||||||
#include <isc/thread.h>
|
#include <isc/thread.h>
|
||||||
#include <isc/util.h>
|
#include <isc/util.h>
|
||||||
|
#include <isc/once.h>
|
||||||
|
|
||||||
#include <dns/adb.h>
|
#include <dns/adb.h>
|
||||||
#include <dns/badcache.h>
|
#include <dns/badcache.h>
|
||||||
@@ -5680,6 +5681,41 @@ recparam_update(ns_query_recparam_t *param, dns_rdatatype_t qtype,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static atomic_uint_fast32_t last_soft, last_hard;
|
||||||
|
static isc_once_t last_initialized = ISC_ONCE_INIT;
|
||||||
|
static void
|
||||||
|
last_init(void) {
|
||||||
|
atomic_init(&last_soft, 0);
|
||||||
|
atomic_init(&last_hard, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
can_log_quota(isc_result_t which) {
|
||||||
|
atomic_uint_fast32_t *last;
|
||||||
|
isc_stdtime_t now;
|
||||||
|
|
||||||
|
isc_once_do(&last_initialized, last_init);
|
||||||
|
|
||||||
|
switch (which) {
|
||||||
|
case ISC_R_SOFTQUOTA:
|
||||||
|
last = &last_soft;
|
||||||
|
break;
|
||||||
|
case ISC_R_QUOTA:
|
||||||
|
last = &last_hard;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
INSIST(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
isc_stdtime_get(&now);
|
||||||
|
if (now != atomic_load_relaxed(last)) {
|
||||||
|
atomic_store_relaxed(last, now);
|
||||||
|
return (true);
|
||||||
|
} else {
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
|
ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
|
||||||
dns_name_t *qdomain, dns_rdataset_t *nameservers,
|
dns_name_t *qdomain, dns_rdataset_t *nameservers,
|
||||||
@@ -5725,11 +5761,7 @@ ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
|
|||||||
ns_statscounter_recursclients);
|
ns_statscounter_recursclients);
|
||||||
|
|
||||||
if (result == ISC_R_SOFTQUOTA) {
|
if (result == ISC_R_SOFTQUOTA) {
|
||||||
static atomic_uint_fast32_t last = 0;
|
if (can_log_quota(result)) {
|
||||||
isc_stdtime_t now;
|
|
||||||
isc_stdtime_get(&now);
|
|
||||||
if (now != atomic_load_relaxed(&last)) {
|
|
||||||
atomic_store_relaxed(&last, now);
|
|
||||||
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
|
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
|
||||||
NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
|
NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
|
||||||
"recursive-clients soft limit "
|
"recursive-clients soft limit "
|
||||||
@@ -5742,12 +5774,8 @@ ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
|
|||||||
ns_client_killoldestquery(client);
|
ns_client_killoldestquery(client);
|
||||||
result = ISC_R_SUCCESS;
|
result = ISC_R_SUCCESS;
|
||||||
} else if (result == ISC_R_QUOTA) {
|
} else if (result == ISC_R_QUOTA) {
|
||||||
static atomic_uint_fast32_t last = 0;
|
if (can_log_quota(result)) {
|
||||||
isc_stdtime_t now;
|
|
||||||
isc_stdtime_get(&now);
|
|
||||||
if (now != atomic_load_relaxed(&last)) {
|
|
||||||
ns_server_t *sctx = client->sctx;
|
ns_server_t *sctx = client->sctx;
|
||||||
atomic_store_relaxed(&last, now);
|
|
||||||
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
|
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
|
||||||
NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
|
NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
|
||||||
"no more recursive clients "
|
"no more recursive clients "
|
||||||
|
|||||||
@@ -2189,6 +2189,7 @@
|
|||||||
./lib/isc/include/isc/md.h C 2018,2019
|
./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/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/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/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/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
|
./lib/isc/include/isc/netscope.h C 2002,2004,2005,2006,2007,2009,2016,2018,2019
|
||||||
|
|||||||
Reference in New Issue
Block a user