Add ASIO completion handler tracking (#2681)

* Add ASIO handler tracking

* Fix gcc build (Serg review)
This commit is contained in:
Wesley Shillingford 2020-07-16 12:49:35 +01:00 committed by GitHub
commit 1f2f61afe6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 1 deletions

View file

@ -65,6 +65,7 @@ set (NANO_WARN_TO_ERR OFF CACHE BOOL "")
set (NANO_TIMED_LOCKS 0 CACHE STRING "")
set (NANO_TIMED_LOCKS_IGNORE_BLOCKED OFF CACHE BOOL "")
set (NANO_FUZZER_TEST OFF CACHE BOOL "")
set (NANO_ASIO_HANDLER_TRACKING 0 CACHE STRING "")
option (NANO_STACKTRACE_BACKTRACE "Use BOOST_STACKTRACE_USE_BACKTRACE in stacktraces, for POSIX" OFF)
if (NANO_STACKTRACE_BACKTRACE)
@ -81,6 +82,10 @@ if (${NANO_TIMED_LOCKS} GREATER 0)
endif ()
endif ()
if (${NANO_ASIO_HANDLER_TRACKING} GREATER 0)
add_definitions (-DNANO_ASIO_HANDLER_TRACKING=${NANO_ASIO_HANDLER_TRACKING} -DBOOST_ASIO_ENABLE_HANDLER_TRACKING)
endif ()
add_definitions (-DNANO_ROCKSDB=$<STREQUAL:${NANO_ROCKSDB},ON>)
option(NANO_ASAN_INT "Enable ASan+UBSan+Integer overflow" OFF)

View file

@ -1,6 +1,9 @@
#include <nano/lib/threading.hpp>
#include <boost/format.hpp>
#include <iostream>
#include <thread>
namespace
{
@ -124,7 +127,26 @@ io_guard (boost::asio::make_work_guard (io_ctx_a))
nano::thread_role::set (nano::thread_role::name::io);
try
{
#if NANO_ASIO_HANDLER_TRACKING == 0
io_ctx_a.run ();
#else
nano::timer<> timer;
timer.start ();
while (true)
{
timer.restart ();
// Run at most 1 completion handler and record the time it took to complete (non-blocking)
auto count = io_ctx_a.poll_one ();
if (count == 1 && timer.since_start ().count () >= NANO_ASIO_HANDLER_TRACKING)
{
auto timestamp = std::chrono::duration_cast<std::chrono::microseconds> (std::chrono::system_clock::now ().time_since_epoch ()).count ();
std::cout << (boost::format ("[%1%] io_thread held for %2%ms") % timestamp % timer.since_start ().count ()).str () << std::endl;
}
// Sleep for a bit to give more time slices to other threads
std::this_thread::sleep_for (std::chrono::milliseconds (5));
std::this_thread::yield ();
}
#endif
}
catch (std::exception const & ex)
{

View file

@ -226,9 +226,24 @@ void nano::system::deadline_set (std::chrono::duration<double, std::nano> const
std::error_code nano::system::poll (std::chrono::nanoseconds const & wait_time)
{
std::error_code ec;
#if NANO_ASIO_HANDLER_TRACKING == 0
io_ctx.run_one_for (wait_time);
#else
nano::timer<> timer;
timer.start ();
auto count = io_ctx.poll_one ();
if (count == 0)
{
std::this_thread::sleep_for (wait_time);
}
else if (count == 1 && timer.since_start ().count () >= NANO_ASIO_HANDLER_TRACKING)
{
auto timestamp = std::chrono::duration_cast<std::chrono::microseconds> (std::chrono::system_clock::now ().time_since_epoch ()).count ();
std::cout << (boost::format ("[%1%] io_thread held for %2%ms") % timestamp % timer.since_start ().count ()).str () << std::endl;
}
#endif
std::error_code ec;
if (std::chrono::steady_clock::now () > deadline)
{
ec = nano::error_system::deadline_expired;