Kill the LLVM global lock.
This patch removes the LLVM global lock, and updates all existing
users of the global lock to use their own mutex. None of the
existing users of the global lock were protecting code that was
mutually exclusive with any of the other users of the global
lock, so its purpose was not being met.
Reviewed by: rnk
Differential Revision: http://reviews.llvm.org/D4142
llvm-svn: 211277
diff --git a/llvm/lib/Support/ManagedStatic.cpp b/llvm/lib/Support/ManagedStatic.cpp
index 6a1c2a5..9d7e99f 100644
--- a/llvm/lib/Support/ManagedStatic.cpp
+++ b/llvm/lib/Support/ManagedStatic.cpp
@@ -15,15 +15,32 @@
#include "llvm/Config/config.h"
#include "llvm/Support/Atomic.h"
#include <cassert>
+#include <mutex>
using namespace llvm;
static const ManagedStaticBase *StaticList = nullptr;
+// ManagedStatics can get created during execution of static constructors. As a
+// result, we cannot use a global static std::mutex object for the lock since it
+// may not have been constructed. Instead, we do a call-once initialization of
+// a pointer to a mutex.
+static std::once_flag MutexInitializationFlag;
+static std::recursive_mutex* ManagedStaticMutex = nullptr;
+
+// Not all supported platforms (in particular VS2012) have thread-safe function
+// static initialization, so roll our own.
+static std::recursive_mutex& GetManagedStaticMutex() {
+ std::call_once(MutexInitializationFlag,
+ []() { ManagedStaticMutex = new std::recursive_mutex(); } );
+
+ return *ManagedStaticMutex;
+}
+
void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
void (*Deleter)(void*)) const {
assert(Creator);
if (llvm_is_multithreaded()) {
- llvm_acquire_global_lock();
+ std::lock_guard<std::recursive_mutex> Lock(GetManagedStaticMutex());
if (!Ptr) {
void* tmp = Creator();
@@ -43,8 +60,6 @@
Next = StaticList;
StaticList = this;
}
-
- llvm_release_global_lock();
} else {
assert(!Ptr && !DeleterFn && !Next &&
"Partially initialized ManagedStatic!?");
@@ -75,6 +90,8 @@
/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
void llvm::llvm_shutdown() {
+ std::lock_guard<std::recursive_mutex> Lock(GetManagedStaticMutex());
+
while (StaticList)
StaticList->destroy();