Commit 6034664e authored by Ondřej Surý's avatar Ondřej Surý
Browse files

Merge branch '10-use-atomic_builtins' into 'master'

Resolve "Use and require atomic primitives support"

Closes #10

See merge request !657
parents 7ab9c9db ddaa853e
Pipeline #4278 passed with stages
in 13 minutes and 5 seconds
5024. [func] Replace custom assembly for atomic operations with
atomic support from the compiler. The code will now use
C11 stdatomic, or __atomic, or __sync builtins with GCC
or Clang compilers, and Interlocked functions with MSVC.
[GL #10]
5023. [cleanup] Remove wrappers that try to fix broken or incomplete
implementations of IPv6, pthreads and other core
functionality required and used by BIND. [GL #192]
......
......@@ -9143,7 +9143,6 @@ view_loaded(void *arg) {
ns_zoneload_t *zl = (ns_zoneload_t *) arg;
named_server_t *server = zl->server;
bool reconfig = zl->reconfig;
unsigned int refs;
/*
......@@ -9154,34 +9153,33 @@ view_loaded(void *arg) {
* We use the zoneload reference counter to let us
* know when all views are finished.
*/
isc_refcount_decrement(&zl->refs, &refs);
if (refs != 0)
return (ISC_R_SUCCESS);
if (isc_refcount_decrement(&zl->refs) == 1) {
isc_refcount_destroy(&zl->refs);
isc_mem_put(server->mctx, zl, sizeof (*zl));
isc_refcount_destroy(&zl->refs);
isc_mem_put(server->mctx, zl, sizeof (*zl));
/*
* To maintain compatibility with log parsing tools that might
* be looking for this string after "rndc reconfig", we keep it
* as it is
*/
if (reconfig) {
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
"any newly configured zones are now loaded");
} else {
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_NOTICE,
"all zones loaded");
}
/*
* To maintain compatibility with log parsing tools that might
* be looking for this string after "rndc reconfig", we keep it
* as it is
*/
if (reconfig) {
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
"any newly configured zones are now loaded");
} else {
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_NOTICE,
"all zones loaded");
}
CHECKFATAL(dns_zonemgr_forcemaint(server->zonemgr),
"forcing zone maintenance");
CHECKFATAL(dns_zonemgr_forcemaint(server->zonemgr),
"forcing zone maintenance");
named_os_started();
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_NOTICE, "running");
named_os_started();
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_NOTICE, "running");
}
return (ISC_R_SUCCESS);
}
......@@ -9191,7 +9189,6 @@ load_zones(named_server_t *server, bool init, bool reconfig) {
isc_result_t result;
dns_view_t *view;
ns_zoneload_t *zl;
unsigned int refs = 0;
zl = isc_mem_get(server->mctx, sizeof (*zl));
if (zl == NULL)
......@@ -9230,13 +9227,12 @@ load_zones(named_server_t *server, bool init, bool reconfig) {
* 'dns_view_asyncload' calls view_loaded if there are no
* zones.
*/
isc_refcount_increment(&zl->refs, NULL);
isc_refcount_increment(&zl->refs);
CHECK(dns_view_asyncload(view, view_loaded, zl));
}
cleanup:
isc_refcount_decrement(&zl->refs, &refs);
if (refs == 0) {
if (isc_refcount_decrement(&zl->refs) == 1) {
isc_refcount_destroy(&zl->refs);
isc_mem_put(server->mctx, zl, sizeof (*zl));
} else if (init) {
......
......@@ -72,7 +72,7 @@ attach(dns_db_t *source, dns_db_t **targetp) {
REQUIRE(VALID_SAMPLEDB(sampledb));
isc_refcount_increment(&sampledb->refs, NULL);
isc_refcount_increment(&sampledb->refs);
*targetp = source;
}
......@@ -87,15 +87,13 @@ free_sampledb(sampledb_t *sampledb) {
static void
detach(dns_db_t **dbp) {
REQUIRE(dbp != NULL && VALID_SAMPLEDB((sampledb_t *)(*dbp)));
sampledb_t *sampledb = (sampledb_t *)(*dbp);
unsigned int refs;
REQUIRE(VALID_SAMPLEDB(sampledb));
*dbp = NULL;
isc_refcount_decrement(&sampledb->refs, &refs);
if (refs == 0)
if (isc_refcount_decrement(&sampledb->refs) == 1) {
free_sampledb(sampledb);
*dbp = NULL;
}
}
/*
......@@ -773,7 +771,7 @@ create_db(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
CHECK(dns_name_dupwithoffsets(origin, mctx, &sampledb->common.origin));
CHECK(isc_refcount_init(&sampledb->refs, 1));
isc_refcount_init(&sampledb->refs, 1);
/* Translate instance name to instance pointer. */
sampledb->inst = driverarg;
......
......@@ -392,6 +392,9 @@
/* Define to 1 if you have the `sigwait' function. */
#undef HAVE_SIGWAIT
/* Define to 1 if you have the <stdatomic.h> header file. */
#undef HAVE_STDATOMIC_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
......@@ -464,6 +467,9 @@
/* Define if zlib was found */
#undef HAVE_ZLIB
/* define if __atomic builtins are not available */
#undef HAVE___ATOMIC
/* Define if __thread keyword is available */
#undef HAVE___THREAD
......@@ -524,9 +530,6 @@
your system. */
#undef PTHREAD_CREATE_JOINABLE
/* The size of `void *', as computed by sizeof. */
#undef SIZEOF_VOID_P
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
......
......@@ -707,16 +707,6 @@ DNSTAP
FSTRM_CAPTURE
PROTOC_C
ISC_PLATFORM_BUSYWAITNOP
ISC_ARCH_DIR
ISC_PLATFORM_USEMACASM
ISC_PLATFORM_USESTDASM
ISC_PLATFORM_USEGCCASM
ISC_PLATFORM_HAVEATOMICSTOREQ
ISC_PLATFORM_HAVEATOMICSTORE
ISC_PLATFORM_HAVECMPXCHG
ISC_PLATFORM_HAVEXADDQ
ISC_PLATFORM_HAVEXADD
ISC_PLATFORM_HAVESTDATOMIC
ISC_PLATFORM_HAVEIFNAMETOINDEX
ISC_PLATFORM_HAVESTRINGSH
IRS_PLATFORM_USEDECLSPEC
......@@ -947,7 +937,6 @@ with_readline
enable_isc_spnego
enable_chroot
enable_linux_caps
enable_atomic
enable_fixed_rrset
enable_rpz_nsip
enable_rpz_nsdname
......@@ -1635,8 +1624,6 @@ Optional Features:
--disable-isc-spnego use SPNEGO from GSSAPI library
--disable-chroot disable chroot
--disable-linux-caps disable Linux capabilities
--enable-atomic enable machine specific atomic operations
[default=autodetect]
--enable-fixed-rrset enable fixed rrset ordering [default=no]
--disable-rpz-nsip disable rpz nsip rules [default=enabled]
--disable-rpz-nsdname disable rpz nsdname rules [default=enabled]
......@@ -2226,189 +2213,6 @@ $as_echo "$ac_res" >&6; }
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
} # ac_fn_c_check_type
# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
# --------------------------------------------
# Tries to find the compile-time value of EXPR in a program that includes
# INCLUDES, setting VAR accordingly. Returns whether the value could be
# computed
ac_fn_c_compute_int ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
if test "$cross_compiling" = yes; then
# Depending upon the size, compute the lo and hi bounds.
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
int
main ()
{
static int test_array [1 - 2 * !(($2) >= 0)];
test_array [0] = 0;
return test_array [0];
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_lo=0 ac_mid=0
while :; do
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
int
main ()
{
static int test_array [1 - 2 * !(($2) <= $ac_mid)];
test_array [0] = 0;
return test_array [0];
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_hi=$ac_mid; break
else
as_fn_arith $ac_mid + 1 && ac_lo=$as_val
if test $ac_lo -le $ac_mid; then
ac_lo= ac_hi=
break
fi
as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
done
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
int
main ()
{
static int test_array [1 - 2 * !(($2) < 0)];
test_array [0] = 0;
return test_array [0];
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_hi=-1 ac_mid=-1
while :; do
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
int
main ()
{
static int test_array [1 - 2 * !(($2) >= $ac_mid)];
test_array [0] = 0;
return test_array [0];
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_lo=$ac_mid; break
else
as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
if test $ac_mid -le $ac_hi; then
ac_lo= ac_hi=
break
fi
as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
done
else
ac_lo= ac_hi=
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
# Binary search between lo and hi bounds.
while test "x$ac_lo" != "x$ac_hi"; do
as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
int
main ()
{
static int test_array [1 - 2 * !(($2) <= $ac_mid)];
test_array [0] = 0;
return test_array [0];
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_hi=$ac_mid
else
as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
done
case $ac_lo in #((
?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
'') ac_retval=1 ;;
esac
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
static long int longval () { return $2; }
static unsigned long int ulongval () { return $2; }
#include <stdio.h>
#include <stdlib.h>
int
main ()
{
FILE *f = fopen ("conftest.val", "w");
if (! f)
return 1;
if (($2) < 0)
{
long int i = longval ();
if (i != ($2))
return 1;
fprintf (f, "%ld", i);
}
else
{
unsigned long int i = ulongval ();
if (i != ($2))
return 1;
fprintf (f, "%lu", i);
}
/* Do not output a trailing newline, as this causes \r\n confusion
on some platforms. */
return ferror (f) || fclose (f) != 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
echo >>conftest.val; read $3 <conftest.val; ac_retval=0
else
ac_retval=1
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
rm -f conftest.val
fi
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
} # ac_fn_c_compute_int
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
......@@ -18424,22 +18228,22 @@ fi
done
 
 
#
# Machine architecture dependent features
#
have_stdatomic=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for usable stdatomic.h" >&5
$as_echo_n "checking for usable stdatomic.h... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
ISC_ATOMIC_LIBS=""
for ac_header in stdatomic.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "stdatomic.h" "ac_cv_header_stdatomic_h" "$ac_includes_default"
if test "x$ac_cv_header_stdatomic_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_STDATOMIC_H 1
_ACEOF
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for memory model aware atomic operations" >&5
$as_echo_n "checking for memory model aware atomic operations... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdio.h>
#include <stdatomic.h>
int
main ()
{
atomic_int_fast32_t val = 0; atomic_fetch_add_explicit(&val, 1, memory_order_relaxed);
 
;
......@@ -18447,47 +18251,18 @@ atomic_int_fast32_t val = 0; atomic_fetch_add_explicit(&val, 1, memory_order_rel
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
have_stdatomic=yes
ISC_PLATFORM_HAVESTDATOMIC="#define ISC_PLATFORM_HAVESTDATOMIC 1"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
have_stdatomic=no
ISC_PLATFORM_HAVESTDATOMIC="#undef ISC_PLATFORM_HAVESTDATOMIC"
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
# Check whether --enable-atomic was given.
if test "${enable_atomic+set}" = set; then :
enableval=$enable_atomic; enable_atomic="$enableval"
else
enable_atomic="autodetect"
fi
case "$enable_atomic" in
yes|''|autodetect)
use_atomic=yes
;;
no)
have_stdatomic=no
ISC_PLATFORM_HAVESTDATOMIC="#undef ISC_PLATFORM_HAVESTDATOMIC"
use_atomic=no
arch=noatomic
;;
esac
if test "X$have_stdatomic" = "Xyes"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if -latomic is needed to use 64-bit stdatomic.h primitives" >&5
$as_echo_n "checking if -latomic is needed to use 64-bit stdatomic.h primitives... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: stdatomic.h" >&5
$as_echo "stdatomic.h" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -latomic is needed for 64-bit stdatomic.h functions" >&5
$as_echo_n "checking whether -latomic is needed for 64-bit stdatomic.h functions... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdatomic.h>
int
main ()
{
atomic_int_fast64_t val = 0; atomic_fetch_add_explicit(&val, 1, memory_order_relaxed);
;
return 0;
}
......@@ -18495,7 +18270,6 @@ _ACEOF
if ac_fn_c_try_link "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
ISC_ATOMIC_LIBS=""
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
......@@ -18504,206 +18278,74 @@ $as_echo "yes" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS="$LIBS $ISC_ATOMIC_LIBS"
fi
ISC_PLATFORM_USEGCCASM="#undef ISC_PLATFORM_USEGCCASM"
ISC_PLATFORM_USESTDASM="#undef ISC_PLATFORM_USESTDASM"
ISC_PLATFORM_USEMACASM="#undef ISC_PLATFORM_USEMACASM"
if test "yes" = "$use_atomic"; then
# The cast to long int works around a bug in the HP C Compiler
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
# This bug is HP SR number 8606223364.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5
$as_echo_n "checking size of void *... " >&6; }
if ${ac_cv_sizeof_void_p+:} false; then :
$as_echo_n "(cached) " >&6
else
if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then :
 
else
if test "$ac_cv_type_void_p" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error 77 "cannot compute sizeof (void *)
as_fn_error $? "stdatomic.h header found, but compilation failed, fix your toolchaing.
See \`config.log' for more details" "$LINENO" 5; }
else
ac_cv_sizeof_void_p=0
fi
fi
 
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5
$as_echo "$ac_cv_sizeof_void_p" >&6; }
cat >>confdefs.h <<_ACEOF
#define SIZEOF_VOID_P $ac_cv_sizeof_void_p
_ACEOF
have_atomic=yes # set default
case "$host" in
i[3456]86-*)
# XXX: some old x86 architectures actually do not support
# (some of) these operations. Do we need stricter checks?
if test $ac_cv_sizeof_void_p = 8; then
arch=x86_64
have_xaddq=yes
else
arch=x86_32
fi
;;
x86_64-*|amd64-*)
if test $ac_cv_sizeof_void_p = 8; then
arch=x86_64
have_xaddq=yes
else
arch=x86_32
fi
;;
powerpc-*|powerpc64-*)
arch=powerpc
;;
mips-*|mipsel-*|mips64-*|mips64el-*)
arch=mips
;;
ia64-*)
arch=ia64
;;
*)
have_atomic=no
arch=noatomic
;;
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking architecture type for atomic operations" >&5
$as_echo_n "checking architecture type for atomic operations... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $arch" >&5
$as_echo "$arch" >&6; }
fi
if test "yes" = "$have_atomic"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler support for inline assembly code" >&5
$as_echo_n "checking compiler support for inline assembly code... " >&6; }
compiler=generic
# Check whether the compiler supports the assembly syntax we provide.
if test "X$GCC" = "Xyes"; then
# GCC's ASM extension always works
compiler=gcc
if test $arch = "x86_64"; then
# We can share the same code for gcc with x86_32
arch=x86_32
fi
if test $arch = "powerpc"; then
#
# The MacOS (and maybe others) uses "r0" for register
# zero. Under linux/ibm it is "0" for register 0.
# Probe to see if we have a MacOS style assembler.
#
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Checking for MacOS style assembler syntax" >&5
$as_echo_n "checking Checking for MacOS style assembler syntax... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for memory model aware atomic operations" >&5
$as_echo_n "checking for memory model aware atomic operations... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <inttypes.h>
int
main ()
{
__asm__ volatile ("li r0, 0x0\n"::);
int32_t val = 0; __atomic_fetch_add(&val, 1, __ATOMIC_RELAXED);
 
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: __atomic builtins" >&5
$as_echo "__atomic builtins" >&6; }
 
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
compiler="mac"
ISC_PLATFORM_USEMACASM="#define ISC_PLATFORM_USEMACASM 1"
$as_echo "#define HAVE___ATOMIC 1" >>confdefs.h
 
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
fi
case "$compiler" in
gcc)
ISC_PLATFORM_USEGCCASM="#define ISC_PLATFORM_USEGCCASM 1"
;;
mac)
;;
*)
# See if the generic __asm function works. If not,
# we need to disable the atomic operations.
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -latomic is needed for 64-bit __atomic builtins" >&5
$as_echo_n "checking whether -latomic is needed for 64-bit __atomic builtins... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <inttypes.h>
int
main ()
{
__asm("nop")
int64_t val = 0; __atomic_fetch_add(&val, 1, __ATOMIC_RELAXED);
 
;
return 0;
}
_ACEOF