Index: llvm/cmake/config-ix.cmake =================================================================== --- llvm/cmake/config-ix.cmake +++ llvm/cmake/config-ix.cmake @@ -73,14 +73,12 @@ if( NOT PURE_WINDOWS ) check_library_exists(pthread pthread_create "" HAVE_LIBPTHREAD) if (HAVE_LIBPTHREAD) - check_library_exists(pthread pthread_getspecific "" HAVE_PTHREAD_GETSPECIFIC) check_library_exists(pthread pthread_rwlock_init "" HAVE_PTHREAD_RWLOCK_INIT) check_library_exists(pthread pthread_mutex_lock "" HAVE_PTHREAD_MUTEX_LOCK) else() # this could be Android check_library_exists(c pthread_create "" PTHREAD_IN_LIBC) if (PTHREAD_IN_LIBC) - check_library_exists(c pthread_getspecific "" HAVE_PTHREAD_GETSPECIFIC) check_library_exists(c pthread_rwlock_init "" HAVE_PTHREAD_RWLOCK_INIT) check_library_exists(c pthread_mutex_lock "" HAVE_PTHREAD_MUTEX_LOCK) endif() Index: llvm/include/llvm/Support/ThreadLocal.h =================================================================== --- llvm/include/llvm/Support/ThreadLocal.h +++ /dev/null @@ -1,62 +0,0 @@ -//===- llvm/Support/ThreadLocal.h - Thread Local Data ------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file declares the llvm::sys::ThreadLocal class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_THREADLOCAL_H -#define LLVM_SUPPORT_THREADLOCAL_H - -#include "llvm/Support/DataTypes.h" -#include "llvm/Support/Threading.h" -#include - -namespace llvm { - namespace sys { - // ThreadLocalImpl - Common base class of all ThreadLocal instantiations. - // YOU SHOULD NEVER USE THIS DIRECTLY. - class ThreadLocalImpl { - typedef uint64_t ThreadLocalDataTy; - /// Platform-specific thread local data. - /// - /// This is embedded in the class and we avoid malloc'ing/free'ing it, - /// to make this class more safe for use along with CrashRecoveryContext. - union { - char data[sizeof(ThreadLocalDataTy)]; - ThreadLocalDataTy align_data; - }; - public: - ThreadLocalImpl(); - virtual ~ThreadLocalImpl(); - void setInstance(const void* d); - void *getInstance(); - void removeInstance(); - }; - - /// ThreadLocal - A class used to abstract thread-local storage. It holds, - /// for each thread, a pointer a single object of type T. - template - class ThreadLocal : public ThreadLocalImpl { - public: - ThreadLocal() : ThreadLocalImpl() { } - - /// get - Fetches a pointer to the object associated with the current - /// thread. If no object has yet been associated, it returns NULL; - T* get() { return static_cast(getInstance()); } - - // set - Associates a pointer to an object with the current thread. - void set(T* d) { setInstance(d); } - - // erase - Removes the pointer associated with the current thread. - void erase() { removeInstance(); } - }; - } -} - -#endif Index: llvm/lib/Support/CMakeLists.txt =================================================================== --- llvm/lib/Support/CMakeLists.txt +++ llvm/lib/Support/CMakeLists.txt @@ -166,7 +166,6 @@ RWMutex.cpp Signals.cpp TargetRegistry.cpp - ThreadLocal.cpp Threading.cpp Valgrind.cpp Watchdog.cpp Index: llvm/lib/Support/CrashRecoveryContext.cpp =================================================================== --- llvm/lib/Support/CrashRecoveryContext.cpp +++ llvm/lib/Support/CrashRecoveryContext.cpp @@ -11,7 +11,6 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Mutex.h" -#include "llvm/Support/ThreadLocal.h" #include using namespace llvm; @@ -19,8 +18,7 @@ struct CrashRecoveryContextImpl; -static ManagedStatic< - sys::ThreadLocal > CurrentContext; +static const thread_local CrashRecoveryContextImpl *CurrentContext; struct CrashRecoveryContextImpl { // When threads are disabled, this links up all active @@ -38,12 +36,12 @@ CrashRecoveryContextImpl(CrashRecoveryContext *CRC) : CRC(CRC), Failed(false), SwitchedThread(false) { - Next = CurrentContext->get(); - CurrentContext->set(this); + Next = CurrentContext; + CurrentContext = this; } ~CrashRecoveryContextImpl() { if (!SwitchedThread) - CurrentContext->set(Next); + CurrentContext = Next; } /// Called when the separate crash-recovery thread was finished, to @@ -57,7 +55,7 @@ void HandleCrash() { // Eliminate the current context entry, to avoid re-entering in case the // cleanup code crashes. - CurrentContext->set(Next); + CurrentContext = Next; assert(!Failed && "Crash recovery context already failed!"); Failed = true; @@ -74,8 +72,7 @@ static ManagedStatic gCrashRecoveryContextMutex; static bool gCrashRecoveryEnabled = false; -static ManagedStatic> - tlIsRecoveringFromCrash; +const thread_local CrashRecoveryContext *tlIsRecoveringFromCrash = nullptr; static void installExceptionOrSignalHandlers(); static void uninstallExceptionOrSignalHandlers(); @@ -85,8 +82,8 @@ CrashRecoveryContext::~CrashRecoveryContext() { // Reclaim registered resources. CrashRecoveryContextCleanup *i = head; - const CrashRecoveryContext *PC = tlIsRecoveringFromCrash->get(); - tlIsRecoveringFromCrash->set(this); + const CrashRecoveryContext *PC = tlIsRecoveringFromCrash; + tlIsRecoveringFromCrash = this; while (i) { CrashRecoveryContextCleanup *tmp = i; i = tmp->next; @@ -94,21 +91,21 @@ tmp->recoverResources(); delete tmp; } - tlIsRecoveringFromCrash->set(PC); + tlIsRecoveringFromCrash = PC; CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl; delete CRCI; } bool CrashRecoveryContext::isRecoveringFromCrash() { - return tlIsRecoveringFromCrash->get() != nullptr; + return tlIsRecoveringFromCrash != nullptr; } CrashRecoveryContext *CrashRecoveryContext::GetCurrent() { if (!gCrashRecoveryEnabled) return nullptr; - const CrashRecoveryContextImpl *CRCI = CurrentContext->get(); + const CrashRecoveryContextImpl *CRCI = CurrentContext; if (!CRCI) return nullptr; @@ -293,7 +290,7 @@ static void CrashRecoverySignalHandler(int Signal) { // Lookup the current thread local recovery object. - const CrashRecoveryContextImpl *CRCI = CurrentContext->get(); + const CrashRecoveryContextImpl *CRCI = CurrentContext; if (!CRCI) { // We didn't find a crash recovery context -- this means either we got a Index: llvm/lib/Support/ThreadLocal.cpp =================================================================== --- llvm/lib/Support/ThreadLocal.cpp +++ /dev/null @@ -1,47 +0,0 @@ -//===- ThreadLocal.cpp - Thread Local Data ----------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file implements the llvm::sys::ThreadLocal class. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Support/ThreadLocal.h" -#include "llvm/Config/llvm-config.h" -#include "llvm/Support/Compiler.h" - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only TRULY operating system -//=== independent code. -//===----------------------------------------------------------------------===// - -#if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0 -// Define all methods as no-ops if threading is explicitly disabled -namespace llvm { -using namespace sys; -ThreadLocalImpl::ThreadLocalImpl() : data() { } -ThreadLocalImpl::~ThreadLocalImpl() { } -void ThreadLocalImpl::setInstance(const void* d) { - static_assert(sizeof(d) <= sizeof(data), "size too big"); - void **pd = reinterpret_cast(&data); - *pd = const_cast(d); -} -void *ThreadLocalImpl::getInstance() { - void **pd = reinterpret_cast(&data); - return *pd; -} -void ThreadLocalImpl::removeInstance() { - setInstance(nullptr); -} -} -#elif defined(LLVM_ON_UNIX) -#include "Unix/ThreadLocal.inc" -#elif defined( _WIN32) -#include "Windows/ThreadLocal.inc" -#else -#warning Neither LLVM_ON_UNIX nor _WIN32 set in Support/ThreadLocal.cpp -#endif Index: llvm/lib/Support/Unix/ThreadLocal.inc =================================================================== --- llvm/lib/Support/Unix/ThreadLocal.inc +++ /dev/null @@ -1,70 +0,0 @@ -//=== llvm/Support/Unix/ThreadLocal.inc - Unix Thread Local Data -*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file implements the Unix specific (non-pthread) ThreadLocal class. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic UNIX code that -//=== is guaranteed to work on *all* UNIX variants. -//===----------------------------------------------------------------------===// - -#include "llvm/Config/config.h" - -#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_GETSPECIFIC) - -#include -#include -#include - -namespace llvm { -using namespace sys; - -ThreadLocalImpl::ThreadLocalImpl() : data() { - static_assert(sizeof(pthread_key_t) <= sizeof(data), "size too big"); - pthread_key_t* key = reinterpret_cast(&data); - int errorcode = pthread_key_create(key, nullptr); - assert(errorcode == 0); - (void) errorcode; -} - -ThreadLocalImpl::~ThreadLocalImpl() { - pthread_key_t* key = reinterpret_cast(&data); - int errorcode = pthread_key_delete(*key); - assert(errorcode == 0); - (void) errorcode; -} - -void ThreadLocalImpl::setInstance(const void* d) { - pthread_key_t* key = reinterpret_cast(&data); - int errorcode = pthread_setspecific(*key, d); - assert(errorcode == 0); - (void) errorcode; -} - -void *ThreadLocalImpl::getInstance() { - pthread_key_t* key = reinterpret_cast(&data); - return pthread_getspecific(*key); -} - -void ThreadLocalImpl::removeInstance() { - setInstance(nullptr); -} - -} -#else -namespace llvm { -using namespace sys; -ThreadLocalImpl::ThreadLocalImpl() : data() { } -ThreadLocalImpl::~ThreadLocalImpl() { } -void ThreadLocalImpl::setInstance(const void* d) { data = const_cast(d);} -void *ThreadLocalImpl::getInstance() { return data; } -void ThreadLocalImpl::removeInstance() { setInstance(0); } -} -#endif Index: llvm/lib/Support/Windows/ThreadLocal.inc =================================================================== --- llvm/lib/Support/Windows/ThreadLocal.inc +++ /dev/null @@ -1,51 +0,0 @@ -//= llvm/Support/Win32/ThreadLocal.inc - Win32 Thread Local Data -*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file implements the Win32 specific (non-pthread) ThreadLocal class. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic Win32 code that -//=== is guaranteed to work on *all* Win32 variants. -//===----------------------------------------------------------------------===// - -#include "WindowsSupport.h" -#include "llvm/Support/ThreadLocal.h" - -namespace llvm { - -sys::ThreadLocalImpl::ThreadLocalImpl() : data() { - static_assert(sizeof(DWORD) <= sizeof(data), "size too big"); - DWORD* tls = reinterpret_cast(&data); - *tls = TlsAlloc(); - assert(*tls != TLS_OUT_OF_INDEXES); -} - -sys::ThreadLocalImpl::~ThreadLocalImpl() { - DWORD* tls = reinterpret_cast(&data); - TlsFree(*tls); -} - -void *sys::ThreadLocalImpl::getInstance() { - DWORD* tls = reinterpret_cast(&data); - return TlsGetValue(*tls); -} - -void sys::ThreadLocalImpl::setInstance(const void* d){ - DWORD* tls = reinterpret_cast(&data); - int errorcode = TlsSetValue(*tls, const_cast(d)); - assert(errorcode != 0); - (void)errorcode; -} - -void sys::ThreadLocalImpl::removeInstance() { - setInstance(0); -} - -} Index: llvm/unittests/Support/CMakeLists.txt =================================================================== --- llvm/unittests/Support/CMakeLists.txt +++ llvm/unittests/Support/CMakeLists.txt @@ -58,7 +58,6 @@ TarWriterTest.cpp TargetParserTest.cpp TaskQueueTest.cpp - ThreadLocalTest.cpp ThreadPool.cpp Threading.cpp TimerTest.cpp Index: llvm/unittests/Support/ThreadLocalTest.cpp =================================================================== --- llvm/unittests/Support/ThreadLocalTest.cpp +++ /dev/null @@ -1,56 +0,0 @@ -//===- llvm/unittest/Support/ThreadLocalTest.cpp - ThreadLocal tests ------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/Support/ThreadLocal.h" -#include "gtest/gtest.h" -#include - -using namespace llvm; -using namespace sys; - -namespace { - -class ThreadLocalTest : public ::testing::Test { -}; - -struct S { - int i; -}; - -TEST_F(ThreadLocalTest, Basics) { - ThreadLocal x; - - static_assert( - std::is_const::type>::value, - "ThreadLocal::get didn't return a pointer to const object"); - - EXPECT_EQ(nullptr, x.get()); - - S s; - x.set(&s); - EXPECT_EQ(&s, x.get()); - - x.erase(); - EXPECT_EQ(nullptr, x.get()); - - ThreadLocal y; - - static_assert( - !std::is_const::type>::value, - "ThreadLocal::get returned a pointer to const object"); - - EXPECT_EQ(nullptr, y.get()); - - y.set(&s); - EXPECT_EQ(&s, y.get()); - - y.erase(); - EXPECT_EQ(nullptr, y.get()); -} - -}