|
|
|
@ -4,14 +4,16 @@
@@ -4,14 +4,16 @@
|
|
|
|
|
|
|
|
|
|
#include <sync.h> |
|
|
|
|
|
|
|
|
|
#include <set> |
|
|
|
|
#include <util.h> |
|
|
|
|
#include <utilstrencodings.h> |
|
|
|
|
|
|
|
|
|
#include <stdio.h> |
|
|
|
|
|
|
|
|
|
#include <boost/thread.hpp> |
|
|
|
|
|
|
|
|
|
#ifdef DEBUG_LOCKCONTENTION |
|
|
|
|
#if !defined(HAVE_THREAD_LOCAL) |
|
|
|
|
static_assert(false, "thread_local is not supported"); |
|
|
|
|
#endif |
|
|
|
|
void PrintLockContention(const char* pszName, const char* pszFile, int nLine) |
|
|
|
|
{ |
|
|
|
|
LogPrintf("LOCKCONTENTION: %s\n", pszName); |
|
|
|
@ -45,8 +47,8 @@ struct CLockLocation {
@@ -45,8 +47,8 @@ struct CLockLocation {
|
|
|
|
|
return mutexName + " " + sourceFile + ":" + itostr(sourceLine) + (fTry ? " (TRY)" : ""); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool fTry; |
|
|
|
|
private: |
|
|
|
|
bool fTry; |
|
|
|
|
std::string mutexName; |
|
|
|
|
std::string sourceFile; |
|
|
|
|
int sourceLine; |
|
|
|
@ -67,10 +69,10 @@ struct LockData {
@@ -67,10 +69,10 @@ struct LockData {
|
|
|
|
|
|
|
|
|
|
LockOrders lockorders; |
|
|
|
|
InvLockOrders invlockorders; |
|
|
|
|
boost::mutex dd_mutex; |
|
|
|
|
std::mutex dd_mutex; |
|
|
|
|
} static lockdata; |
|
|
|
|
|
|
|
|
|
boost::thread_specific_ptr<LockStack> lockstack; |
|
|
|
|
static thread_local std::unique_ptr<LockStack> lockstack; |
|
|
|
|
|
|
|
|
|
static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch, const LockStack& s1, const LockStack& s2) |
|
|
|
|
{ |
|
|
|
@ -100,12 +102,12 @@ static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch,
@@ -100,12 +102,12 @@ static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch,
|
|
|
|
|
|
|
|
|
|
static void push_lock(void* c, const CLockLocation& locklocation) |
|
|
|
|
{ |
|
|
|
|
if (lockstack.get() == nullptr) |
|
|
|
|
if (!lockstack) |
|
|
|
|
lockstack.reset(new LockStack); |
|
|
|
|
|
|
|
|
|
boost::unique_lock<boost::mutex> lock(lockdata.dd_mutex); |
|
|
|
|
std::lock_guard<std::mutex> lock(lockdata.dd_mutex); |
|
|
|
|
|
|
|
|
|
(*lockstack).push_back(std::make_pair(c, locklocation)); |
|
|
|
|
lockstack->push_back(std::make_pair(c, locklocation)); |
|
|
|
|
|
|
|
|
|
for (const std::pair<void*, CLockLocation> & i : (*lockstack)) { |
|
|
|
|
if (i.first == c) |
|
|
|
@ -171,7 +173,7 @@ void DeleteLock(void* cs)
@@ -171,7 +173,7 @@ void DeleteLock(void* cs)
|
|
|
|
|
// We're already shutting down.
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
boost::unique_lock<boost::mutex> lock(lockdata.dd_mutex); |
|
|
|
|
std::lock_guard<std::mutex> lock(lockdata.dd_mutex); |
|
|
|
|
std::pair<void*, void*> item = std::make_pair(cs, nullptr); |
|
|
|
|
LockOrders::iterator it = lockdata.lockorders.lower_bound(item); |
|
|
|
|
while (it != lockdata.lockorders.end() && it->first.first == cs) { |
|
|
|
|