diff --git a/configure.ac b/configure.ac --- a/configure.ac +++ b/configure.ac @@ -825,6 +825,21 @@ ] ) +AC_MSG_CHECKING([for thread_local support]) +case $host in + i?86-*mingw*) + # Disable thread_local for mingw on 32 bits targets. See discussion in: + # https://github.com/bitcoin/bitcoin/pull/15849/files#r280537603 + # and bug report: + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83562 + AC_MSG_RESULT(no) + ;; + *) + AC_DEFINE(HAVE_THREAD_LOCAL,1,[Define if thread_local is supported.]) + AC_MSG_RESULT(yes) + ;; +esac + # Check for different ways of gathering OS randomness AC_MSG_CHECKING(for Linux getrandom syscall) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include diff --git a/src/config/CMakeLists.txt b/src/config/CMakeLists.txt --- a/src/config/CMakeLists.txt +++ b/src/config/CMakeLists.txt @@ -201,6 +201,16 @@ set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY}) check_symbol_exists(EVP_MD_CTX_new "openssl/evp.h" HAVE_DECL_EVP_MD_CTX_NEW) +# Disable thread_local for mingw on 32 bits targets. See discussion in: +# https://github.com/bitcoin/bitcoin/pull/15849/files#r280537603 +# and bug report: +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83562 +if(NOT CMAKE_C_COMPILER_TARGET MATCHES "i[3-6]86-.*mingw.*") + set(HAVE_THREAD_LOCAL 1) +else() + message(STATUS "Disabled thread_local for this platform") +endif() + # Activate wallet set(ENABLE_WALLET ${BUILD_BITCOIN_WALLET}) diff --git a/src/config/bitcoin-config.h.cmake.in b/src/config/bitcoin-config.h.cmake.in --- a/src/config/bitcoin-config.h.cmake.in +++ b/src/config/bitcoin-config.h.cmake.in @@ -60,6 +60,8 @@ #cmakedefine HAVE_DECL_EVP_MD_CTX_NEW 1 +#cmakedefine HAVE_THREAD_LOCAL 1 + #define FDELT_TYPE ${FDELT_TYPE} #cmakedefine ENABLE_BIP70 1 diff --git a/src/test/util_threadnames_tests.cpp b/src/test/util_threadnames_tests.cpp --- a/src/test/util_threadnames_tests.cpp +++ b/src/test/util_threadnames_tests.cpp @@ -55,6 +55,11 @@ BOOST_AUTO_TEST_CASE(util_threadnames_test_rename_threaded) { BOOST_CHECK_EQUAL(util::ThreadGetInternalName(), ""); +#if !defined(HAVE_THREAD_LOCAL) + // This test doesn't apply to platforms where we don't have thread_local. + return; +#endif + std::set names = RenameEnMasse(100); BOOST_CHECK_EQUAL(names.size(), 100); diff --git a/src/util/threadnames.cpp b/src/util/threadnames.cpp --- a/src/util/threadnames.cpp +++ b/src/util/threadnames.cpp @@ -35,6 +35,10 @@ #endif } +// If we have thread_local, just keep thread ID and name in a thread_local +// global. +#if defined(HAVE_THREAD_LOCAL) + static thread_local std::string g_thread_name; const std::string &util::ThreadGetInternalName() { return g_thread_name; @@ -45,6 +49,17 @@ g_thread_name = std::move(name); } +// Without thread_local available, don't handle internal name at all. +#else + +static const std::string empty_string; +const std::string &util::ThreadGetInternalName() { + return empty_string; +} +static void SetInternalName(std::string name) {} + +#endif // defined(HAVE_THREAD_LOCAL) + void util::ThreadRename(std::string &&name) { SetThreadName(("b-" + name).c_str()); SetInternalName(std::move(name));