diff options
author | Jonas Schnelli <dev@jonasschnelli.ch> | 2017-04-19 18:45:11 +0200 |
---|---|---|
committer | Jonas Schnelli <dev@jonasschnelli.ch> | 2017-05-31 10:53:46 +0200 |
commit | 1e936d7e8760de230377f4e4af5eb68368f1f550 (patch) | |
tree | 1401150ebd408ce6b5ff2d8f8c1025396e3704a4 /src | |
parent | 0aee4a132b6d3be276503c517cb2b7f07d774bf6 (diff) |
Reduce cs_main locks during modal overlay by adding an atomic cache
Diffstat (limited to 'src')
-rw-r--r-- | src/qt/clientmodel.cpp | 35 | ||||
-rw-r--r-- | src/qt/clientmodel.h | 8 |
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; |