+3440. [performance] Implement adaptive read-write locks, reducing the
+ overhead of locks that are only held briefly.
+ [RT #37329]
+
4339. [test] Use "mdig" to test pipelined queries. [RT #41929]
4338. [bug] Reimplement change 4324 as it wasn't properly doing
DNSTAPSRCS
DNSTAP
PROTOC_C
+ISC_PLATFORM_BUSYWAITNOP
ISC_ARCH_DIR
ISC_PLATFORM_USEMACASM
ISC_PLATFORM_USESTDASM
fi
+#
+# CPU relax (for spin locks)
+#
+if $use_threads
+then
+ case "$host" in
+ i[3456]86-*)
+ # x86_32
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if asm(\"rep; nop\"); works" >&5
+$as_echo_n "checking if asm(\"rep; nop\"); works... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+asm("rep; nop");
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"rep; nop\")"
+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
+ ;;
+ x86_64-*|amd64-*)
+ # x86_64
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if asm(\"rep; nop\"); works" >&5
+$as_echo_n "checking if asm(\"rep; nop\"); works... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+asm("rep; nop");
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"rep; nop\")"
+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
+ ;;
+ ia64-*)
+ # ia64
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if asm(\"hint @pause\"); works" >&5
+$as_echo_n "checking if asm(\"hint @pause\"); works... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+asm("hint @pause");
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"hint @pause\")"
+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
+ ;;
+ sparc-*)
+ # sparc
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if cpu_relax(); or __cpu_relax(); works" >&5
+$as_echo_n "checking if cpu_relax(); or __cpu_relax(); works... " >&6; }
+ ac_fn_c_check_func "$LINENO" "cpu_relax" "ac_cv_func_cpu_relax"
+if test "x$ac_cv_func_cpu_relax" = xyes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP cpu_relax()"
+else
+ ac_fn_c_check_func "$LINENO" "__cpu_relax" "ac_cv_func___cpu_relax"
+if test "x$ac_cv_func___cpu_relax" = xyes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP __cpu_relax()"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+fi
+
+ ;;
+ esac
+fi
+
+
+
#
# Activate "rrset-order fixed" or not?
#
AC_DEFINE(HAVE_BUILTIN_EXPECT, 1, [Define to 1 if the compiler supports __builtin_expect.])
fi
+#
+# CPU relax (for spin locks)
+#
+if $use_threads
+then
+ case "$host" in
+ [i[3456]86-*])
+ # x86_32
+ AC_MSG_CHECKING([if asm("rep; nop"); works])
+ AC_TRY_COMPILE(,[asm("rep; nop");],
+ [AC_MSG_RESULT(yes)
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"rep; nop\")"],
+ [AC_MSG_RESULT(no)],
+ [AC_MSG_RESULT([cross compile, assume yes])
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"rep; nop\")"])
+ ;;
+ x86_64-*|amd64-*)
+ # x86_64
+ AC_MSG_CHECKING([if asm("rep; nop"); works])
+ AC_TRY_COMPILE(,[asm("rep; nop");],
+ [AC_MSG_RESULT(yes)
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"rep; nop\")"],
+ [AC_MSG_RESULT(no)],
+ [AC_MSG_RESULT([cross compile, assume yes])
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"rep; nop\")"])
+ ;;
+ ia64-*)
+ # ia64
+ AC_MSG_CHECKING([if asm("hint @pause"); works])
+ AC_TRY_COMPILE(,[asm("hint @pause");],
+ [AC_MSG_RESULT(yes)
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"hint @pause\")"],
+ [AC_MSG_RESULT(no)],
+ [AC_MSG_RESULT([cross compile, assume yes])
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP asm(\"hint @pause\")"])
+ ;;
+ sparc-*)
+ # sparc
+ AC_MSG_CHECKING([if cpu_relax(); or __cpu_relax(); works])
+ AC_CHECK_FUNC(cpu_relax,
+ [AC_MSG_RESULT(yes)
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP cpu_relax()"],
+ [AC_CHECK_FUNC(__cpu_relax,
+ [AC_MSG_RESULT(yes)
+ ISC_PLATFORM_BUSYWAITNOP="#define ISC_PLATFORM_BUSYWAITNOP __cpu_relax()"],
+ [AC_MSG_RESULT(no)])])
+ ;;
+ esac
+fi
+
+AC_SUBST(ISC_PLATFORM_BUSYWAITNOP)
+
#
# Activate "rrset-order fixed" or not?
#
*/
@ISC_PLATFORM_USESTDASM@
+/*
+ * Define with the busy wait nop asm or function call.
+ */
+@ISC_PLATFORM_BUSYWAITNOP@
+
/*
* Define if the platform has <strings.h>.
*/
/* Unlocked. */
unsigned int magic;
isc_mutex_t lock;
+ isc_int32_t spins;
#if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
/*
#define RWLOCK_DEFAULT_WRITE_QUOTA 4
#endif
+#ifndef RWLOCK_MAX_ADAPTIVE_COUNT
+#define RWLOCK_MAX_ADAPTIVE_COUNT 100
+#endif
+
+#if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
+static isc_result_t
+isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
+#endif
+
#ifdef ISC_RWLOCK_TRACE
#include <stdio.h> /* Required for fprintf/stderr. */
#include <isc/thread.h> /* Required for isc_thread_self(). */
*/
rwl->magic = 0;
+ rwl->spins = 0;
#if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
rwl->write_requests = 0;
rwl->write_completions = 0;
#define WRITER_ACTIVE 0x1
#define READER_INCR 0x2
-isc_result_t
-isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
+static isc_result_t
+isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
isc_int32_t cntflag;
REQUIRE(VALID_RWLOCK(rwl));
return (ISC_R_SUCCESS);
}
+isc_result_t
+isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
+ isc_int32_t cnt = 0;
+ isc_int32_t max_cnt = rwl->spins * 2 + 10;
+ isc_result_t result = ISC_R_SUCCESS;
+
+ if (max_cnt > RWLOCK_MAX_ADAPTIVE_COUNT)
+ max_cnt = RWLOCK_MAX_ADAPTIVE_COUNT;
+
+ do {
+ if (cnt++ >= max_cnt) {
+ result = isc__rwlock_lock(rwl, type);
+ break;
+ }
+#ifdef ISC_PLATFORM_BUSYWAITNOP
+ ISC_PLATFORM_BUSYWAITNOP;
+#endif
+ } while (isc_rwlock_trylock(rwl, type) != ISC_R_SUCCESS);
+
+ rwl->spins += (cnt - rwl->spins) / 8;
+
+ return (result);
+}
+
isc_result_t
isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
isc_int32_t cntflag;
isc_result_t
isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) {
- return (doit(rwl, type, ISC_FALSE));
+ isc_int32_t cnt = 0;
+ isc_int32_t max_cnt = rwl->spins * 2 + 10;
+ isc_result_t result = ISC_R_SUCCESS;
+
+ if (max_cnt > RWLOCK_MAX_ADAPTIVE_COUNT)
+ max_cnt = RWLOCK_MAX_ADAPTIVE_COUNT;
+
+ do {
+ if (cnt++ >= max_cnt) {
+ result = doit(rwl, type, ISC_FALSE);
+ break;
+ }
+#ifdef ISC_PLATFORM_BUSYWAITNOP
+ ISC_PLATFORM_BUSYWAITNOP;
+#endif
+ } while (doit(rwl, type, ISC_TRUE) != ISC_R_SUCCESS);
+
+ rwl->spins += (cnt - rwl->spins) / 8;
+
+ return (ISC_R_SUCCESS);
}
isc_result_t
*/
@ISC_PLATFORM_HAVECMPXCHG@
+/*
+ * Define with the busy wait nop asm or function call.
+ */
+@ISC_PLATFORM_BUSYWAITNOP@
+
/*
* If the strcasestr() operation is not available on this platform,
* ISC_PLATFORM_NEEDSTRCASESTR will be defined.
my %configdefp;
-my @substdefp = ("ISC_PLATFORM_HAVEATOMICSTORE",
+my @substdefp = ("ISC_PLATFORM_BUSYWAITNOP",
+ "ISC_PLATFORM_HAVEATOMICSTORE",
"ISC_PLATFORM_HAVEATOMICSTOREQ",
"ISC_PLATFORM_HAVECMPXCHG",
"ISC_PLATFORM_HAVEXADD",
$configvar{"BUILD_PLATFORM"} = "Win32";
$configvar{"MACHINE"} = "/machine:X86";
$configvar{"BUILD_MACHINE"} = "/machine:X86";
+ $configdefp{"ISC_PLATFORM_BUSYWAITNOP"} = "__asm { rep nop }";
} elsif ($want_x64 eq "yes") {
$configvar{"PLATFORM"} = "x64";
$configvar{"BUILD_PLATFORM"} = "x64";
$configvar{"MACHINE"} = "/machine:X64";
$configvar{"BUILD_MACHINE"} = "/machine:X64";
+ $configdefp{"ISC_PLATFORM_BUSYWAITNOP"} = "__asm { rep nop }";
}
# get the version information