Compare commits
6 Commits
v9.18.20
...
wpk-mutexa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
533c68ef2c | ||
|
|
863d1acd1b | ||
|
|
424f25079b | ||
|
|
be793db16c | ||
|
|
c1793dd7ec | ||
|
|
dc76725357 |
@@ -429,6 +429,28 @@ unit:asan:sid:amd64:
|
||||
dependencies:
|
||||
- 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)
|
||||
|
||||
clang:stretch:amd64:
|
||||
|
||||
@@ -550,6 +550,9 @@
|
||||
non-blocking. */
|
||||
#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 */
|
||||
#undef USE_OPENSSL
|
||||
|
||||
|
||||
48
configure
vendored
48
configure
vendored
@@ -845,6 +845,7 @@ infodir
|
||||
docdir
|
||||
oldincludedir
|
||||
includedir
|
||||
runstatedir
|
||||
localstatedir
|
||||
sharedstatedir
|
||||
sysconfdir
|
||||
@@ -901,6 +902,7 @@ with_geoip
|
||||
with_locktype
|
||||
with_libtool
|
||||
enable_pthread_rwlock
|
||||
enable_mutex_atomics
|
||||
with_openssl
|
||||
enable_fips_mode
|
||||
with_cc_alg
|
||||
@@ -1006,6 +1008,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}'
|
||||
@@ -1258,6 +1261,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=* \
|
||||
@@ -1395,7 +1407,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.
|
||||
@@ -1548,6 +1560,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]
|
||||
@@ -1602,6 +1615,8 @@ Optional Features:
|
||||
--enable-devpoll use /dev/poll when available [default=yes]
|
||||
--enable-pthread-rwlock use pthread rwlock instead of internal rwlock
|
||||
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-native-pkcs11 use native PKCS11 for public-key crypto [default=no]
|
||||
--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,
|
||||
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];
|
||||
@@ -3988,7 +4003,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];
|
||||
@@ -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,
|
||||
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];
|
||||
@@ -4057,7 +4072,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];
|
||||
@@ -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,
|
||||
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];
|
||||
@@ -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
|
||||
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
|
||||
|
||||
#
|
||||
|
||||
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"],
|
||||
[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
|
||||
|
||||
#
|
||||
|
||||
@@ -44,9 +44,9 @@ isc_counter_create(isc_mem_t *mctx, int limit, isc_counter_t **counterp) {
|
||||
counter->mctx = NULL;
|
||||
isc_mem_attach(mctx, &counter->mctx);
|
||||
|
||||
atomic_store(&counter->references, 1);
|
||||
atomic_store(&counter->limit, limit);
|
||||
atomic_store(&counter->used, 0);
|
||||
atomic_init(&counter->references, 1);
|
||||
atomic_init(&counter->limit, limit);
|
||||
atomic_init(&counter->used, 0);
|
||||
|
||||
counter->magic = COUNTER_MAGIC;
|
||||
*counterp = counter;
|
||||
|
||||
@@ -11,12 +11,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef USE_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
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
#include <isc/atomic.h>
|
||||
#include <isc/condition.h>
|
||||
#include <isc/lang.h>
|
||||
#include <isc/platform.h>
|
||||
@@ -36,10 +35,15 @@ typedef enum {
|
||||
|
||||
struct isc_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 */
|
||||
#include <isc/atomic.h>
|
||||
|
||||
struct isc_rwlock {
|
||||
/* Unlocked. */
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include <synch.h> /* for smt_pause(3c) */
|
||||
#endif
|
||||
|
||||
#include <isc/atomic.h>
|
||||
#include <isc/magic.h>
|
||||
#include <isc/platform.h>
|
||||
#include <isc/print.h>
|
||||
@@ -31,7 +30,7 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <stdatomic.h>
|
||||
isc_result_t
|
||||
isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
|
||||
unsigned int write_quota)
|
||||
@@ -53,10 +52,12 @@ isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
||||
while (true) {
|
||||
REQUIRE(pthread_rwlock_wrlock(&rwl->rwlock) == 0);
|
||||
/* 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)
|
||||
== 0);
|
||||
while (atomic_load_acquire(&rwl->downgrade));
|
||||
while (atomic_load_explicit(&rwl->downgrade,
|
||||
memory_order_acquire));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
@@ -78,7 +79,9 @@ isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
|
||||
break;
|
||||
case isc_rwlocktype_write:
|
||||
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);
|
||||
return (ISC_R_LOCKBUSY);
|
||||
}
|
||||
@@ -110,10 +113,10 @@ isc_rwlock_tryupgrade(isc_rwlock_t *rwl) {
|
||||
|
||||
void
|
||||
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_lock(rwl, isc_rwlocktype_read);
|
||||
atomic_store_release(&rwl->downgrade, false);
|
||||
atomic_store_explicit(&rwl->downgrade, false, memory_order_release);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -122,6 +125,7 @@ isc_rwlock_destroy(isc_rwlock_t *rwl) {
|
||||
}
|
||||
|
||||
#else
|
||||
#include <isc/atomic.h>
|
||||
|
||||
#define RWLOCK_MAGIC ISC_MAGIC('R', 'W', 'L', 'k')
|
||||
#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
|
||||
* 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,
|
||||
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.
|
||||
*
|
||||
*/
|
||||
if (manager->mode != isc_taskmgrmode_normal &&
|
||||
if (atomic_load_relaxed(&manager->mode) != isc_taskmgrmode_normal &&
|
||||
atomic_load_explicit(&manager->tasks_running,
|
||||
memory_order_acquire) == 0)
|
||||
{
|
||||
@@ -1335,7 +1335,7 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
|
||||
RUNTIME_CHECK(manager != NULL);
|
||||
manager->common.impmagic = TASK_MANAGER_MAGIC;
|
||||
manager->common.magic = ISCAPI_TASKMGR_MAGIC;
|
||||
atomic_store(&manager->mode, isc_taskmgrmode_normal);
|
||||
atomic_init(&manager->mode, isc_taskmgrmode_normal);
|
||||
manager->mctx = NULL;
|
||||
isc_mutex_init(&manager->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;
|
||||
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));
|
||||
RUNTIME_CHECK(manager->queues != NULL);
|
||||
|
||||
manager->tasks_running = 0;
|
||||
manager->tasks_ready = 0;
|
||||
manager->curq = 0;
|
||||
manager->exiting = false;
|
||||
atomic_init(&manager->tasks_running, 0);
|
||||
atomic_init(&manager->tasks_ready, 0);
|
||||
atomic_init(&manager->curq, 0);
|
||||
atomic_init(&manager->exiting, false);
|
||||
manager->excl = NULL;
|
||||
manager->halted = 0;
|
||||
atomic_store_relaxed(&manager->exclusive_req, false);
|
||||
atomic_store_relaxed(&manager->pause_req, false);
|
||||
atomic_init(&manager->exclusive_req, false);
|
||||
atomic_init(&manager->pause_req, false);
|
||||
|
||||
isc_mem_attach(mctx, &manager->mctx);
|
||||
|
||||
@@ -1523,8 +1523,8 @@ void
|
||||
isc__taskmgr_resume(isc_taskmgr_t *manager0) {
|
||||
isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0;
|
||||
LOCK(&manager->halt_lock);
|
||||
if (manager->pause_req) {
|
||||
manager->pause_req = false;
|
||||
if (atomic_load_relaxed(&manager->pause_req)) {
|
||||
atomic_store_relaxed(&manager->pause_req, false);
|
||||
while (manager->halted > 0) {
|
||||
BROADCAST(&manager->halt_cond);
|
||||
WAIT(&manager->halt_cond, &manager->halt_lock);
|
||||
|
||||
@@ -422,8 +422,8 @@ isc_app_finish(void) {
|
||||
void
|
||||
isc_app_block(void) {
|
||||
sigset_t sset;
|
||||
REQUIRE(isc_g_appctx.running);
|
||||
REQUIRE(!isc_g_appctx.blocked);
|
||||
REQUIRE(atomic_load_relaxed(&isc_g_appctx.running));
|
||||
REQUIRE(!atomic_load_relaxed(&isc_g_appctx.blocked));
|
||||
|
||||
atomic_store_release(&isc_g_appctx.blocked, true);
|
||||
blockedthread = pthread_self();
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <isc/string.h>
|
||||
#include <isc/thread.h>
|
||||
#include <isc/util.h>
|
||||
#include <isc/once.h>
|
||||
|
||||
#include <dns/adb.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
|
||||
ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
|
||||
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);
|
||||
|
||||
if (result == ISC_R_SOFTQUOTA) {
|
||||
static atomic_uint_fast32_t last = 0;
|
||||
isc_stdtime_t now;
|
||||
isc_stdtime_get(&now);
|
||||
if (now != atomic_load_relaxed(&last)) {
|
||||
atomic_store_relaxed(&last, now);
|
||||
if (can_log_quota(result)) {
|
||||
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
|
||||
NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
|
||||
"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);
|
||||
result = ISC_R_SUCCESS;
|
||||
} else if (result == ISC_R_QUOTA) {
|
||||
static atomic_uint_fast32_t last = 0;
|
||||
isc_stdtime_t now;
|
||||
isc_stdtime_get(&now);
|
||||
if (now != atomic_load_relaxed(&last)) {
|
||||
if (can_log_quota(result)) {
|
||||
ns_server_t *sctx = client->sctx;
|
||||
atomic_store_relaxed(&last, now);
|
||||
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
|
||||
NS_LOGMODULE_QUERY, ISC_LOG_WARNING,
|
||||
"no more recursive clients "
|
||||
|
||||
@@ -2189,6 +2189,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
|
||||
|
||||
Reference in New Issue
Block a user