Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow filtering a specific mutex for tracking with NANO_TIMED_LOCKS #2765

Merged
merged 12 commits into from
Mar 4, 2021
28 changes: 28 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,33 @@ set(NANO_TIMED_LOCKS
set(NANO_TIMED_LOCKS_IGNORE_BLOCKED
OFF
CACHE BOOL "")
set(NANO_TIMED_LOCKS_FILTER
""
CACHE
STRING
"Selects which mutex should be the only one to have stacktraces generated, empty string means report on all"
)
set_property(
CACHE NANO_TIMED_LOCKS_FILTER
PROPERTY STRINGS
active
block_arrival
block_processor
block_uniquer
confirmation_height_processor
dropped_elections,
election_winner_details
gap_cache
network_filter
observer_set
request_aggregator
state_block_signature_verification
telemetry
vote_generator
vote_processor
vote_uniquer
votes_cache
work_pool)
set(NANO_FUZZER_TEST
OFF
CACHE BOOL "")
Expand All @@ -103,6 +130,7 @@ endif()

if(${NANO_TIMED_LOCKS} GREATER 0)
add_definitions(-DNANO_TIMED_LOCKS=${NANO_TIMED_LOCKS})
add_definitions(-DNANO_TIMED_LOCKS_FILTER=${NANO_TIMED_LOCKS_FILTER})
if(NANO_TIMED_LOCKS_IGNORE_BLOCKED)
add_definitions(-DNANO_TIMED_LOCKS_IGNORE_BLOCKED)
endif()
Expand Down
6 changes: 3 additions & 3 deletions ci/build-travis.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ if [[ $(grep -rl --exclude="*asio.hpp" "asio::async_write" ./nano) ]]; then
exit 1
fi

# prevent unsolicited use of std::lock_guard, std::unique_lock & std::condition_variable outside of allowed areas
if [[ $(grep -rl --exclude={"*random_pool.cpp","*random_pool.hpp","*random_pool_shuffle.hpp","*locks.hpp","*locks.cpp"} "std::unique_lock\|std::lock_guard\|std::condition_variable" ./nano) ]]; then
echo "Using std::unique_lock, std::lock_guard or std::condition_variable is not permitted (except in nano/lib/locks.hpp and non-nano dependent libraries). Use the nano::* versions instead"
# prevent unsolicited use of std::lock_guard, std::unique_lock, std::condition_variable & std::mutex outside of allowed areas
if [[ $(grep -rl --exclude={"*random_pool.cpp","*random_pool.hpp","*random_pool_shuffle.hpp","*locks.hpp","*locks.cpp"} "std::unique_lock\|std::lock_guard\|std::condition_variable\|std::mutex" ./nano) ]]; then
echo "Using std::unique_lock, std::lock_guard, std::condition_variable or std::mutex is not permitted (except in nano/lib/locks.hpp and non-nano dependent libraries). Use the nano::* versions instead"
exit 1
fi

Expand Down
22 changes: 11 additions & 11 deletions nano/core_test/active_transactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ TEST (active_transactions, confirm_active)
auto peers (node2.network.random_set (1));
ASSERT_FALSE (peers.empty ());
{
nano::lock_guard<std::mutex> guard (node2.rep_crawler.probable_reps_mutex);
nano::lock_guard<nano::mutex> guard (node2.rep_crawler.probable_reps_mutex);
node2.rep_crawler.probable_reps.emplace (nano::dev_genesis_key.pub, nano::genesis_amount, *peers.begin ());
}
ASSERT_TIMELY (10s, node2.ledger.cache.cemented_count == 2 && node2.active.empty ());
Expand Down Expand Up @@ -91,7 +91,7 @@ TEST (active_transactions, confirm_frontier)
auto peers (node2.network.random_set (1));
ASSERT_FALSE (peers.empty ());
{
nano::lock_guard<std::mutex> guard (node2.rep_crawler.probable_reps_mutex);
nano::lock_guard<nano::mutex> guard (node2.rep_crawler.probable_reps_mutex);
node2.rep_crawler.probable_reps.emplace (nano::dev_genesis_key.pub, nano::genesis_amount, *peers.begin ());
}
ASSERT_TIMELY (5s, node2.ledger.cache.cemented_count == 2 && node2.active.empty ());
Expand Down Expand Up @@ -271,7 +271,7 @@ TEST (active_transactions, inactive_votes_cache_existing_vote)
ASSERT_EQ (send->hash (), last_vote1.hash);
ASSERT_EQ (1, last_vote1.timestamp);
// Attempt to change vote with inactive_votes_cache
nano::unique_lock<std::mutex> active_lock (node.active.mutex);
nano::unique_lock<nano::mutex> active_lock (node.active.mutex);
node.active.add_inactive_votes_cache (active_lock, send->hash (), key.pub);
active_lock.unlock ();
auto cache (node.active.find_inactive_votes_cache (send->hash ()));
Expand Down Expand Up @@ -554,13 +554,13 @@ TEST (active_transactions, update_difficulty)
{
{
// node1
nano::lock_guard<std::mutex> guard1 (node1.active.mutex);
nano::lock_guard<nano::mutex> guard1 (node1.active.mutex);
auto const existing1 (node1.active.roots.find (send1->qualified_root ()));
ASSERT_NE (existing1, node1.active.roots.end ());
auto const existing2 (node1.active.roots.find (send2->qualified_root ()));
ASSERT_NE (existing2, node1.active.roots.end ());
// node2
nano::lock_guard<std::mutex> guard2 (node2.active.mutex);
nano::lock_guard<nano::mutex> guard2 (node2.active.mutex);
auto const existing3 (node2.active.roots.find (send1->qualified_root ()));
ASSERT_NE (existing3, node2.active.roots.end ());
auto const existing4 (node2.active.roots.find (send2->qualified_root ()));
Expand Down Expand Up @@ -657,7 +657,7 @@ TEST (active_transactions, vote_replays)

// Removing blocks as recently confirmed makes every vote indeterminate
{
nano::lock_guard<std::mutex> guard (node.active.mutex);
nano::lock_guard<nano::mutex> guard (node.active.mutex);
node.active.recently_confirmed.clear ();
}
ASSERT_EQ (nano::vote_code::indeterminate, node.active.vote (vote_send1));
Expand Down Expand Up @@ -1015,7 +1015,7 @@ TEST (active_transactions, confirmation_consistency)
ASSERT_NO_ERROR (system.poll (5ms));
}
ASSERT_NO_ERROR (system.poll_until_true (1s, [&node, &block, i] {
nano::lock_guard<std::mutex> guard (node.active.mutex);
nano::lock_guard<nano::mutex> guard (node.active.mutex);
EXPECT_EQ (i + 1, node.active.recently_confirmed.size ());
EXPECT_EQ (block->qualified_root (), node.active.recently_confirmed.back ().first);
return i + 1 == node.active.recently_cemented.size (); // done after a callback
Expand Down Expand Up @@ -1106,7 +1106,7 @@ TEST (active_transactions, insertion_prioritization)
std::sort (blocks.begin (), blocks.end (), [](auto const & blockl, auto const & blockr) { return blockl->difficulty () > blockr->difficulty (); });

auto update_active_multiplier = [&node] {
nano::unique_lock<std::mutex> lock (node.active.mutex);
nano::unique_lock<nano::mutex> lock (node.active.mutex);
node.active.update_active_multiplier (lock);
};

Expand All @@ -1132,7 +1132,7 @@ TEST (active_multiplier, less_than_one)
{
nano::system system (1);
auto & node (*system.nodes[0]);
nano::unique_lock<std::mutex> lock (node.active.mutex);
nano::unique_lock<nano::mutex> lock (node.active.mutex);
auto base_active_difficulty = node.network_params.network.publish_thresholds.epoch_1;
auto base_active_multiplier = 1.0;
auto min_active_difficulty = node.network_params.network.publish_thresholds.entry;
Expand Down Expand Up @@ -1241,7 +1241,7 @@ TEST (active_transactions, election_difficulty_update_old)
ASSERT_EQ (1, node.active.size ());
auto multiplier = node.active.roots.begin ()->multiplier;
{
nano::lock_guard<std::mutex> guard (node.active.mutex);
nano::lock_guard<nano::mutex> guard (node.active.mutex);
ASSERT_EQ (node.active.normalized_multiplier (*send1), multiplier);
}
// Should not update with a lower difficulty
Expand Down Expand Up @@ -1675,7 +1675,7 @@ TEST (active_transactions, difficulty_update_observer)
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);
nano::unique_lock<nano::mutex> lock (mutex, std::defer_lock);
EXPECT_TRUE (lock.try_lock ());
update_received = true;
});
Expand Down
2 changes: 1 addition & 1 deletion nano/core_test/bootstrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ TEST (bootstrap_processor, DISABLED_pull_requeue_network_error)
ASSERT_TIMELY (2s, attempt->frontiers_received);
// Add non-existing pull & stop remote peer
{
nano::unique_lock<std::mutex> lock (node1->bootstrap_initiator.connections->mutex);
nano::unique_lock<nano::mutex> lock (node1->bootstrap_initiator.connections->mutex);
ASSERT_FALSE (attempt->stopped);
++attempt->pulling;
node1->bootstrap_initiator.connections->pulls.push_back (nano::pull_info (nano::dev_genesis_key.pub, send1->hash (), genesis.hash (), attempt->incremental_id));
Expand Down
10 changes: 5 additions & 5 deletions nano/core_test/confirmation_height.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ using namespace std::chrono_literals;

namespace
{
void add_callback_stats (nano::node & node, std::vector<nano::block_hash> * observer_order = nullptr, std::mutex * mutex = nullptr)
void add_callback_stats (nano::node & node, std::vector<nano::block_hash> * observer_order = nullptr, nano::mutex * mutex = nullptr)
{
node.observers.blocks.add ([& stats = node.stats, observer_order, mutex](nano::election_status const & status_a, nano::account const &, nano::amount const &, bool) {
stats.inc (nano::stat::type::http_callback, nano::stat::detail::http_callback, nano::stat::dir::out);
if (mutex)
{
nano::lock_guard<std::mutex> guard (*mutex);
nano::lock_guard<nano::mutex> guard (*mutex);
debug_assert (observer_order);
observer_order->push_back (status_a.winner->hash ());
}
Expand Down Expand Up @@ -1006,7 +1006,7 @@ TEST (confirmation_height, callback_confirmed_history)
ASSERT_TIMELY (10s, node->active.size () == 0);
ASSERT_EQ (0, node->active.list_recently_cemented ().size ());
{
nano::lock_guard<std::mutex> guard (node->active.mutex);
nano::lock_guard<nano::mutex> guard (node->active.mutex);
ASSERT_EQ (0, node->active.blocks.size ());
}

Expand Down Expand Up @@ -1151,7 +1151,7 @@ TEST (confirmation_height, cemented_gap_below_receive)
}

std::vector<nano::block_hash> observer_order;
std::mutex mutex;
nano::mutex mutex;
add_callback_stats (*node, &observer_order, &mutex);

node->block_confirm (open1);
Expand All @@ -1172,7 +1172,7 @@ TEST (confirmation_height, cemented_gap_below_receive)

// Check that the order of callbacks is correct
std::vector<nano::block_hash> expected_order = { send.hash (), open.hash (), send1.hash (), receive1.hash (), send2.hash (), dummy_send.hash (), receive2.hash (), dummy_send1.hash (), send3.hash (), open1->hash () };
nano::lock_guard<std::mutex> guard (mutex);
nano::lock_guard<nano::mutex> guard (mutex);
ASSERT_EQ (observer_order, expected_order);
};

Expand Down
4 changes: 2 additions & 2 deletions nano/core_test/confirmation_solicitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ TEST (confirmation_solicitor, batches)
auto send (std::make_shared<nano::send_block> (nano::genesis_hash, nano::keypair ().pub, nano::genesis_amount - 100, nano::dev_genesis_key.prv, nano::dev_genesis_key.pub, *system.work.generate (nano::genesis_hash)));
send->sideband_set ({});
{
nano::lock_guard<std::mutex> guard (node2.active.mutex);
nano::lock_guard<nano::mutex> guard (node2.active.mutex);
for (size_t i (0); i < nano::network::confirm_req_hashes_max; ++i)
{
auto election (std::make_shared<nano::election> (node2, send, nullptr, nullptr, false, nano::election_behavior::normal));
Expand Down Expand Up @@ -115,7 +115,7 @@ TEST (confirmation_solicitor, bypass_max_requests_cap)
// Add a vote for something else, not the winner
for (auto const & rep : representatives)
{
nano::lock_guard<std::mutex> guard (election->mutex);
nano::lock_guard<nano::mutex> guard (election->mutex);
election->last_votes[rep.account] = { std::chrono::steady_clock::now (), 1, 1 };
}
ASSERT_FALSE (solicitor.add (*election));
Expand Down
4 changes: 2 additions & 2 deletions nano/core_test/conflicts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ TEST (conflicts, reprioritize)
node1.process_active (send1);
node1.block_processor.flush ();
{
nano::lock_guard<std::mutex> guard (node1.active.mutex);
nano::lock_guard<nano::mutex> guard (node1.active.mutex);
auto existing1 (node1.active.roots.find (send1->qualified_root ()));
ASSERT_NE (node1.active.roots.end (), existing1);
ASSERT_EQ (multiplier1, existing1->multiplier);
Expand All @@ -177,7 +177,7 @@ TEST (conflicts, reprioritize)
node1.process_active (std::make_shared<nano::send_block> (send1_copy));
node1.block_processor.flush ();
{
nano::lock_guard<std::mutex> guard (node1.active.mutex);
nano::lock_guard<nano::mutex> guard (node1.active.mutex);
auto existing2 (node1.active.roots.find (send1->qualified_root ()));
ASSERT_NE (node1.active.roots.end (), existing2);
ASSERT_EQ (multiplier2, existing2->multiplier);
Expand Down
2 changes: 1 addition & 1 deletion nano/core_test/election.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ TEST (election, quorum_minimum_update_weight_before_quorum_checks)
ASSERT_TIMELY (10s, !node1.rep_crawler.response (channel, vote2));
ASSERT_FALSE (election.election->confirmed ());
{
nano::lock_guard<std::mutex> guard (node1.online_reps.mutex);
nano::lock_guard<nano::mutex> guard (node1.online_reps.mutex);
// Modify online_m for online_reps to more than is available, this checks that voting below updates it to current online reps.
node1.online_reps.online_m = node_config.online_weight_minimum.number () + 20;
}
Expand Down
4 changes: 2 additions & 2 deletions nano/core_test/frontiers_confirmation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ TEST (frontiers_confirmation, prioritize_frontiers_max_optimistic_elections)
}

{
nano::unique_lock<std::mutex> lk (node->active.mutex);
nano::unique_lock<nano::mutex> lk (node->active.mutex);
node->active.frontiers_confirmation (lk);
}

Expand All @@ -179,7 +179,7 @@ TEST (frontiers_confirmation, prioritize_frontiers_max_optimistic_elections)

// Call frontiers confirmation again and confirm that next_frontier_account hasn't changed
{
nano::unique_lock<std::mutex> lk (node->active.mutex);
nano::unique_lock<nano::mutex> lk (node->active.mutex);
node->active.frontiers_confirmation (lk);
}

Expand Down
4 changes: 2 additions & 2 deletions nano/core_test/gap_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ TEST (gap_cache, add_existing)
nano::gap_cache cache (*system.nodes[0]);
auto block1 (std::make_shared<nano::send_block> (0, 1, 2, nano::keypair ().prv, 4, 5));
cache.add (block1->hash ());
nano::unique_lock<std::mutex> lock (cache.mutex);
nano::unique_lock<nano::mutex> lock (cache.mutex);
auto existing1 (cache.blocks.get<1> ().find (block1->hash ()));
ASSERT_NE (cache.blocks.get<1> ().end (), existing1);
auto arrival (existing1->arrival);
Expand All @@ -39,7 +39,7 @@ TEST (gap_cache, comparison)
nano::gap_cache cache (*system.nodes[0]);
auto block1 (std::make_shared<nano::send_block> (1, 0, 2, nano::keypair ().prv, 4, 5));
cache.add (block1->hash ());
nano::unique_lock<std::mutex> lock (cache.mutex);
nano::unique_lock<nano::mutex> lock (cache.mutex);
auto existing1 (cache.blocks.get<1> ().find (block1->hash ()));
ASSERT_NE (cache.blocks.get<1> ().end (), existing1);
auto arrival (existing1->arrival);
Expand Down
6 changes: 3 additions & 3 deletions nano/core_test/ledger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,7 @@ TEST (votes, add_one)
auto existing1 (votes1.find (nano::dev_genesis_key.pub));
ASSERT_NE (votes1.end (), existing1);
ASSERT_EQ (send1->hash (), existing1->second.hash);
nano::lock_guard<std::mutex> guard (node1.active.mutex);
nano::lock_guard<nano::mutex> guard (node1.active.mutex);
auto winner (*election1.election->tally ().begin ());
ASSERT_EQ (*send1, *winner.second);
ASSERT_EQ (nano::genesis_amount - 100, winner.first);
Expand Down Expand Up @@ -872,7 +872,7 @@ TEST (votes, add_existing)
node1.work_generate_blocking (*send2);
auto vote2 (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 2, send2));
// Pretend we've waited the timeout
nano::unique_lock<std::mutex> lock (election1.election->mutex);
nano::unique_lock<nano::mutex> lock (election1.election->mutex);
election1.election->last_votes[nano::dev_genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20);
lock.unlock ();
ASSERT_EQ (nano::vote_code::vote, node1.active.vote (vote2));
Expand Down Expand Up @@ -911,7 +911,7 @@ TEST (votes, add_old)
node1.work_generate_blocking (*send2);
auto vote2 (std::make_shared<nano::vote> (nano::dev_genesis_key.pub, nano::dev_genesis_key.prv, 1, send2));
{
nano::lock_guard<std::mutex> lock (election1.election->mutex);
nano::lock_guard<nano::mutex> lock (election1.election->mutex);
election1.election->last_votes[nano::dev_genesis_key.pub].time = std::chrono::steady_clock::now () - std::chrono::seconds (20);
}
node1.vote_processor.vote_blocking (vote2, channel);
Expand Down
Loading