aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Schnelli <dev@jonasschnelli.ch>2017-04-19 18:45:11 +0200
committerJonas Schnelli <dev@jonasschnelli.ch>2017-05-31 10:53:46 +0200
commit1e936d7e8760de230377f4e4af5eb68368f1f550 (patch)
tree1401150ebd408ce6b5ff2d8f8c1025396e3704a4
parent0aee4a132b6d3be276503c517cb2b7f07d774bf6 (diff)
downloadbitcoin-1e936d7e8760de230377f4e4af5eb68368f1f550.tar.xz
Reduce cs_main locks during modal overlay by adding an atomic cache
-rw-r--r--src/qt/clientmodel.cpp35
-rw-r--r--src/qt/clientmodel.h8
2 files changed, 31 insertions, 12 deletions
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index bb10e49422..9a8af01a32 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -36,6 +36,8 @@ ClientModel::ClientModel(OptionsModel *_optionsModel, QObject *parent) :
banTableModel(0),
pollTimer(0)
{
+ cachedBestHeaderHeight = -1;
+ cachedBestHeaderTime = -1;
peerTableModel = new PeerTableModel(this);
banTableModel = new BanTableModel(this);
pollTimer = new QTimer(this);
@@ -72,20 +74,28 @@ int ClientModel::getNumBlocks() const
return chainActive.Height();
}
-int ClientModel::getHeaderTipHeight() const
+int ClientModel::getHeaderTipHeight()
{
- LOCK(cs_main);
- if (!pindexBestHeader)
- return 0;
- return pindexBestHeader->nHeight;
+ if (cachedBestHeaderHeight == -1) {
+ // make sure we initially populate the cache via a cs_main lock
+ // otherwise we need to wait for a tip update
+ LOCK(cs_main);
+ if (pindexBestHeader) {
+ cachedBestHeaderHeight = pindexBestHeader->nHeight;
+ }
+ }
+ return cachedBestHeaderHeight;
}
-int64_t ClientModel::getHeaderTipTime() const
+int64_t ClientModel::getHeaderTipTime()
{
- LOCK(cs_main);
- if (!pindexBestHeader)
- return 0;
- return pindexBestHeader->GetBlockTime();
+ if (cachedBestHeaderTime == -1) {
+ LOCK(cs_main);
+ if (pindexBestHeader) {
+ cachedBestHeaderTime = pindexBestHeader->GetBlockTime();
+ }
+ }
+ return cachedBestHeaderTime;
}
quint64 ClientModel::getTotalBytesRecv() const
@@ -283,6 +293,11 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CB
int64_t& nLastUpdateNotification = fHeader ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification;
+ if (fHeader) {
+ // cache best headers time and height to reduce future cs_main locks
+ clientmodel->cachedBestHeaderHeight = pIndex->nHeight;
+ clientmodel->cachedBestHeaderTime = pIndex->GetBlockTime();
+ }
// if we are in-sync, update the UI regardless of last update time
if (!initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) {
//pass a async signal to the UI thread
diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h
index 2c10e633b8..6f7077dad6 100644
--- a/src/qt/clientmodel.h
+++ b/src/qt/clientmodel.h
@@ -51,8 +51,8 @@ public:
//! Return number of connections, default is in- and outbound (total)
int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const;
int getNumBlocks() const;
- int getHeaderTipHeight() const;
- int64_t getHeaderTipTime() const;
+ int getHeaderTipHeight();
+ int64_t getHeaderTipTime();
//! Return number of transactions in the mempool
long getMempoolSize() const;
//! Return the dynamic memory usage of the mempool
@@ -81,6 +81,10 @@ public:
QString formatClientStartupTime() const;
QString dataDir() const;
+ // caches for the best header
+ std::atomic<int> cachedBestHeaderHeight;
+ std::atomic<int64_t> cachedBestHeaderTime;
+
private:
OptionsModel *optionsModel;
PeerTableModel *peerTableModel;