From 0990a8c3e943dc5d000f6df185fea43ba137bf3c Mon Sep 17 00:00:00 2001 From: Thomas Moenicke Date: Tue, 11 Jun 2019 16:06:16 +0300 Subject: use C++11 thread_local, ThreadLocal class as a fallback when thread_local not supported --- CMakeLists.txt | 3 ++- cmake/core.cmake | 1 + cmake/test.cmake | 1 + cmake/thread_local.cmake | 10 ++++++++++ platform/android/src/run_loop.cpp | 1 - platform/default/src/mbgl/util/run_loop.cpp | 1 - platform/default/src/mbgl/util/thread_local.cpp | 22 ++++++++++++++++++++++ src/mbgl/actor/scheduler.cpp | 2 -- src/mbgl/util/thread_local.hpp | 17 +++++++++++++++++ 9 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 cmake/thread_local.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index ca33c36be2..f01f6e6941 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ include(cmake/vendor.cmake) include(cmake/mason.cmake) include(cmake/xcode.cmake) include(cmake/doxygen.cmake) +include(cmake/thread_local.cmake) if(WITH_CXX11ABI) set(MASON_CXXABI_SUFFIX -cxx11abi) @@ -159,7 +160,7 @@ elseif(WIN32) string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") endif() else() - message(STATUS "Can't find ccache — consider installing ccache to improve recompilation performance") + message(STATUS "Can't find ccache — consider installing ccache to improve recompilation performance") endif() if(NOT EXISTS ${CMAKE_SOURCE_DIR}/platform/${MBGL_PLATFORM}/config.cmake) diff --git a/cmake/core.cmake b/cmake/core.cmake index 1971352c37..ea44400f0b 100644 --- a/cmake/core.cmake +++ b/cmake/core.cmake @@ -5,6 +5,7 @@ add_library(mbgl-core STATIC ${MBGL_CORE_FILES}) target_include_directories(mbgl-core PUBLIC include PRIVATE src + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/compilerchecks ) target_link_libraries(mbgl-core PRIVATE diff --git a/cmake/test.cmake b/cmake/test.cmake index 16dc10f93d..de78e5f06b 100644 --- a/cmake/test.cmake +++ b/cmake/test.cmake @@ -22,6 +22,7 @@ target_include_directories(mbgl-test PRIVATE test/include PRIVATE test/src PRIVATE platform/default/include + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/compilerchecks ) target_link_libraries(mbgl-test PRIVATE diff --git a/cmake/thread_local.cmake b/cmake/thread_local.cmake new file mode 100644 index 0000000000..e0031d8439 --- /dev/null +++ b/cmake/thread_local.cmake @@ -0,0 +1,10 @@ +include(WriteCompilerDetectionHeader) + +write_compiler_detection_header( + FILE "${CMAKE_CURRENT_BINARY_DIR}/compilerchecks/thread_local_compiler_detection.h" + PREFIX MB + COMPILERS GNU Clang AppleClang MSVC Intel + FEATURES cxx_thread_local +) + +add_definitions(-DDETECT_THREAD_LOCAL) diff --git a/platform/android/src/run_loop.cpp b/platform/android/src/run_loop.cpp index 2966ecdfb0..6bc792a6e4 100644 --- a/platform/android/src/run_loop.cpp +++ b/platform/android/src/run_loop.cpp @@ -1,7 +1,6 @@ #include "run_loop_impl.hpp" #include -#include #include #include #include diff --git a/platform/default/src/mbgl/util/run_loop.cpp b/platform/default/src/mbgl/util/run_loop.cpp index 868ee72114..dabba63cbe 100644 --- a/platform/default/src/mbgl/util/run_loop.cpp +++ b/platform/default/src/mbgl/util/run_loop.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include diff --git a/platform/default/src/mbgl/util/thread_local.cpp b/platform/default/src/mbgl/util/thread_local.cpp index 5fb66c3440..159a8e8e17 100644 --- a/platform/default/src/mbgl/util/thread_local.cpp +++ b/platform/default/src/mbgl/util/thread_local.cpp @@ -6,20 +6,33 @@ #include +#ifdef MB_COMPILER_CXX_THREAD_LOCAL +#include +#endif + namespace mbgl { namespace util { namespace impl { +#ifdef MB_COMPILER_CXX_THREAD_LOCAL +namespace { +thread_local std::unordered_map mapOfPointers; +} +#endif + ThreadLocalBase::ThreadLocalBase() { +#ifndef MB_COMPILER_CXX_THREAD_LOCAL static_assert(sizeof(storage) >= sizeof(pthread_key_t), "storage is too small"); static_assert(alignof(decltype(storage)) % alignof(pthread_key_t) == 0, "storage is incorrectly aligned"); if (pthread_key_create(&reinterpret_cast(storage), nullptr) != 0) { Log::Error(Event::General, "Failed to initialize thread-specific storage key"); abort(); } +#endif } ThreadLocalBase::~ThreadLocalBase() { +#ifndef MB_COMPILER_CXX_THREAD_LOCAL // ThreadLocal will not take ownership of the pointer it is managing. The pointer // needs to be explicitly cleared before we destroy this object. assert(!get()); @@ -28,17 +41,26 @@ ThreadLocalBase::~ThreadLocalBase() { Log::Error(Event::General, "Failed to delete thread-specific storage key"); abort(); } +#endif } void* ThreadLocalBase::get() { +#ifdef MB_COMPILER_CXX_THREAD_LOCAL + return mapOfPointers[this]; +#else return pthread_getspecific(reinterpret_cast(storage)); +#endif } void ThreadLocalBase::set(void* ptr) { +#ifdef MB_COMPILER_CXX_THREAD_LOCAL + mapOfPointers[this] = ptr; +#else if (pthread_setspecific(reinterpret_cast(storage), ptr) != 0) { Log::Error(Event::General, "Failed to set thread-specific storage"); abort(); } +#endif } } // namespace impl diff --git a/src/mbgl/actor/scheduler.cpp b/src/mbgl/actor/scheduler.cpp index cb0c7728ec..06a4c6a9fc 100644 --- a/src/mbgl/actor/scheduler.cpp +++ b/src/mbgl/actor/scheduler.cpp @@ -4,8 +4,6 @@ namespace mbgl { -util::ThreadLocal g_currentScheduler; - static auto& current() { static util::ThreadLocal scheduler; return scheduler; diff --git a/src/mbgl/util/thread_local.hpp b/src/mbgl/util/thread_local.hpp index cf5579a2ba..84417e631c 100644 --- a/src/mbgl/util/thread_local.hpp +++ b/src/mbgl/util/thread_local.hpp @@ -2,6 +2,21 @@ #include +#ifdef DETECT_THREAD_LOCAL +#include "thread_local_compiler_detection.h" +#endif + +#ifdef __APPLE__ +# include +# include +# if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0 +# undef MB_COMPILER_CXX_THREAD_LOCAL +# endif +# if defined(__i386__) && defined(TARGET_OS_SIMULATOR) +# undef MB_COMPILER_CXX_THREAD_LOCAL +# endif +#endif + namespace mbgl { namespace util { namespace impl { @@ -15,7 +30,9 @@ protected: void set(void*); private: +#ifndef MB_COMPILER_CXX_THREAD_LOCAL std::aligned_storage_t storage; +#endif }; } // namespace impl -- cgit v1.2.1