Prevent supurious wakeup in active transactions request loop (#2263)

* Preventing supurious wakeup in active transactions request loop

* Move lock creation back into worker loop, removing unecessary lock

* Capturing only what is necessary

* clang-format being clang-format

* Making some tests less time-strict to pass on travis
This commit is contained in:
Guilherme Lawless 2019-08-30 18:25:48 +01:00 committed by GitHub
commit 0b9173ce88
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 21 additions and 32 deletions

View file

@ -83,12 +83,12 @@ TEST (distributed_work, no_peers_multi)
{
node->distributed_work.make (hash, callback, nano::difficulty::from_multiplier (10, node->network_params.network.publish_threshold));
}
// 1 root, and _total_ requests for that root are expected
// 1 root, and _total_ requests for that root are expected, but some may have already finished
ASSERT_EQ (1, node->distributed_work.work.size ());
{
auto requests (node->distributed_work.work.begin ());
ASSERT_EQ (hash, requests->first);
ASSERT_EQ (total, requests->second.size ());
ASSERT_GE (requests->second.size (), total - 4);
}
system.deadline_set (5s);
while (count < total)

View file

@ -1130,11 +1130,11 @@ TEST (wallet, work_watcher_update)
//fill multipliers_cb and update active difficulty;
for (auto i (0); i < node.active.multipliers_cb.size (); i++)
{
node.active.multipliers_cb.push_back (multiplier * (2 + i / 100.));
node.active.multipliers_cb.push_back (multiplier * (1.5 + i / 100.));
}
node.active.update_active_difficulty (lock);
}
system.deadline_set (10s);
system.deadline_set (20s);
while (updated_difficulty1 == difficulty1 || updated_difficulty2 == difficulty2)
{
{

View file

@ -250,7 +250,6 @@ void nano::worker::run ()
// So that we reduce locking for anything being pushed as that will
// most likely be on an io-thread
std::this_thread::yield ();
lk.lock ();
}
else
{

View file

@ -20,10 +20,7 @@ thread ([this]() {
})
{
std::unique_lock<std::mutex> lock (mutex);
while (!started)
{
condition.wait (lock);
}
condition.wait (lock, [& started = started] { return started; });
}
nano::active_transactions::~active_transactions ()
@ -340,7 +337,8 @@ void nano::active_transactions::request_loop ()
break;
}
const auto extra_delay (std::min (roots.size (), max_broadcast_queue) * node.network.broadcast_interval_ms * 2);
condition.wait_for (lock, std::chrono::milliseconds (node.network_params.network.request_interval_ms + extra_delay));
const auto wakeup (std::chrono::steady_clock::now () + std::chrono::milliseconds (node.network_params.network.request_interval_ms + extra_delay));
condition.wait_until (lock, wakeup, [&wakeup] { return std::chrono::steady_clock::now () >= wakeup; });
}
}
@ -504,10 +502,7 @@ void nano::active_transactions::prioritize_frontiers_for_confirmation (nano::tra
void nano::active_transactions::stop ()
{
std::unique_lock<std::mutex> lock (mutex);
while (!started)
{
condition.wait (lock);
}
condition.wait (lock, [& started = started] { return started; });
stopped = true;
lock.unlock ();
condition.notify_all ();

View file

@ -982,10 +982,9 @@ void nano::bootstrap_attempt::run ()
std::shared_ptr<nano::bootstrap_client> nano::bootstrap_attempt::connection (std::unique_lock<std::mutex> & lock_a)
{
while (!stopped && idle.empty ())
{
condition.wait (lock_a);
}
// clang-format off
condition.wait (lock_a, [& stopped = stopped, &idle = idle] { return stopped || !idle.empty (); });
// clang-format on
std::shared_ptr<nano::bootstrap_client> result;
if (!idle.empty ())
{
@ -1687,10 +1686,10 @@ void nano::bootstrap_initiator::bootstrap (nano::endpoint const & endpoint_a, bo
std::unique_lock<std::mutex> lock (mutex);
if (!stopped)
{
while (attempt != nullptr)
if (attempt != nullptr)
{
attempt->stop ();
condition.wait (lock);
condition.wait (lock, [attempt = attempt] { return attempt == nullptr; });
}
node.stats.inc (nano::stat::type::bootstrap, nano::stat::detail::initiate, nano::stat::dir::out);
attempt = std::make_shared<nano::bootstrap_attempt> (node.shared ());
@ -1705,10 +1704,10 @@ void nano::bootstrap_initiator::bootstrap_lazy (nano::block_hash const & hash_a,
std::unique_lock<std::mutex> lock (mutex);
if (force)
{
while (attempt != nullptr)
if (attempt != nullptr)
{
attempt->stop ();
condition.wait (lock);
condition.wait (lock, [attempt = attempt] { return attempt == nullptr; });
}
}
node.stats.inc (nano::stat::type::bootstrap, nano::stat::detail::initiate_lazy, nano::stat::dir::out);

View file

@ -842,10 +842,12 @@ stopped (false)
nano::message_buffer * nano::message_buffer_manager::allocate ()
{
std::unique_lock<std::mutex> lock (mutex);
while (!stopped && free.empty () && full.empty ())
if (!stopped && free.empty () && full.empty ())
{
stats.inc (nano::stat::type::udp, nano::stat::detail::blocking, nano::stat::dir::in);
condition.wait (lock);
// clang-format off
condition.wait (lock, [& stopped = stopped, &free = free, &full = full] { return stopped || !free.empty () || !full.empty (); });
// clang-format on
}
nano::message_buffer * result (nullptr);
if (!free.empty ())

View file

@ -13,10 +13,7 @@ thread ([this]() {
})
{
std::unique_lock<std::mutex> lock (mutex);
while (!started)
{
condition.wait (lock);
}
condition.wait (lock, [& started = started] { return started; });
}
void nano::vote_processor::process_loop ()

View file

@ -8,10 +8,7 @@ node (node_a),
thread ([this]() { run (); })
{
std::unique_lock<std::mutex> lock (mutex);
while (!started)
{
condition.wait (lock);
}
condition.wait (lock, [& started = started] { return started; });
}
void nano::vote_generator::add (nano::block_hash const & hash_a)