Reminder to please always mention the reason for the revert/recommit in the commit message.
On Tue, Jan 10, 2023 at 7:22 AM Owen Anderson via cfe-commits <cfe-commits@lists.llvm.org> wrote: > > > Author: Owen Anderson > Date: 2023-01-09T21:21:38-07:00 > New Revision: ef9aa34f0274cdbfa82c47f8ab99f02679fd0d13 > > URL: > https://github.com/llvm/llvm-project/commit/ef9aa34f0274cdbfa82c47f8ab99f02679fd0d13 > DIFF: > https://github.com/llvm/llvm-project/commit/ef9aa34f0274cdbfa82c47f8ab99f02679fd0d13.diff > > LOG: Revert "Remove the ThreadLocal template from LLVM." > > This reverts commit 54d78b639b9c18b42abd4fac5c6e76105f06b3ef. > > Added: > llvm/include/llvm/Support/ThreadLocal.h > llvm/lib/Support/ThreadLocal.cpp > llvm/lib/Support/Unix/ThreadLocal.inc > llvm/lib/Support/Windows/ThreadLocal.inc > llvm/unittests/Support/ThreadLocalTest.cpp > > Modified: > clang-tools-extra/clangd/support/ThreadCrashReporter.cpp > llvm/lib/Support/CMakeLists.txt > llvm/lib/Support/CrashRecoveryContext.cpp > llvm/unittests/Support/CMakeLists.txt > mlir/include/mlir/Support/ThreadLocalCache.h > > Removed: > > > > ################################################################################ > diff --git a/clang-tools-extra/clangd/support/ThreadCrashReporter.cpp > b/clang-tools-extra/clangd/support/ThreadCrashReporter.cpp > index 9551bbfda43c1..05afb3b25f28e 100644 > --- a/clang-tools-extra/clangd/support/ThreadCrashReporter.cpp > +++ b/clang-tools-extra/clangd/support/ThreadCrashReporter.cpp > @@ -7,6 +7,7 @@ > > //===----------------------------------------------------------------------===// > > #include "support/ThreadCrashReporter.h" > +#include "llvm/Support/ThreadLocal.h" > #include <atomic> > > namespace clang { > > diff --git a/llvm/include/llvm/Support/ThreadLocal.h > b/llvm/include/llvm/Support/ThreadLocal.h > new file mode 100644 > index 0000000000000..d6838c15fc345 > --- /dev/null > +++ b/llvm/include/llvm/Support/ThreadLocal.h > @@ -0,0 +1,62 @@ > +//===- 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 <cassert> > + > +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 T> > + 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<T*>(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 > > diff --git a/llvm/lib/Support/CMakeLists.txt > b/llvm/lib/Support/CMakeLists.txt > index 9b5402fa54f0f..46469c6e9e624 100644 > --- a/llvm/lib/Support/CMakeLists.txt > +++ b/llvm/lib/Support/CMakeLists.txt > @@ -260,6 +260,7 @@ add_llvm_component_library(LLVMSupport > Program.cpp > RWMutex.cpp > Signals.cpp > + ThreadLocal.cpp > Threading.cpp > Valgrind.cpp > Watchdog.cpp > > diff --git a/llvm/lib/Support/CrashRecoveryContext.cpp > b/llvm/lib/Support/CrashRecoveryContext.cpp > index 9e792d1f51777..c7c384c9edc22 100644 > --- a/llvm/lib/Support/CrashRecoveryContext.cpp > +++ b/llvm/lib/Support/CrashRecoveryContext.cpp > @@ -11,6 +11,7 @@ > #include "llvm/Support/ErrorHandling.h" > #include "llvm/Support/ExitCodes.h" > #include "llvm/Support/Signals.h" > +#include "llvm/Support/ThreadLocal.h" > #include "llvm/Support/thread.h" > #include <mutex> > #include <setjmp.h> > @@ -20,7 +21,11 @@ using namespace llvm; > namespace { > > struct CrashRecoveryContextImpl; > -LLVM_THREAD_LOCAL static const CrashRecoveryContextImpl *CurrentContext; > + > +sys::ThreadLocal<const CrashRecoveryContextImpl> &getCurrentContext() { > + static sys::ThreadLocal<const CrashRecoveryContextImpl> CurrentContext; > + return CurrentContext; > +} > > struct CrashRecoveryContextImpl { > // When threads are disabled, this links up all active > @@ -38,12 +43,12 @@ struct CrashRecoveryContextImpl { > public: > CrashRecoveryContextImpl(CrashRecoveryContext *CRC) noexcept > : CRC(CRC), Failed(false), SwitchedThread(false), > ValidJumpBuffer(false) { > - Next = CurrentContext; > - CurrentContext = this; > + Next = getCurrentContext().get(); > + getCurrentContext().set(this); > } > ~CrashRecoveryContextImpl() { > if (!SwitchedThread) > - CurrentContext = Next; > + getCurrentContext().set(Next); > } > > /// Called when the separate crash-recovery thread was finished, to > @@ -61,7 +66,7 @@ struct CrashRecoveryContextImpl { > void HandleCrash(int RetCode, uintptr_t Context) { > // Eliminate the current context entry, to avoid re-entering in case the > // cleanup code crashes. > - CurrentContext = Next; > + getCurrentContext().set(Next); > > assert(!Failed && "Crash recovery context already failed!"); > Failed = true; > @@ -87,7 +92,10 @@ std::mutex &getCrashRecoveryContextMutex() { > > static bool gCrashRecoveryEnabled = false; > > -LLVM_THREAD_LOCAL static const CrashRecoveryContext *IsRecoveringFromCrash; > +sys::ThreadLocal<const CrashRecoveryContext> &getIsRecoveringFromCrash() { > + static sys::ThreadLocal<const CrashRecoveryContext> IsRecoveringFromCrash; > + return IsRecoveringFromCrash; > +} > > } // namespace > > @@ -106,8 +114,8 @@ CrashRecoveryContext::CrashRecoveryContext() { > CrashRecoveryContext::~CrashRecoveryContext() { > // Reclaim registered resources. > CrashRecoveryContextCleanup *i = head; > - const CrashRecoveryContext *PC = IsRecoveringFromCrash; > - IsRecoveringFromCrash = this; > + const CrashRecoveryContext *PC = getIsRecoveringFromCrash().get(); > + getIsRecoveringFromCrash().set(this); > while (i) { > CrashRecoveryContextCleanup *tmp = i; > i = tmp->next; > @@ -115,21 +123,21 @@ CrashRecoveryContext::~CrashRecoveryContext() { > tmp->recoverResources(); > delete tmp; > } > - IsRecoveringFromCrash = PC; > + getIsRecoveringFromCrash().set(PC); > > CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl; > delete CRCI; > } > > bool CrashRecoveryContext::isRecoveringFromCrash() { > - return IsRecoveringFromCrash != nullptr; > + return getIsRecoveringFromCrash().get() != nullptr; > } > > CrashRecoveryContext *CrashRecoveryContext::GetCurrent() { > if (!gCrashRecoveryEnabled) > return nullptr; > > - const CrashRecoveryContextImpl *CRCI = CurrentContext; > + const CrashRecoveryContextImpl *CRCI = getCurrentContext().get(); > if (!CRCI) > return nullptr; > > @@ -199,7 +207,7 @@ static void uninstallExceptionOrSignalHandlers() {} > // occur inside the __except evaluation block > static int ExceptionFilter(_EXCEPTION_POINTERS *Except) { > // Lookup the current thread local recovery object. > - const CrashRecoveryContextImpl *CRCI = CurrentContext; > + const CrashRecoveryContextImpl *CRCI = getCurrentContext().get(); > > if (!CRCI) { > // Something has gone horribly wrong, so let's just tell everyone > @@ -276,7 +284,7 @@ static LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS > ExceptionInfo) > } > > // Lookup the current thread local recovery object. > - const CrashRecoveryContextImpl *CRCI = CurrentContext; > + const CrashRecoveryContextImpl *CRCI = getCurrentContext().get(); > > if (!CRCI) { > // Something has gone horribly wrong, so let's just tell everyone > @@ -350,7 +358,7 @@ static struct sigaction PrevActions[NumSignals]; > > static void CrashRecoverySignalHandler(int Signal) { > // Lookup the current thread local recovery object. > - const CrashRecoveryContextImpl *CRCI = CurrentContext; > + const CrashRecoveryContextImpl *CRCI = getCurrentContext().get(); > > if (!CRCI) { > // We didn't find a crash recovery context -- this means either we got a > > diff --git a/llvm/lib/Support/ThreadLocal.cpp > b/llvm/lib/Support/ThreadLocal.cpp > new file mode 100644 > index 0000000000000..44e6223cf17b6 > --- /dev/null > +++ b/llvm/lib/Support/ThreadLocal.cpp > @@ -0,0 +1,47 @@ > +//===- 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<void**>(&data); > + *pd = const_cast<void*>(d); > +} > +void *ThreadLocalImpl::getInstance() { > + void **pd = reinterpret_cast<void**>(&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 > > diff --git a/llvm/lib/Support/Unix/ThreadLocal.inc > b/llvm/lib/Support/Unix/ThreadLocal.inc > new file mode 100644 > index 0000000000000..483c5b0d324e1 > --- /dev/null > +++ b/llvm/lib/Support/Unix/ThreadLocal.inc > @@ -0,0 +1,57 @@ > +//=== 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" > + > +#include <cassert> > +#include <pthread.h> > +#include <stdlib.h> > + > +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<pthread_key_t *>(&data); > + int errorcode = pthread_key_create(key, nullptr); > + assert(errorcode == 0); > + (void)errorcode; > +} > + > +ThreadLocalImpl::~ThreadLocalImpl() { > + pthread_key_t *key = reinterpret_cast<pthread_key_t *>(&data); > + int errorcode = pthread_key_delete(*key); > + assert(errorcode == 0); > + (void)errorcode; > +} > + > +void ThreadLocalImpl::setInstance(const void *d) { > + pthread_key_t *key = reinterpret_cast<pthread_key_t *>(&data); > + int errorcode = pthread_setspecific(*key, d); > + assert(errorcode == 0); > + (void)errorcode; > +} > + > +void *ThreadLocalImpl::getInstance() { > + pthread_key_t *key = reinterpret_cast<pthread_key_t *>(&data); > + return pthread_getspecific(*key); > +} > + > +void ThreadLocalImpl::removeInstance() { setInstance(nullptr); } > + > +} // namespace llvm > > diff --git a/llvm/lib/Support/Windows/ThreadLocal.inc > b/llvm/lib/Support/Windows/ThreadLocal.inc > new file mode 100644 > index 0000000000000..900444d11b25c > --- /dev/null > +++ b/llvm/lib/Support/Windows/ThreadLocal.inc > @@ -0,0 +1,50 @@ > +//= 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 "llvm/Support/ThreadLocal.h" > +#include "llvm/Support/Windows/WindowsSupport.h" > + > +namespace llvm { > + > +sys::ThreadLocalImpl::ThreadLocalImpl() : data() { > + static_assert(sizeof(DWORD) <= sizeof(data), "size too big"); > + DWORD *tls = reinterpret_cast<DWORD *>(&data); > + *tls = TlsAlloc(); > + assert(*tls != TLS_OUT_OF_INDEXES); > +} > + > +sys::ThreadLocalImpl::~ThreadLocalImpl() { > + DWORD *tls = reinterpret_cast<DWORD *>(&data); > + TlsFree(*tls); > +} > + > +void *sys::ThreadLocalImpl::getInstance() { > + DWORD *tls = reinterpret_cast<DWORD *>(&data); > + return TlsGetValue(*tls); > +} > + > +void sys::ThreadLocalImpl::setInstance(const void *d) { > + DWORD *tls = reinterpret_cast<DWORD *>(&data); > + int errorcode = TlsSetValue(*tls, const_cast<void *>(d)); > + assert(errorcode != 0); > + (void)errorcode; > +} > + > +void sys::ThreadLocalImpl::removeInstance() { setInstance(0); } > + > +} // namespace llvm > > diff --git a/llvm/unittests/Support/CMakeLists.txt > b/llvm/unittests/Support/CMakeLists.txt > index d987d65db13ea..ccffb42e267eb 100644 > --- a/llvm/unittests/Support/CMakeLists.txt > +++ b/llvm/unittests/Support/CMakeLists.txt > @@ -80,6 +80,7 @@ add_llvm_unittest(SupportTests > SymbolRemappingReaderTest.cpp > TarWriterTest.cpp > TaskQueueTest.cpp > + ThreadLocalTest.cpp > ThreadPool.cpp > Threading.cpp > TimerTest.cpp > > diff --git a/llvm/unittests/Support/ThreadLocalTest.cpp > b/llvm/unittests/Support/ThreadLocalTest.cpp > new file mode 100644 > index 0000000000000..454e4f21a05fe > --- /dev/null > +++ b/llvm/unittests/Support/ThreadLocalTest.cpp > @@ -0,0 +1,54 @@ > +//===- 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 <type_traits> > + > +using namespace llvm; > +using namespace sys; > + > +namespace { > + > +class ThreadLocalTest : public ::testing::Test { > +}; > + > +struct S { > + int i; > +}; > + > +TEST_F(ThreadLocalTest, Basics) { > + ThreadLocal<const S> x; > + > + static_assert(std::is_const_v<std::remove_pointer_t<decltype(x.get())>>, > + "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<S> y; > + > + static_assert(!std::is_const_v<std::remove_pointer_t<decltype(y.get())>>, > + "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()); > +} > + > +} > > diff --git a/mlir/include/mlir/Support/ThreadLocalCache.h > b/mlir/include/mlir/Support/ThreadLocalCache.h > index e98fae6b117ae..083956b717422 100644 > --- a/mlir/include/mlir/Support/ThreadLocalCache.h > +++ b/mlir/include/mlir/Support/ThreadLocalCache.h > @@ -18,6 +18,7 @@ > #include "llvm/ADT/DenseMap.h" > #include "llvm/Support/ManagedStatic.h" > #include "llvm/Support/Mutex.h" > +#include "llvm/Support/ThreadLocal.h" > > namespace mlir { > /// This class provides support for defining a thread local object with non > > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits