Skip to content

Commit

Permalink
Reduce cs_main locks during modal overlay by adding an atomic cache
Browse files Browse the repository at this point in the history
  • Loading branch information
jonasschnelli committed May 31, 2017
1 parent 0aee4a1 commit 1e936d7
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 12 deletions.
35 changes: 25 additions & 10 deletions src/qt/clientmodel.cpp
Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
8 changes: 6 additions & 2 deletions src/qt/clientmodel.h
Expand Up @@ -51,8 +51,8 @@ class ClientModel : public QObject
//! 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
Expand Down Expand Up @@ -81,6 +81,10 @@ class ClientModel : public QObject
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;
Expand Down

0 comments on commit 1e936d7

Please sign in to comment.