mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-01 13:20:25 +00:00
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
This commit is contained in:
parent
c8e3b5f849
commit
6ad2444d5b
@ -2226,11 +2226,6 @@ Note that, because no other threads are allowed to issue LLVM API calls before
|
|||||||
``llvm_start_multithreaded()`` returns, it is possible to have
|
``llvm_start_multithreaded()`` returns, it is possible to have
|
||||||
``ManagedStatic``\ s of ``llvm::sys::Mutex``\ s.
|
``ManagedStatic``\ s of ``llvm::sys::Mutex``\ s.
|
||||||
|
|
||||||
The ``llvm_acquire_global_lock()`` and ``llvm_release_global_lock`` APIs provide
|
|
||||||
access to the global lock used to implement the double-checked locking for lazy
|
|
||||||
initialization. These should only be used internally to LLVM, and only if you
|
|
||||||
know what you're doing!
|
|
||||||
|
|
||||||
.. _llvmcontext:
|
.. _llvmcontext:
|
||||||
|
|
||||||
Achieving Isolation with ``LLVMContext``
|
Achieving Isolation with ``LLVMContext``
|
||||||
|
@ -33,14 +33,6 @@ namespace llvm {
|
|||||||
/// mode or not.
|
/// mode or not.
|
||||||
bool llvm_is_multithreaded();
|
bool llvm_is_multithreaded();
|
||||||
|
|
||||||
/// acquire_global_lock - Acquire the global lock. This is a no-op if called
|
|
||||||
/// before llvm_start_multithreaded().
|
|
||||||
void llvm_acquire_global_lock();
|
|
||||||
|
|
||||||
/// release_global_lock - Release the global lock. This is a no-op if called
|
|
||||||
/// before llvm_start_multithreaded().
|
|
||||||
void llvm_release_global_lock();
|
|
||||||
|
|
||||||
/// llvm_execute_on_thread - Execute the given \p UserFn on a separate
|
/// llvm_execute_on_thread - Execute the given \p UserFn on a separate
|
||||||
/// thread, passing it the provided \p UserData.
|
/// thread, passing it the provided \p UserData.
|
||||||
///
|
///
|
||||||
|
@ -15,15 +15,32 @@
|
|||||||
#include "llvm/Config/config.h"
|
#include "llvm/Config/config.h"
|
||||||
#include "llvm/Support/Atomic.h"
|
#include "llvm/Support/Atomic.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <mutex>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
static const ManagedStaticBase *StaticList = nullptr;
|
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 ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
|
||||||
void (*Deleter)(void*)) const {
|
void (*Deleter)(void*)) const {
|
||||||
assert(Creator);
|
assert(Creator);
|
||||||
if (llvm_is_multithreaded()) {
|
if (llvm_is_multithreaded()) {
|
||||||
llvm_acquire_global_lock();
|
std::lock_guard<std::recursive_mutex> Lock(GetManagedStaticMutex());
|
||||||
|
|
||||||
if (!Ptr) {
|
if (!Ptr) {
|
||||||
void* tmp = Creator();
|
void* tmp = Creator();
|
||||||
@ -43,8 +60,6 @@ void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
|
|||||||
Next = StaticList;
|
Next = StaticList;
|
||||||
StaticList = this;
|
StaticList = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm_release_global_lock();
|
|
||||||
} else {
|
} else {
|
||||||
assert(!Ptr && !DeleterFn && !Next &&
|
assert(!Ptr && !DeleterFn && !Next &&
|
||||||
"Partially initialized ManagedStatic!?");
|
"Partially initialized ManagedStatic!?");
|
||||||
@ -75,6 +90,8 @@ void ManagedStaticBase::destroy() const {
|
|||||||
|
|
||||||
/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
|
/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
|
||||||
void llvm::llvm_shutdown() {
|
void llvm::llvm_shutdown() {
|
||||||
|
std::lock_guard<std::recursive_mutex> Lock(GetManagedStaticMutex());
|
||||||
|
|
||||||
while (StaticList)
|
while (StaticList)
|
||||||
StaticList->destroy();
|
StaticList->destroy();
|
||||||
|
|
||||||
|
@ -21,13 +21,10 @@ using namespace llvm;
|
|||||||
|
|
||||||
static bool multithreaded_mode = false;
|
static bool multithreaded_mode = false;
|
||||||
|
|
||||||
static sys::Mutex* global_lock = nullptr;
|
|
||||||
|
|
||||||
bool llvm::llvm_start_multithreaded() {
|
bool llvm::llvm_start_multithreaded() {
|
||||||
#if LLVM_ENABLE_THREADS != 0
|
#if LLVM_ENABLE_THREADS != 0
|
||||||
assert(!multithreaded_mode && "Already multithreaded!");
|
assert(!multithreaded_mode && "Already multithreaded!");
|
||||||
multithreaded_mode = true;
|
multithreaded_mode = true;
|
||||||
global_lock = new sys::Mutex(true);
|
|
||||||
|
|
||||||
// We fence here to ensure that all initialization is complete BEFORE we
|
// We fence here to ensure that all initialization is complete BEFORE we
|
||||||
// return from llvm_start_multithreaded().
|
// return from llvm_start_multithreaded().
|
||||||
@ -47,7 +44,6 @@ void llvm::llvm_stop_multithreaded() {
|
|||||||
sys::MemoryFence();
|
sys::MemoryFence();
|
||||||
|
|
||||||
multithreaded_mode = false;
|
multithreaded_mode = false;
|
||||||
delete global_lock;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,14 +51,6 @@ bool llvm::llvm_is_multithreaded() {
|
|||||||
return multithreaded_mode;
|
return multithreaded_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void llvm::llvm_acquire_global_lock() {
|
|
||||||
if (multithreaded_mode) global_lock->acquire();
|
|
||||||
}
|
|
||||||
|
|
||||||
void llvm::llvm_release_global_lock() {
|
|
||||||
if (multithreaded_mode) global_lock->release();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if LLVM_ENABLE_THREADS != 0 && defined(HAVE_PTHREAD_H)
|
#if LLVM_ENABLE_THREADS != 0 && defined(HAVE_PTHREAD_H)
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "llvm/Support/Format.h"
|
#include "llvm/Support/Format.h"
|
||||||
#include "llvm/Support/ManagedStatic.h"
|
#include "llvm/Support/ManagedStatic.h"
|
||||||
#include "llvm/Support/Mutex.h"
|
#include "llvm/Support/Mutex.h"
|
||||||
|
#include "llvm/Support/MutexGuard.h"
|
||||||
#include "llvm/Support/Process.h"
|
#include "llvm/Support/Process.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
@ -84,14 +85,13 @@ static TimerGroup *getDefaultTimerGroup() {
|
|||||||
sys::MemoryFence();
|
sys::MemoryFence();
|
||||||
if (tmp) return tmp;
|
if (tmp) return tmp;
|
||||||
|
|
||||||
llvm_acquire_global_lock();
|
sys::SmartScopedLock<true> Lock(*TimerLock);
|
||||||
tmp = DefaultTimerGroup;
|
tmp = DefaultTimerGroup;
|
||||||
if (!tmp) {
|
if (!tmp) {
|
||||||
tmp = new TimerGroup("Miscellaneous Ungrouped Timers");
|
tmp = new TimerGroup("Miscellaneous Ungrouped Timers");
|
||||||
sys::MemoryFence();
|
sys::MemoryFence();
|
||||||
DefaultTimerGroup = tmp;
|
DefaultTimerGroup = tmp;
|
||||||
}
|
}
|
||||||
llvm_release_global_lock();
|
|
||||||
|
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user