From 24a53756eb3849d9cea0ef035f963048ad6f211a Mon Sep 17 00:00:00 2001 From: Guilherme Lawless Date: Wed, 2 Sep 2020 09:37:45 +0100 Subject: [PATCH] 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 --- nano/core_test/active_transactions.cpp | 13 +++++++++++++ nano/node/active_transactions.cpp | 5 +++-- nano/node/active_transactions.hpp | 2 +- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/nano/core_test/active_transactions.cpp b/nano/core_test/active_transactions.cpp index c559844f..a8794fac 100644 --- a/nano/core_test/active_transactions.cpp +++ b/nano/core_test/active_transactions.cpp @@ -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 update_received (false); + node.observers.difficulty.add ([& mutex = node.active.mutex, &update_received](uint64_t difficulty_a) { + nano::unique_lock lock (mutex, std::defer_lock); + EXPECT_TRUE (lock.try_lock ()); + update_received = true; + }); + ASSERT_TIMELY (3s, update_received); +} diff --git a/nano/node/active_transactions.cpp b/nano/node/active_transactions.cpp index 2af15693..049b09c8 100644 --- a/nano/node/active_transactions.cpp +++ b/nano/node/active_transactions.cpp @@ -882,7 +882,9 @@ void nano::active_transactions::update_active_multiplier (nano::unique_lock= 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 lock (mutex); - return trended_active_multiplier; + return trended_active_multiplier.load (); } // List of active blocks in elections diff --git a/nano/node/active_transactions.hpp b/nano/node/active_transactions.hpp index ee39ddac..b1d218de 100644 --- a/nano/node/active_transactions.hpp +++ b/nano/node/active_transactions.hpp @@ -199,7 +199,7 @@ public: nano::node & node; mutable std::mutex mutex; boost::circular_buffer multipliers_cb; - double trended_active_multiplier; + std::atomic trended_active_multiplier; size_t priority_cementable_frontiers_size (); size_t priority_wallet_cementable_frontiers_size (); boost::circular_buffer difficulty_trend ();