mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-14 14:24:05 +00:00
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:
@ -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();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
|
@ -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))
|
||||||
|
@ -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)
|
||||||
|
@ -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; }
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user