Skip to content

Commit 7148f5e

Browse files
committed
Reduce cs_main locks during modal overlay by adding an atomic cache
1 parent c91ca0a commit 7148f5e

File tree

2 files changed

+31
-12
lines changed

2 files changed

+31
-12
lines changed

src/qt/clientmodel.cpp

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ ClientModel::ClientModel(OptionsModel *_optionsModel, QObject *parent) :
3636
banTableModel(0),
3737
pollTimer(0)
3838
{
39+
cachedBestHeaderHeight = -1;
40+
cachedBestHeaderTime = -1;
3941
peerTableModel = new PeerTableModel(this);
4042
banTableModel = new BanTableModel(this);
4143
pollTimer = new QTimer(this);
@@ -72,20 +74,28 @@ int ClientModel::getNumBlocks() const
7274
return chainActive.Height();
7375
}
7476

75-
int ClientModel::getHeaderTipHeight() const
77+
int ClientModel::getHeaderTipHeight()
7678
{
77-
LOCK(cs_main);
78-
if (!pindexBestHeader)
79-
return 0;
80-
return pindexBestHeader->nHeight;
79+
if (cachedBestHeaderHeight == -1) {
80+
// make sure we initially populate the cache via a cs_main lock
81+
// otherwise we need to wait for a tip update
82+
LOCK(cs_main);
83+
if (pindexBestHeader) {
84+
cachedBestHeaderHeight = pindexBestHeader->nHeight;
85+
}
86+
}
87+
return cachedBestHeaderHeight;
8188
}
8289

83-
int64_t ClientModel::getHeaderTipTime() const
90+
int64_t ClientModel::getHeaderTipTime()
8491
{
85-
LOCK(cs_main);
86-
if (!pindexBestHeader)
87-
return 0;
88-
return pindexBestHeader->GetBlockTime();
92+
if (cachedBestHeaderTime == -1) {
93+
LOCK(cs_main);
94+
if (pindexBestHeader) {
95+
cachedBestHeaderTime = pindexBestHeader->GetBlockTime();
96+
}
97+
}
98+
return cachedBestHeaderTime;
8999
}
90100

91101
quint64 ClientModel::getTotalBytesRecv() const
@@ -283,6 +293,11 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CB
283293

284294
int64_t& nLastUpdateNotification = fHeader ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification;
285295

296+
if (fHeader) {
297+
// cache best headers time and height to reduce future cs_main locks
298+
clientmodel->cachedBestHeaderHeight = pIndex->nHeight;
299+
clientmodel->cachedBestHeaderTime = pIndex->GetBlockTime();
300+
}
286301
// if we are in-sync, update the UI regardless of last update time
287302
if (!initialSync || now - nLastUpdateNotification > MODEL_UPDATE_DELAY) {
288303
//pass a async signal to the UI thread

src/qt/clientmodel.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ class ClientModel : public QObject
5151
//! Return number of connections, default is in- and outbound (total)
5252
int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const;
5353
int getNumBlocks() const;
54-
int getHeaderTipHeight() const;
55-
int64_t getHeaderTipTime() const;
54+
int getHeaderTipHeight();
55+
int64_t getHeaderTipTime();
5656
//! Return number of transactions in the mempool
5757
long getMempoolSize() const;
5858
//! Return the dynamic memory usage of the mempool
@@ -81,6 +81,10 @@ class ClientModel : public QObject
8181
QString formatClientStartupTime() const;
8282
QString dataDir() const;
8383

84+
// caches for the best header
85+
std::atomic<int> cachedBestHeaderHeight;
86+
std::atomic<int64_t> cachedBestHeaderTime;
87+
8488
private:
8589
OptionsModel *optionsModel;
8690
PeerTableModel *peerTableModel;

0 commit comments

Comments
 (0)