]> Git Repo - VerusCoin.git/blame - src/sync.cpp
Build fix
[VerusCoin.git] / src / sync.cpp
CommitLineData
f914f1a7 1// Copyright (c) 2011-2012 The Bitcoin Core developers
78253fcb 2// Distributed under the MIT software license, see the accompanying
bc909a7a 3// file COPYING or https://www.opensource.org/licenses/mit-license.php .
7f3ccb59
PW
4
5#include "sync.h"
51ed9ec9 6
660ff174 7#include "util.h"
d2d6f708 8#include "utilstrencodings.h"
7f3ccb59 9
611116d4
PK
10#include <stdio.h>
11
660ff174 12#include <boost/foreach.hpp>
d2d6f708 13#include <boost/thread.hpp>
7f3ccb59 14
4d009243
MC
15#ifdef DEBUG_LOCKCONTENTION
16void PrintLockContention(const char* pszName, const char* pszFile, int nLine)
17{
881a85a2
GA
18 LogPrintf("LOCKCONTENTION: %s\n", pszName);
19 LogPrintf("Locker: %s:%d\n", pszFile, nLine);
4d009243
MC
20}
21#endif /* DEBUG_LOCKCONTENTION */
22
7f3ccb59
PW
23#ifdef DEBUG_LOCKORDER
24//
25// Early deadlock detection.
26// Problem being solved:
27// Thread 1 locks A, then B, then C
28// Thread 2 locks D, then C, then A
29// --> may result in deadlock between the two threads, depending on when they run.
30// Solution implemented here:
31// Keep track of pairs of locks: (A before B), (A before C), etc.
e7494052 32// Complain if any thread tries to lock in a different order.
7f3ccb59
PW
33//
34
20e01b1a 35struct CLockLocation {
8e4bc69d 36 CLockLocation(const char* pszName, const char* pszFile, int nLine, bool fTryIn)
7f3ccb59
PW
37 {
38 mutexName = pszName;
39 sourceFile = pszFile;
40 sourceLine = nLine;
8e4bc69d 41 fTry = fTryIn;
7f3ccb59
PW
42 }
43
44 std::string ToString() const
45 {
8e4bc69d 46 return mutexName + " " + sourceFile + ":" + itostr(sourceLine) + (fTry ? " (TRY)" : "");
7f3ccb59
PW
47 }
48
c649637b
GA
49 std::string MutexName() const { return mutexName; }
50
8e4bc69d 51 bool fTry;
7f3ccb59
PW
52private:
53 std::string mutexName;
54 std::string sourceFile;
55 int sourceLine;
56};
57
20e01b1a 58typedef std::vector<std::pair<void*, CLockLocation> > LockStack;
7f3ccb59 59
660ff174 60static boost::mutex dd_mutex;
7f3ccb59
PW
61static std::map<std::pair<void*, void*>, LockStack> lockorders;
62static boost::thread_specific_ptr<LockStack> lockstack;
63
64
65static void potential_deadlock_detected(const std::pair<void*, void*>& mismatch, const LockStack& s1, const LockStack& s2)
66{
8e4bc69d
MC
67 // We attempt to not assert on probably-not deadlocks by assuming that
68 // a try lock will immediately have otherwise bailed if it had
69 // failed to get the lock
70 // We do this by, for the locks which triggered the potential deadlock,
71 // in either lockorder, checking that the second of the two which is locked
72 // is only a TRY_LOCK, ignoring locks if they are reentrant.
73 bool firstLocked = false;
74 bool secondLocked = false;
75 bool onlyMaybeDeadlock = false;
76
881a85a2
GA
77 LogPrintf("POTENTIAL DEADLOCK DETECTED\n");
78 LogPrintf("Previous lock order was:\n");
20e01b1a 79 BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, s2) {
8e4bc69d 80 if (i.first == mismatch.first) {
20e01b1a 81 LogPrintf(" (1)");
8e4bc69d
MC
82 if (!firstLocked && secondLocked && i.second.fTry)
83 onlyMaybeDeadlock = true;
84 firstLocked = true;
85 }
86 if (i.first == mismatch.second) {
20e01b1a 87 LogPrintf(" (2)");
8e4bc69d
MC
88 if (!secondLocked && firstLocked && i.second.fTry)
89 onlyMaybeDeadlock = true;
90 secondLocked = true;
91 }
7d9d134b 92 LogPrintf(" %s\n", i.second.ToString());
7f3ccb59 93 }
8e4bc69d
MC
94 firstLocked = false;
95 secondLocked = false;
881a85a2 96 LogPrintf("Current lock order is:\n");
20e01b1a 97 BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, s1) {
8e4bc69d 98 if (i.first == mismatch.first) {
20e01b1a 99 LogPrintf(" (1)");
8e4bc69d
MC
100 if (!firstLocked && secondLocked && i.second.fTry)
101 onlyMaybeDeadlock = true;
102 firstLocked = true;
103 }
104 if (i.first == mismatch.second) {
20e01b1a 105 LogPrintf(" (2)");
8e4bc69d
MC
106 if (!secondLocked && firstLocked && i.second.fTry)
107 onlyMaybeDeadlock = true;
108 secondLocked = true;
109 }
7d9d134b 110 LogPrintf(" %s\n", i.second.ToString());
7f3ccb59 111 }
8e4bc69d 112 assert(onlyMaybeDeadlock);
7f3ccb59
PW
113}
114
115static void push_lock(void* c, const CLockLocation& locklocation, bool fTry)
116{
7f3ccb59
PW
117 if (lockstack.get() == NULL)
118 lockstack.reset(new LockStack);
119
7f3ccb59
PW
120 dd_mutex.lock();
121
122 (*lockstack).push_back(std::make_pair(c, locklocation));
123
660ff174 124 if (!fTry) {
20e01b1a
PW
125 BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, (*lockstack)) {
126 if (i.first == c)
127 break;
660ff174
PW
128
129 std::pair<void*, void*> p1 = std::make_pair(i.first, c);
130 if (lockorders.count(p1))
131 continue;
132 lockorders[p1] = (*lockstack);
133
134 std::pair<void*, void*> p2 = std::make_pair(c, i.first);
8e4bc69d 135 if (lockorders.count(p2))
660ff174 136 potential_deadlock_detected(p1, lockorders[p2], lockorders[p1]);
7f3ccb59
PW
137 }
138 }
139 dd_mutex.unlock();
140}
141
142static void pop_lock()
143{
7f3ccb59
PW
144 dd_mutex.lock();
145 (*lockstack).pop_back();
146 dd_mutex.unlock();
147}
148
149void EnterCritical(const char* pszName, const char* pszFile, int nLine, void* cs, bool fTry)
150{
8e4bc69d 151 push_lock(cs, CLockLocation(pszName, pszFile, nLine, fTry), fTry);
7f3ccb59
PW
152}
153
154void LeaveCritical()
155{
156 pop_lock();
157}
158
c649637b
GA
159std::string LocksHeld()
160{
161 std::string result;
20e01b1a 162 BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, *lockstack)
c649637b
GA
163 result += i.second.ToString() + std::string("\n");
164 return result;
165}
166
20e01b1a 167void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, void* cs)
c649637b 168{
20e01b1a
PW
169 BOOST_FOREACH (const PAIRTYPE(void*, CLockLocation) & i, *lockstack)
170 if (i.first == cs)
171 return;
172 fprintf(stderr, "Assertion failed: lock %s not held in %s:%i; locks held:\n%s", pszName, pszFile, nLine, LocksHeld().c_str());
ca4cf5cf 173 abort();
c649637b
GA
174}
175
7f3ccb59 176#endif /* DEBUG_LOCKORDER */
This page took 0.26977 seconds and 4 git commands to generate.