Changeset View
Changeset View
Standalone View
Standalone View
src/sync.cpp
Show All 10 Lines | |||||
#include <set> | #include <set> | ||||
#ifdef DEBUG_LOCKCONTENTION | #ifdef DEBUG_LOCKCONTENTION | ||||
#if !defined(HAVE_THREAD_LOCAL) | #if !defined(HAVE_THREAD_LOCAL) | ||||
static_assert(false, "thread_local is not supported"); | static_assert(false, "thread_local is not supported"); | ||||
#endif | #endif | ||||
void PrintLockContention(const char *pszName, const char *pszFile, int nLine) { | void PrintLockContention(const char *pszName, const char *pszFile, int nLine) { | ||||
LogPrintf("LOCKCONTENTION: %s\n", pszName); | LogPrint(BCLog::SYNC, "LOCKCONTENTION: %s\n", pszName); | ||||
LogPrintf("Locker: %s:%d\n", pszFile, nLine); | LogPrint(BCLog::SYNC, "Locker: %s:%d\n", pszFile, nLine); | ||||
} | } | ||||
#endif /* DEBUG_LOCKCONTENTION */ | #endif /* DEBUG_LOCKCONTENTION */ | ||||
#ifdef DEBUG_LOCKORDER | #ifdef DEBUG_LOCKORDER | ||||
// | // | ||||
// Early deadlock detection. | // Early deadlock detection. | ||||
// Problem being solved: | // Problem being solved: | ||||
// Thread 1 locks A, then B, then C | // Thread 1 locks A, then B, then C | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | struct LockData { | ||||
std::mutex dd_mutex; | std::mutex dd_mutex; | ||||
} static lockdata; | } static lockdata; | ||||
static thread_local std::unique_ptr<LockStack> lockstack; | static thread_local std::unique_ptr<LockStack> lockstack; | ||||
static void | static void | ||||
potential_deadlock_detected(const std::pair<void *, void *> &mismatch, | potential_deadlock_detected(const std::pair<void *, void *> &mismatch, | ||||
const LockStack &s1, const LockStack &s2) { | const LockStack &s1, const LockStack &s2) { | ||||
LogPrintf("POTENTIAL DEADLOCK DETECTED\n"); | LogPrint(BCLog::SYNC, "POTENTIAL DEADLOCK DETECTED\n"); | ||||
LogPrintf("Previous lock order was:\n"); | LogPrint(BCLog::SYNC, "Previous lock order was:\n"); | ||||
for (const std::pair<void *, CLockLocation> &i : s2) { | for (const std::pair<void *, CLockLocation> &i : s2) { | ||||
if (i.first == mismatch.first) { | if (i.first == mismatch.first) { | ||||
LogPrintf(" (1)"); | LogPrint(BCLog::SYNC, " (1)"); | ||||
} | } | ||||
if (i.first == mismatch.second) { | if (i.first == mismatch.second) { | ||||
LogPrintf(" (2)"); | LogPrint(BCLog::SYNC, " (2)"); | ||||
} | } | ||||
LogPrintf(" %s\n", i.second.ToString()); | LogPrint(BCLog::SYNC, " %s\n", i.second.ToString()); | ||||
} | } | ||||
LogPrintf("Current lock order is:\n"); | LogPrint(BCLog::SYNC, "Current lock order is:\n"); | ||||
for (const std::pair<void *, CLockLocation> &i : s1) { | for (const std::pair<void *, CLockLocation> &i : s1) { | ||||
if (i.first == mismatch.first) { | if (i.first == mismatch.first) { | ||||
LogPrintf(" (1)"); | LogPrint(BCLog::SYNC, " (1)"); | ||||
} | } | ||||
if (i.first == mismatch.second) { | if (i.first == mismatch.second) { | ||||
LogPrintf(" (2)"); | LogPrint(BCLog::SYNC, " (2)"); | ||||
} | } | ||||
LogPrintf(" %s\n", i.second.ToString()); | LogPrint(BCLog::SYNC, " %s\n", i.second.ToString()); | ||||
} | } | ||||
if (g_debug_lockorder_abort) { | if (g_debug_lockorder_abort) { | ||||
fprintf(stderr, "Assertion failed: detected inconsistent lock order at " | fprintf(stderr, "Assertion failed: detected inconsistent lock order at " | ||||
"%s:%i, details in debug log.\n", | "%s:%i, details in debug log.\n", | ||||
__FILE__, __LINE__); | __FILE__, __LINE__); | ||||
abort(); | abort(); | ||||
} | } | ||||
throw std::logic_error("potential deadlock detected"); | throw std::logic_error("potential deadlock detected"); | ||||
▲ Show 20 Lines • Show All 97 Lines • Show Last 20 Lines |