Relax mutex requirement for retrieving active difficulty (#2901)

* Make active multiplier an atomic to avoid an active mutex lock

* Add failing test to ensure the active mutex is not held in the difficulty observer update

* Unlock active mutex updating difficulty observers
This commit is contained in:
Guilherme Lawless 2020-09-02 09:37:45 +01:00 committed by GitHub
commit 24a53756eb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 3 deletions

View file

@ -1434,3 +1434,16 @@ TEST (active_transactions, activate_inactive)
// The first block was not active so no activation takes place
ASSERT_FALSE (node.active.active (open->qualified_root ()) || node.block_confirmed_or_being_confirmed (node.store.tx_begin_read (), open->hash ()));
}
TEST (active_transactions, difficulty_update_observer)
{
nano::system system (1);
auto & node (*system.nodes[0]);
std::atomic<bool> update_received (false);
node.observers.difficulty.add ([& mutex = node.active.mutex, &update_received](uint64_t difficulty_a) {
nano::unique_lock<std::mutex> lock (mutex, std::defer_lock);
EXPECT_TRUE (lock.try_lock ());
update_received = true;
});
ASSERT_TIMELY (3s, update_received);
}

View file

@ -882,7 +882,9 @@ void nano::active_transactions::update_active_multiplier (nano::unique_lock<std:
debug_assert (difficulty >= node.network_params.network.publish_thresholds.entry);
trended_active_multiplier = avg_multiplier;
lock_a.unlock ();
node.observers.difficulty.notify (difficulty);
lock_a.lock ();
}
uint64_t nano::active_transactions::active_difficulty ()
@ -912,8 +914,7 @@ uint64_t nano::active_transactions::limited_active_difficulty (nano::work_versio
double nano::active_transactions::active_multiplier ()
{
nano::lock_guard<std::mutex> lock (mutex);
return trended_active_multiplier;
return trended_active_multiplier.load ();
}
// List of active blocks in elections

View file

@ -199,7 +199,7 @@ public:
nano::node & node;
mutable std::mutex mutex;
boost::circular_buffer<double> multipliers_cb;
double trended_active_multiplier;
std::atomic<double> trended_active_multiplier;
size_t priority_cementable_frontiers_size ();
size_t priority_wallet_cementable_frontiers_size ();
boost::circular_buffer<double> difficulty_trend ();