Support: make LLVM Mutexes STL-compatible

Use lock/unlock() convention instead of acquire/release().

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216336 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dylan Noblesmith
2014-08-23 22:49:22 +00:00
parent 7e3e4311c5
commit d930a30833
7 changed files with 42 additions and 40 deletions

View File

@ -111,7 +111,7 @@ public:
void clear() { Map.clear(); } void clear() { Map.clear(); }
/// Return 1 if the specified key is in the map, 0 otherwise. /// Return 1 if the specified key is in the map, 0 otherwise.
size_type count(const KeyT &Val) const { size_type count(const KeyT &Val) const {
return Map.find_as(Val) == Map.end() ? 0 : 1; return Map.find_as(Val) == Map.end() ? 0 : 1;
} }
@ -217,11 +217,11 @@ public:
ValueMapCallbackVH Copy(*this); ValueMapCallbackVH Copy(*this);
typename Config::mutex_type *M = Config::getMutex(Copy.Map->Data); typename Config::mutex_type *M = Config::getMutex(Copy.Map->Data);
if (M) if (M)
M->acquire(); M->lock();
Config::onDelete(Copy.Map->Data, Copy.Unwrap()); // May destroy *this. Config::onDelete(Copy.Map->Data, Copy.Unwrap()); // May destroy *this.
Copy.Map->Map.erase(Copy); // Definitely destroys *this. Copy.Map->Map.erase(Copy); // Definitely destroys *this.
if (M) if (M)
M->release(); M->unlock();
} }
void allUsesReplacedWith(Value *new_key) override { void allUsesReplacedWith(Value *new_key) override {
assert(isa<KeySansPointerT>(new_key) && assert(isa<KeySansPointerT>(new_key) &&
@ -230,7 +230,7 @@ public:
ValueMapCallbackVH Copy(*this); ValueMapCallbackVH Copy(*this);
typename Config::mutex_type *M = Config::getMutex(Copy.Map->Data); typename Config::mutex_type *M = Config::getMutex(Copy.Map->Data);
if (M) if (M)
M->acquire(); M->lock();
KeyT typed_new_key = cast<KeySansPointerT>(new_key); KeyT typed_new_key = cast<KeySansPointerT>(new_key);
// Can destroy *this: // Can destroy *this:
@ -246,7 +246,7 @@ public:
} }
} }
if (M) if (M)
M->release(); M->unlock();
} }
}; };

View File

@ -86,16 +86,17 @@ namespace llvm
/// indicates whether this mutex should become a no-op when we're not /// indicates whether this mutex should become a no-op when we're not
/// running in multithreaded mode. /// running in multithreaded mode.
template<bool mt_only> template<bool mt_only>
class SmartMutex : public MutexImpl { class SmartMutex {
MutexImpl impl;
unsigned acquired; unsigned acquired;
bool recursive; bool recursive;
public: public:
explicit SmartMutex(bool rec = true) : explicit SmartMutex(bool rec = true) :
MutexImpl(rec), acquired(0), recursive(rec) { } impl(rec), acquired(0), recursive(rec) { }
bool acquire() { bool lock() {
if (!mt_only || llvm_is_multithreaded()) { if (!mt_only || llvm_is_multithreaded()) {
return MutexImpl::acquire(); return impl.acquire();
} else { } else {
// Single-threaded debugging code. This would be racy in // Single-threaded debugging code. This would be racy in
// multithreaded mode, but provides not sanity checks in single // multithreaded mode, but provides not sanity checks in single
@ -106,9 +107,9 @@ namespace llvm
} }
} }
bool release() { bool unlock() {
if (!mt_only || llvm_is_multithreaded()) { if (!mt_only || llvm_is_multithreaded()) {
return MutexImpl::release(); return impl.release();
} else { } else {
// Single-threaded debugging code. This would be racy in // Single-threaded debugging code. This would be racy in
// multithreaded mode, but provides not sanity checks in single // multithreaded mode, but provides not sanity checks in single
@ -120,9 +121,9 @@ namespace llvm
} }
} }
bool tryacquire() { bool try_lock() {
if (!mt_only || llvm_is_multithreaded()) if (!mt_only || llvm_is_multithreaded())
return MutexImpl::tryacquire(); return impl.tryacquire();
else return true; else return true;
} }
@ -140,11 +141,11 @@ namespace llvm
public: public:
SmartScopedLock(SmartMutex<mt_only>& m) : mtx(m) { SmartScopedLock(SmartMutex<mt_only>& m) : mtx(m) {
mtx.acquire(); mtx.lock();
} }
~SmartScopedLock() { ~SmartScopedLock() {
mtx.release(); mtx.unlock();
} }
}; };

View File

@ -29,8 +29,8 @@ namespace llvm {
MutexGuard(const MutexGuard &) LLVM_DELETED_FUNCTION; MutexGuard(const MutexGuard &) LLVM_DELETED_FUNCTION;
void operator=(const MutexGuard &) LLVM_DELETED_FUNCTION; void operator=(const MutexGuard &) LLVM_DELETED_FUNCTION;
public: public:
MutexGuard(sys::Mutex &m) : M(m) { M.acquire(); } MutexGuard(sys::Mutex &m) : M(m) { M.lock(); }
~MutexGuard() { M.release(); } ~MutexGuard() { M.unlock(); }
/// holds - Returns true if this locker instance holds the specified lock. /// holds - Returns true if this locker instance holds the specified lock.
/// This is mostly used in assertions to validate that the correct mutex /// This is mostly used in assertions to validate that the correct mutex
/// is held. /// is held.

View File

@ -85,14 +85,15 @@ namespace llvm
/// indicates whether this mutex should become a no-op when we're not /// indicates whether this mutex should become a no-op when we're not
/// running in multithreaded mode. /// running in multithreaded mode.
template<bool mt_only> template<bool mt_only>
class SmartRWMutex : public RWMutexImpl { class SmartRWMutex {
RWMutexImpl impl;
unsigned readers, writers; unsigned readers, writers;
public: public:
explicit SmartRWMutex() : RWMutexImpl(), readers(0), writers(0) { } explicit SmartRWMutex() : impl(), readers(0), writers(0) { }
bool reader_acquire() { bool lock_shared() {
if (!mt_only || llvm_is_multithreaded()) if (!mt_only || llvm_is_multithreaded())
return RWMutexImpl::reader_acquire(); return impl.reader_acquire();
// Single-threaded debugging code. This would be racy in multithreaded // Single-threaded debugging code. This would be racy in multithreaded
// mode, but provides not sanity checks in single threaded mode. // mode, but provides not sanity checks in single threaded mode.
@ -100,9 +101,9 @@ namespace llvm
return true; return true;
} }
bool reader_release() { bool unlock_shared() {
if (!mt_only || llvm_is_multithreaded()) if (!mt_only || llvm_is_multithreaded())
return RWMutexImpl::reader_release(); return impl.reader_release();
// Single-threaded debugging code. This would be racy in multithreaded // Single-threaded debugging code. This would be racy in multithreaded
// mode, but provides not sanity checks in single threaded mode. // mode, but provides not sanity checks in single threaded mode.
@ -111,9 +112,9 @@ namespace llvm
return true; return true;
} }
bool writer_acquire() { bool lock() {
if (!mt_only || llvm_is_multithreaded()) if (!mt_only || llvm_is_multithreaded())
return RWMutexImpl::writer_acquire(); return impl.writer_acquire();
// Single-threaded debugging code. This would be racy in multithreaded // Single-threaded debugging code. This would be racy in multithreaded
// mode, but provides not sanity checks in single threaded mode. // mode, but provides not sanity checks in single threaded mode.
@ -122,9 +123,9 @@ namespace llvm
return true; return true;
} }
bool writer_release() { bool unlock() {
if (!mt_only || llvm_is_multithreaded()) if (!mt_only || llvm_is_multithreaded())
return RWMutexImpl::writer_release(); return impl.writer_release();
// Single-threaded debugging code. This would be racy in multithreaded // Single-threaded debugging code. This would be racy in multithreaded
// mode, but provides not sanity checks in single threaded mode. // mode, but provides not sanity checks in single threaded mode.
@ -145,11 +146,11 @@ namespace llvm
SmartRWMutex<mt_only>& mutex; SmartRWMutex<mt_only>& mutex;
explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) { explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) {
mutex.reader_acquire(); mutex.lock_shared();
} }
~SmartScopedReader() { ~SmartScopedReader() {
mutex.reader_release(); mutex.unlock_shared();
} }
}; };
typedef SmartScopedReader<false> ScopedReader; typedef SmartScopedReader<false> ScopedReader;
@ -160,11 +161,11 @@ namespace llvm
SmartRWMutex<mt_only>& mutex; SmartRWMutex<mt_only>& mutex;
explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) { explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) {
mutex.writer_acquire(); mutex.lock();
} }
~SmartScopedWriter() { ~SmartScopedWriter() {
mutex.writer_release(); mutex.unlock();
} }
}; };
typedef SmartScopedWriter<false> ScopedWriter; typedef SmartScopedWriter<false> ScopedWriter;

View File

@ -248,14 +248,14 @@ GenericValue Interpreter::callExternalFunction(Function *F,
const std::vector<GenericValue> &ArgVals) { const std::vector<GenericValue> &ArgVals) {
TheInterpreter = this; TheInterpreter = this;
FunctionsLock->acquire(); FunctionsLock->lock();
// Do a lookup to see if the function is in our cache... this should just be a // Do a lookup to see if the function is in our cache... this should just be a
// deferred annotation! // deferred annotation!
std::map<const Function *, ExFunc>::iterator FI = ExportedFunctions->find(F); std::map<const Function *, ExFunc>::iterator FI = ExportedFunctions->find(F);
if (ExFunc Fn = (FI == ExportedFunctions->end()) ? lookupFunction(F) if (ExFunc Fn = (FI == ExportedFunctions->end()) ? lookupFunction(F)
: FI->second) { : FI->second) {
FunctionsLock->release(); FunctionsLock->unlock();
return Fn(F->getFunctionType(), ArgVals); return Fn(F->getFunctionType(), ArgVals);
} }
@ -273,7 +273,7 @@ GenericValue Interpreter::callExternalFunction(Function *F,
RawFn = RF->second; RawFn = RF->second;
} }
FunctionsLock->release(); FunctionsLock->unlock();
GenericValue Result; GenericValue Result;
if (RawFn != 0 && ffiInvoke(RawFn, F, ArgVals, getDataLayout(), Result)) if (RawFn != 0 && ffiInvoke(RawFn, F, ArgVals, getDataLayout(), Result))

View File

@ -162,24 +162,24 @@ static RETSIGTYPE SignalHandler(int Sig) {
sigfillset(&SigMask); sigfillset(&SigMask);
sigprocmask(SIG_UNBLOCK, &SigMask, nullptr); sigprocmask(SIG_UNBLOCK, &SigMask, nullptr);
SignalsMutex.acquire(); SignalsMutex.lock();
RemoveFilesToRemove(); RemoveFilesToRemove();
if (std::find(IntSigs, IntSigsEnd, Sig) != IntSigsEnd) { if (std::find(IntSigs, IntSigsEnd, Sig) != IntSigsEnd) {
if (InterruptFunction) { if (InterruptFunction) {
void (*IF)() = InterruptFunction; void (*IF)() = InterruptFunction;
SignalsMutex.release(); SignalsMutex.unlock();
InterruptFunction = nullptr; InterruptFunction = nullptr;
IF(); // run the interrupt function. IF(); // run the interrupt function.
return; return;
} }
SignalsMutex.release(); SignalsMutex.unlock();
raise(Sig); // Execute the default handler. raise(Sig); // Execute the default handler.
return; return;
} }
SignalsMutex.release(); SignalsMutex.unlock();
// Otherwise if it is a fault (like SEGV) run any handler. // Otherwise if it is a fault (like SEGV) run any handler.
for (unsigned i = 0, e = CallBacksToRun.size(); i != e; ++i) for (unsigned i = 0, e = CallBacksToRun.size(); i != e; ++i)

View File

@ -186,11 +186,11 @@ struct LockMutex : ValueMapConfig<KeyT, MutexT> {
}; };
static void onRAUW(const ExtraData &Data, KeyT Old, KeyT New) { static void onRAUW(const ExtraData &Data, KeyT Old, KeyT New) {
*Data.CalledRAUW = true; *Data.CalledRAUW = true;
EXPECT_FALSE(Data.M->tryacquire()) << "Mutex should already be locked."; EXPECT_FALSE(Data.M->try_lock()) << "Mutex should already be locked.";
} }
static void onDelete(const ExtraData &Data, KeyT Old) { static void onDelete(const ExtraData &Data, KeyT Old) {
*Data.CalledDeleted = true; *Data.CalledDeleted = true;
EXPECT_FALSE(Data.M->tryacquire()) << "Mutex should already be locked."; EXPECT_FALSE(Data.M->try_lock()) << "Mutex should already be locked.";
} }
static MutexT *getMutex(const ExtraData &Data) { return Data.M; } static MutexT *getMutex(const ExtraData &Data) { return Data.M; }
}; };