9 #ifdef DEBUG_LOCKCONTENTION
17 #include <condition_variable>
55 #ifdef DEBUG_LOCKORDER
56 void EnterCritical(
const char *pszName,
const char *pszFile,
int nLine,
57 void *
cs,
bool fTry =
false);
60 const char *file,
int line);
61 std::string LocksHeld();
62 template <
typename MutexType>
65 template <
typename MutexType>
76 extern bool g_debug_lockorder_abort;
78 inline void EnterCritical(
const char *pszName,
const char *pszFile,
int nLine,
79 void *
cs,
bool fTry =
false) {}
82 const char *guardname,
const char *file,
84 template <
typename MutexType>
86 int nLine, MutexType *
cs)
88 template <
typename MutexType>
96 #define AssertLockHeld(cs) AssertLockHeldInternal(#cs, __FILE__, __LINE__, &cs)
97 #define AssertLockNotHeld(cs) \
98 AssertLockNotHeldInternal(#cs, __FILE__, __LINE__, &cs)
113 return PARENT::try_lock();
136 template <
typename Mutex,
typename Base =
typename Mutex::UniqueLock>
139 void Enter(
const char *pszName,
const char *pszFile,
int nLine) {
140 EnterCritical(pszName, pszFile, nLine, (
void *)(Base::mutex()));
141 #ifdef DEBUG_LOCKCONTENTION
142 if (Base::try_lock()) {
146 strprintf(
"lock contention %s, %s:%d", pszName, pszFile, nLine),
152 bool TryEnter(
const char *pszName,
const char *pszFile,
int nLine) {
153 EnterCritical(pszName, pszFile, nLine, (
void *)(Base::mutex()),
true);
155 if (!Base::owns_lock()) {
158 return Base::owns_lock();
164 : Base(mutexIn, std::defer_lock) {
166 TryEnter(pszName, pszFile, nLine);
168 Enter(pszName, pszFile, nLine);
178 *
static_cast<Base *
>(
this) = Base(*pmutexIn, std::defer_lock);
180 TryEnter(pszName, pszFile, nLine);
182 Enter(pszName, pszFile, nLine);
187 if (Base::owns_lock()) {
192 operator bool() {
return Base::owns_lock(); }
206 const char *_file,
int _line)
207 : lock(_lock), file(_file), line(_line) {
218 (
void *)lock.mutex());
235 #define REVERSE_LOCK(g) \
236 typename std::decay<decltype(g)>::type::reverse_lock PASTE2( \
237 revlock, __COUNTER__)(g, #g, __FILE__, __LINE__)
239 template <
typename MutexArg>
241 typename std::remove_pointer<MutexArg>::type>::type>;
244 DebugLock<decltype(cs)> PASTE2(criticalblock, \
245 __COUNTER__)(cs, #cs, __FILE__, __LINE__)
246 #define LOCK2(cs1, cs2) \
247 DebugLock<decltype(cs1)> criticalblock1(cs1, #cs1, __FILE__, __LINE__); \
248 DebugLock<decltype(cs2)> criticalblock2(cs2, #cs2, __FILE__, __LINE__);
249 #define TRY_LOCK(cs, name) \
250 DebugLock<decltype(cs)> name(cs, #cs, __FILE__, __LINE__, true)
251 #define WAIT_LOCK(cs, name) \
252 DebugLock<decltype(cs)> name(cs, #cs, __FILE__, __LINE__)
254 #define ENTER_CRITICAL_SECTION(cs) \
256 EnterCritical(#cs, __FILE__, __LINE__, (void *)(&cs)); \
260 #define LEAVE_CRITICAL_SECTION(cs) \
262 std::string lockname; \
263 CheckLastCritical((void *)(&cs), lockname, #cs, __FILE__, __LINE__); \
276 #define WITH_LOCK(cs, code) \
292 std::unique_lock<std::mutex> lock(
mutex);
298 std::lock_guard<std::mutex> lock(
mutex);
308 std::lock_guard<std::mutex> lock(
mutex);
Template mixin that adds -Wthread-safety locking annotations and lock order checking to a subset of t...
bool try_lock() EXCLUSIVE_TRYLOCK_FUNCTION(true)
void unlock() UNLOCK_FUNCTION()
void lock() EXCLUSIVE_LOCK_FUNCTION()
RAII-style semaphore lock.
CSemaphoreGrant(CSemaphore &sema, bool fTry=false)
void MoveTo(CSemaphoreGrant &grant)
std::condition_variable condition
An RAII-style reverse lock.
reverse_lock(reverse_lock const &)
reverse_lock & operator=(reverse_lock const &)
reverse_lock(UniqueLock &_lock, const char *_guardname, const char *_file, int _line)
Wrapper around std::unique_lock style lock for Mutex.
bool TryEnter(const char *pszName, const char *pszFile, int nLine)
~UniqueLock() UNLOCK_FUNCTION()
UniqueLock(Mutex &mutexIn, const char *pszName, const char *pszFile, int nLine, bool fTry=false) EXCLUSIVE_LOCK_FUNCTION(mutexIn)
void Enter(const char *pszName, const char *pszFile, int nLine)
UniqueLock(Mutex *pmutexIn, const char *pszName, const char *pszFile, int nLine, bool fTry=false) EXCLUSIVE_LOCK_FUNCTION(pmutexIn)
void AssertLockHeldInternal(const char *pszName, const char *pszFile, int nLine, MutexType *cs) EXCLUSIVE_LOCKS_REQUIRED(cs)
void DeleteLock(void *cs)
AnnotatedMixin< std::mutex > Mutex
Wrapped mutex: supports waiting but not recursive locking.
void CheckLastCritical(void *cs, std::string &lockname, const char *guardname, const char *file, int line)
void EnterCritical(const char *pszName, const char *pszFile, int nLine, void *cs, bool fTry=false)
void AssertLockNotHeldInternal(const char *pszName, const char *pszFile, int nLine, MutexType *cs) LOCKS_EXCLUDED(cs)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
#define EXCLUSIVE_TRYLOCK_FUNCTION(...)
#define LOCKS_EXCLUDED(...)
#define EXCLUSIVE_LOCK_FUNCTION(...)
#define UNLOCK_FUNCTION(...)
#define LOG_TIME_MICROS_WITH_CATEGORY(end_msg, log_category)