2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 05:28:00 +00:00

Add and use ISC_THREAD_LOCAL macro

The new ISC_THREAD_LOCAL macro unifies usage of platform dependent
Thread Local Storage definition thread_local vs __thread vs
__declspec(thread) to a single macro.

The commit also unifies the required level of support for TLS as for
some parts of the code it was mandatory and for some parts of the code
it wasn't.
This commit is contained in:
Ondřej Surý 2019-12-02 11:42:50 +01:00 committed by Ondřej Surý
parent 96475e7eb4
commit 01731d4b1b
10 changed files with 35 additions and 111 deletions

6
configure vendored
View File

@ -13616,8 +13616,7 @@ $as_echo "#define HAVE_TLS 1" >>confdefs.h
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
as_fn_error $? "Thread Local Storage support required, update your toolchain to build BIND 9" "$LINENO" 5
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
@ -13655,8 +13654,7 @@ $as_echo "#define HAVE_TLS 1" >>confdefs.h
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
as_fn_error $? "Thread Local Storage support required, update your toolchain to build BIND 9" "$LINENO" 5
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext

View File

@ -389,7 +389,7 @@ AC_CHECK_HEADERS([threads.h],
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_ERROR([Thread Local Storage support required, update your toolchain to build BIND 9])
])
],[
AC_MSG_CHECKING([for Thread-Local Storage using __thread])
@ -405,7 +405,7 @@ AC_CHECK_HEADERS([threads.h],
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_MSG_ERROR([Thread Local Storage support required, update your toolchain to build BIND 9])
])
])

View File

@ -51,6 +51,7 @@
#include <isc/string.h>
#include <isc/mem.h>
#include <isc/util.h>
#include <isc/thread.h>
#define HP_MAX_THREADS 128
#define HP_MAX_HPS 4 /* This is named 'K' in the HP paper */
@ -64,20 +65,7 @@
static atomic_int_fast32_t tid_v_base = ATOMIC_VAR_INIT(0);
#if defined(HAVE_TLS)
#if defined(HAVE_THREAD_LOCAL)
#include <threads.h>
static thread_local int tid_v = TID_UNKNOWN;
#elif defined(HAVE___THREAD)
static __thread int tid_v = TID_UNKNOWN;
#elif defined(HAVE___DECLSPEC_THREAD)
static __declspec( thread ) int tid_v = TID_UNKNOWN;
#else /* if defined(HAVE_THREAD_LOCAL) */
#error "Unknown method for defining a TLS variable!"
#endif /* if defined(HAVE_THREAD_LOCAL) */
#else /* if defined(HAVE_TLS) */
#error "Thread-local storage support is required!"
#endif /* if defined(HAVE_TLS) */
ISC_THREAD_LOCAL int tid_v = TID_UNKNOWN;
typedef struct retirelist {
int size;

View File

@ -18,14 +18,6 @@
***** Platform-dependent defines.
*****/
/***
*** Thread-Local Storage
***/
#ifdef HAVE___THREAD
#define thread_local __thread
#endif
/***
*** Default strerror_r buffer size
***/

View File

@ -31,7 +31,6 @@
#include <isc/util.h>
#define ISC_NETMGR_TID_UNKNOWN -1
#define ISC_NETMGR_TID_NOTLS -2
/*
* Single network event loop worker.

View File

@ -40,20 +40,7 @@
* request using async_cb.
*/
#if defined(HAVE_TLS)
#if defined(HAVE_THREAD_LOCAL)
#include <threads.h>
static thread_local int isc__nm_tid_v = ISC_NETMGR_TID_UNKNOWN;
#elif defined(HAVE___THREAD)
static __thread int isc__nm_tid_v = ISC_NETMGR_TID_UNKNOWN;
#elif defined(HAVE___DECLSPEC_THREAD)
static __declspec( thread ) int isc__nm_tid_v = ISC_NETMGR_TID_UNKNOWN;
#else /* if defined(HAVE_THREAD_LOCAL) */
#error "Unknown method for defining a TLS variable!"
#endif /* if defined(HAVE_THREAD_LOCAL) */
#else /* if defined(HAVE_TLS) */
static int isc__nm_tid_v = ISC_NETMGR_TID_NOTLS;
#endif /* if defined(HAVE_TLS) */
ISC_THREAD_LOCAL int isc__nm_tid_v = ISC_NETMGR_TID_UNKNOWN;
static void
nmsocket_maybe_destroy(isc_nmsocket_t *sock);

View File

@ -58,6 +58,23 @@ isc_thread_setaffinity(int cpu);
#define isc_thread_key_setspecific pthread_setspecific
#define isc_thread_key_delete pthread_key_delete
/***
*** Thread-Local Storage
***/
#if defined(HAVE_TLS)
#if defined(HAVE_THREAD_LOCAL)
#include <threads.h>
#define ISC_THREAD_LOCAL static thread_local
#elif defined(HAVE___THREAD)
#define ISC_THREAD_LOCAL static __thread
#else /* if defined(HAVE_THREAD_LOCAL) */
#error "Unknown method for defining a TLS variable!"
#endif /* if defined(HAVE_THREAD_LOCAL) */
#else /* if defined(HAVE_TLS) */
#error "Thread-local storage support is required!"
#endif /* if defined(HAVE_TLS) */
ISC_LANG_ENDDECLS
#endif /* ISC_THREAD_H */

View File

@ -36,6 +36,7 @@
#include <isc/platform.h>
#include <isc/random.h>
#include <isc/result.h>
#include <isc/thread.h>
#include <isc/types.h>
#include <isc/util.h>
@ -60,20 +61,7 @@
*/
#include "xoshiro128starstar.c"
#if defined(HAVE_TLS)
#if defined(HAVE_THREAD_LOCAL)
#include <threads.h>
static thread_local isc_once_t isc_random_once = ISC_ONCE_INIT;
#elif defined(HAVE___THREAD)
static __thread isc_once_t isc_random_once = ISC_ONCE_INIT;
#elif defined(HAVE___DECLSPEC_THREAD)
static __declspec( thread ) isc_once_t isc_random_once = ISC_ONCE_INIT;
#else
#error "Unknown method for defining a TLS variable!"
#endif
#else
static isc_once_t isc_random_once = ISC_ONCE_INIT;
#endif
ISC_THREAD_LOCAL isc_once_t isc_random_once = ISC_ONCE_INIT;
static void
isc_random_initialize(void) {

View File

@ -96,6 +96,12 @@ isc_thread_key_setspecific(isc_thread_key_t key, void *value);
#define isc_thread_yield() Sleep(0)
#if HAVE___DECLSPEC_THREAD
#define ISC_THREAD_LOCAL static __declspec( thread )
#else
#error "Thread-local storage support is required!"
#endif
ISC_LANG_ENDDECLS
#endif /* ISC_THREAD_H */

View File

@ -22,6 +22,8 @@
#include <inttypes.h>
#include <isc/thread.h>
/*
* This is xoshiro128** 1.0, our 32-bit all-purpose, rock-solid generator.
* It has excellent (sub-ns) speed, a state size (128 bits) that is large
@ -32,56 +34,7 @@
*
* The state must be seeded so that it is not everywhere zero.
*/
#if defined(HAVE_TLS)
#define _LOCK() {};
#define _UNLOCK() {};
#if defined(HAVE_THREAD_LOCAL)
#include <threads.h>
static thread_local uint32_t seed[4];
#elif defined(HAVE___THREAD)
static __thread uint32_t seed[4];
#elif defined(HAVE___DECLSPEC_THREAD)
static __declspec( thread ) uint32_t seed[4];
#else
#error "Unknown method for defining a TLS variable!"
#endif
#else
#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
static volatile void *_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() \
do { \
if (!_mutex) { \
void *p = CreateMutex(NULL, FALSE, NULL); \
if (InterlockedCompareExchangePointer \
((void **)&_mutex, (void *)p, NULL)) { \
CloseHandle(p); \
} \
} \
WaitForSingleObject(_mutex, INFINITE); \
} while (0)
#define _UNLOCK() ReleaseMutex(_mutex)
#else /* defined(_WIN32) || defined(_WIN64) */
#include <pthread.h>
static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER;
#define _LOCK() RUNTIME_CHECK(pthread_mutex_lock(&_mutex)==0)
#define _UNLOCK() RUNTIME_CHECK(pthread_mutex_unlock(&_mutex)==0)
#endif /* defined(_WIN32) || defined(_WIN64) */
static uint32_t seed[4];
#endif /* defined(HAVE_TLS) */
ISC_THREAD_LOCAL uint32_t seed[4] = { 0 };
static inline uint32_t rotl(const uint32_t x, int k) {
return (x << k) | (x >> (32 - k));
@ -91,8 +44,6 @@ static inline uint32_t
next(void) {
uint32_t result_starstar, t;
_LOCK();
result_starstar = rotl(seed[0] * 5, 7) * 9;
t = seed[1] << 9;
@ -105,7 +56,5 @@ next(void) {
seed[3] = rotl(seed[3], 11);
_UNLOCK();
return (result_starstar);
}