Changeset View
Changeset View
Standalone View
Standalone View
src/sync.h
// Copyright (c) 2009-2010 Satoshi Nakamoto | // Copyright (c) 2009-2010 Satoshi Nakamoto | ||||
// Copyright (c) 2009-2016 The Bitcoin Core developers | // Copyright (c) 2009-2016 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#ifndef BITCOIN_SYNC_H | #ifndef BITCOIN_SYNC_H | ||||
#define BITCOIN_SYNC_H | #define BITCOIN_SYNC_H | ||||
#ifdef DEBUG_LOCKCONTENTION | |||||
#include <logging.h> | |||||
#include <logging/timer.h> | |||||
#endif | |||||
#include <threadsafety.h> | #include <threadsafety.h> | ||||
#include <util/macros.h> | #include <util/macros.h> | ||||
#include <condition_variable> | #include <condition_variable> | ||||
#include <mutex> | #include <mutex> | ||||
#include <string> | #include <string> | ||||
#include <thread> | #include <thread> | ||||
▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Lines | |||||
* Wrapped mutex: supports recursive locking, but no waiting | * Wrapped mutex: supports recursive locking, but no waiting | ||||
* TODO: We should move away from using the recursive lock by default. | * TODO: We should move away from using the recursive lock by default. | ||||
*/ | */ | ||||
using RecursiveMutex = AnnotatedMixin<std::recursive_mutex>; | using RecursiveMutex = AnnotatedMixin<std::recursive_mutex>; | ||||
/** Wrapped mutex: supports waiting but not recursive locking */ | /** Wrapped mutex: supports waiting but not recursive locking */ | ||||
typedef AnnotatedMixin<std::mutex> Mutex; | typedef AnnotatedMixin<std::mutex> Mutex; | ||||
#ifdef DEBUG_LOCKCONTENTION | |||||
void PrintLockContention(const char *pszName, const char *pszFile, int nLine); | |||||
#endif | |||||
/** Wrapper around std::unique_lock style lock for Mutex. */ | /** Wrapper around std::unique_lock style lock for Mutex. */ | ||||
template <typename Mutex, typename Base = typename Mutex::UniqueLock> | template <typename Mutex, typename Base = typename Mutex::UniqueLock> | ||||
class SCOPED_LOCKABLE UniqueLock : public Base { | class SCOPED_LOCKABLE UniqueLock : public Base { | ||||
private: | private: | ||||
void Enter(const char *pszName, const char *pszFile, int nLine) { | void Enter(const char *pszName, const char *pszFile, int nLine) { | ||||
EnterCritical(pszName, pszFile, nLine, (void *)(Base::mutex())); | EnterCritical(pszName, pszFile, nLine, (void *)(Base::mutex())); | ||||
#ifdef DEBUG_LOCKCONTENTION | #ifdef DEBUG_LOCKCONTENTION | ||||
if (!Base::try_lock()) { | if (Base::try_lock()) { | ||||
PrintLockContention(pszName, pszFile, nLine); | return; | ||||
#endif | |||||
Base::lock(); | |||||
#ifdef DEBUG_LOCKCONTENTION | |||||
} | } | ||||
LOG_TIME_MICROS_WITH_CATEGORY( | |||||
strprintf("lock contention %s, %s:%d", pszName, pszFile, nLine), | |||||
BCLog::LOCK); | |||||
#endif | #endif | ||||
Base::lock(); | |||||
} | } | ||||
bool TryEnter(const char *pszName, const char *pszFile, int nLine) { | bool TryEnter(const char *pszName, const char *pszFile, int nLine) { | ||||
EnterCritical(pszName, pszFile, nLine, (void *)(Base::mutex()), true); | EnterCritical(pszName, pszFile, nLine, (void *)(Base::mutex()), true); | ||||
Base::try_lock(); | Base::try_lock(); | ||||
if (!Base::owns_lock()) { | if (!Base::owns_lock()) { | ||||
LeaveCritical(); | LeaveCritical(); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 211 Lines • Show Last 20 Lines |