diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e80cc01..8112b724 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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=$) option(NANO_ASAN_INT "Enable ASan+UBSan+Integer overflow" OFF) diff --git a/nano/lib/threading.cpp b/nano/lib/threading.cpp index 0b0319bd..9d54240c 100644 --- a/nano/lib/threading.cpp +++ b/nano/lib/threading.cpp @@ -1,6 +1,9 @@ #include +#include + #include +#include 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::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) { diff --git a/nano/node/testing.cpp b/nano/node/testing.cpp index d185779f..5aa08e47 100644 --- a/nano/node/testing.cpp +++ b/nano/node/testing.cpp @@ -226,9 +226,24 @@ void nano::system::deadline_set (std::chrono::duration 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::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;