]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Make the xoshiro128plusplus thread-safe
authorOndřej Surý <ondrej@sury.org>
Tue, 29 May 2018 12:10:32 +0000 (14:10 +0200)
committerOndřej Surý <ondrej@sury.org>
Tue, 29 May 2018 20:58:49 +0000 (22:58 +0200)
config.h.in
configure
configure.in
lib/isc/include/isc/platform.h.in
lib/isc/random.c
lib/isc/win32/include/isc/platform.h.in
lib/isc/xoshiro128starstar.c

index 69e3c1fd3153b0e4c3d900903fc445b26d717957..1d149f7afd0a37b04ca56fa3da55dcdef5fe83dd 100644 (file)
@@ -521,6 +521,15 @@ int sigwait(const unsigned int *set, int *sig);
 /* Define to 1 if you have the <sys/un.h> header file. */
 #undef HAVE_SYS_UN_H
 
+/* Define to 1 if you have the <threads.h> header file. */
+#undef HAVE_THREADS_H
+
+/* Define if thread_local keyword is available */
+#undef HAVE_THREAD_LOCAL
+
+/* Define if Thread-Local Storage is available */
+#undef HAVE_TLS
+
 /* Define if running under Compaq TruCluster */
 #undef HAVE_TRUCLUSTER
 
@@ -533,6 +542,9 @@ int sigwait(const unsigned int *set, int *sig);
 /* Define if zlib was found */
 #undef HAVE_ZLIB
 
+/* Define if __thread keyword is available */
+#undef HAVE___THREAD
+
 /* Use HMAC-SHA1 for Client Cookie generation */
 #undef HMAC_SHA1_CC
 
index 28840a8a9ca7543212be5b5e0ad7d9cfef70bc7a..539abdf5c740cfa18af1387ddcf5a4474ad182b2 100755 (executable)
--- a/configure
+++ b/configure
@@ -2146,60 +2146,6 @@ $as_echo "$ac_res" >&6; }
 
 } # ac_fn_c_check_func
 
-# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
-# -------------------------------------------
-# Tests whether TYPE exists after having included INCLUDES, setting cache
-# variable VAR accordingly.
-ac_fn_c_check_type ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  eval "$3=no"
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-if (sizeof ($2))
-        return 0;
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-if (sizeof (($2)))
-           return 0;
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
-  eval "$3=yes"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_type
-
 # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
 # -------------------------------------------------------
 # Tests whether HEADER exists, giving a warning if it cannot be compiled using
@@ -2291,6 +2237,60 @@ fi
 
 } # ac_fn_c_check_header_mongrel
 
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+        return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+           return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$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
 done
 
 
+#
+# Check for thread local storage
+#
+for ac_header in threads.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "threads.h" "ac_cv_header_threads_h" "$ac_includes_default"
+if test "x$ac_cv_header_threads_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_THREADS_H 1
+_ACEOF
+
+                    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C11 Thread-Local Storage using thread_local" >&5
+$as_echo_n "checking for C11 Thread-Local Storage using thread_local... " >&6; }
+                    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+                                 #include <threads.h>
+
+int
+main ()
+{
+
+                                 static thread_local int tls = 0;
+                                 return (tls);
+
+  ;
+  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; }
+
+$as_echo "#define HAVE_THREAD_LOCAL 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_TLS 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
+
+else
+
+                    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Thread-Local Storage using __thread" >&5
+$as_echo_n "checking for Thread-Local Storage using __thread... " >&6; }
+                    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+
+                                 static __thread int tls = 0;
+                                 return (tls);
+
+  ;
+  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; }
+
+$as_echo "#define HAVE___THREAD 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_TLS 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
+
+done
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
 $as_echo_n "checking for an ANSI C-conforming const... " >&6; }
 if ${ac_cv_c_const+:} false; then :
index 9594c01630cc6d49f9d4cf35a120efc18d4c4b9a..627ddec3108a96e466d3b2551cf91035b210d85e 100644 (file)
@@ -486,6 +486,45 @@ AC_CHECK_HEADERS(fcntl.h regex.h sys/time.h unistd.h sys/mman.h sys/sockio.h sys
 #endif
 ])
 
+#
+# Check for thread local storage
+#
+AC_CHECK_HEADERS([threads.h],
+                [
+                    AC_MSG_CHECKING([for C11 Thread-Local Storage using thread_local])
+                    AC_COMPILE_IFELSE(
+                        [AC_LANG_PROGRAM(
+                             [
+                                 #include <threads.h>
+                             ],[
+                                 static thread_local int tls = 0;
+                                 return (tls);
+                             ])
+                        ],[
+                            AC_MSG_RESULT([yes])
+                            AC_DEFINE([HAVE_THREAD_LOCAL],[1],[Define if thread_local keyword is available])
+                            AC_DEFINE([HAVE_TLS],[1],[Define if Thread-Local Storage is available])
+                        ],[
+                            AC_MSG_RESULT([no])
+                        ])
+                ],[
+                    AC_MSG_CHECKING([for Thread-Local Storage using __thread])
+                    AC_COMPILE_IFELSE(
+                        [AC_LANG_PROGRAM(
+                             [
+                             ],[
+                                 static __thread int tls = 0;
+                                 return (tls);
+                             ])
+                        ],[
+                            AC_MSG_RESULT([yes])
+                            AC_DEFINE([HAVE___THREAD],[1],[Define if __thread keyword is available])
+                            AC_DEFINE([HAVE_TLS],[1],[Define if Thread-Local Storage is available])
+                        ],[
+                            AC_MSG_RESULT([no])
+                        ])
+                ])
+
 AC_C_CONST
 AC_C_INLINE
 AC_C_VOLATILE
index 9a74ee64d53a36478b6fadefaf30026d1b844aed..b8c67624c83d55a83c8757193013868bd62f7a9e 100644 (file)
  ***** Platform-dependent defines.
  *****/
 
+/***
+ *** Thread-Local Storage
+ ***/
+
+#ifdef HAVE___THREAD
+#define thread_local __thread
+#endif
+
 /***
  *** Network.
  ***/
index d88431d6d0e667b372d097a39d2e7bdc52bdd3c2..490f0d95ad5a298c56b5008af73d0dadc4995db7 100644 (file)
@@ -35,6 +35,7 @@
 #include <string.h>
 #include <unistd.h>
 
+#include <isc/platform.h>
 #include <isc/random.h>
 #include <isc/result.h>
 #include <isc/types.h>
index d7f94a6ff09e1c602f6c446b8838b38d662f570d..3b60b01e11b6349bccae4957142861590fcc9517 100644 (file)
 
 #define ISC_PLATFORM_USETHREADS 1
 
+/*
+ * Thread-Local Storage
+ */
+#ifndef thread_local
+#define thread_local
+#endif
+
 /*
  * Some compatibility cludges
  */
index f12f5cf52f0ed18704d8bc38ff794dcd4afe22a1..137ffa1ae287d78f57e54a7f08991419ea9a7180 100644 (file)
  * The state must be seeded so that it is not everywhere zero.
  */
 
+#if defined(_WIN32) || defined(_WIN64)
+#include <windows.h>
+static volatile HANDLE _mutex = NULL;
+
+/*
+ * Initialize the mutex on the first lock attempt. On collision, each thread
+ * will attempt to allocate a mutex and compare-and-swap it into place as the
+ * global mutex. On failure to swap in the global mutex, the mutex is closed.
+ */
+#define _LOCK() { \
+       if (!_mutex) { \
+               HANDLE p = CreateMutex(NULL, FALSE, NULL); \
+               if (InterlockedCompareExchangePointer((void **)&_mutex, (void *)p, NULL)) \
+                       CloseHandle(p); \
+       } \
+       WaitForSingleObject(_mutex, INFINITE); \
+}
+
+#define _UNLOCK() ReleaseMutex(_mutex)
+
+#else /* defined(_WIN32) || defined(_WIN64) */
+
+#include <pthread.h>
+static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER;
+#define _LOCK()   pthread_mutex_lock(&_mutex)
+#define _UNLOCK() pthread_mutex_unlock(&_mutex)
+#endif /* defined(_WIN32) || defined(_WIN64) */
+
 static inline uint32_t rotl(const uint32_t x, int k) {
        return (x << k) | (x >> (32 - k));
 }
@@ -41,6 +69,8 @@ static uint32_t seed[4];
 
 static inline uint32_t
 next(void) {
+       _LOCK();
+
        const uint32_t result_starstar = rotl(seed[0] * 5, 7) * 9;
 
        const uint32_t t = seed[1] << 9;
@@ -54,5 +84,7 @@ next(void) {
 
        seed[3] = rotl(seed[3], 11);
 
+       _UNLOCK();
+
        return (result_starstar);
 }