diff --git a/CMakeLists.txt b/CMakeLists.txt index f3e9c3c316..645c59b456 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.4) +cmake_minimum_required(VERSION 3.14) if(CMAKE_VERSION VERSION_GREATER 3.12 OR CMAKE_VERSION VERSION_EQUAL 3.12) # find_package uses _ROOT variables @@ -547,7 +547,8 @@ endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_definitions(-DCRYPTOPP_DISABLE_MIXED_ASM -DCRYPTOPP_DISABLE_ASM) message( - "CryptoPP with disabled ASM for ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}" + STATUS + "CryptoPP with disabled ASM for ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}" ) endif() add_definitions(-DCRYPTOPP_DISABLE_SHANI) @@ -774,7 +775,7 @@ if(NANO_GUI OR RAIBLOCKS_GUI) nano_wallet ${PLATFORM_GUI_TARGET_PROPERTIES} ${PLATFORM_WALLET_SOURCE} nano/nano_wallet/entry.cpp nano/nano_wallet/icon.hpp ${RES}) - target_link_libraries(nano_wallet rpc node qt) + target_link_libraries(nano_wallet Boost::process rpc node qt) if(WIN32) target_link_libraries(nano_wallet Qt5::WinExtras) diff --git a/nano/core_test/block_store.cpp b/nano/core_test/block_store.cpp index 370e11ed53..d322a66890 100644 --- a/nano/core_test/block_store.cpp +++ b/nano/core_test/block_store.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/nano/core_test/bootstrap_ascending.cpp b/nano/core_test/bootstrap_ascending.cpp index cdc2e5c38e..fd3850ccee 100644 --- a/nano/core_test/bootstrap_ascending.cpp +++ b/nano/core_test/bootstrap_ascending.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include diff --git a/nano/core_test/confirmation_height.cpp b/nano/core_test/confirmation_height.cpp index 508697f4ee..c78a579fc8 100644 --- a/nano/core_test/confirmation_height.cpp +++ b/nano/core_test/confirmation_height.cpp @@ -1,4 +1,5 @@ #include +#include #include #include diff --git a/nano/core_test/ledger.cpp b/nano/core_test/ledger.cpp index 8339eda186..fb995e52c6 100644 --- a/nano/core_test/ledger.cpp +++ b/nano/core_test/ledger.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include diff --git a/nano/core_test/logger.cpp b/nano/core_test/logger.cpp index d60cf397df..88bccc5a4d 100644 --- a/nano/core_test/logger.cpp +++ b/nano/core_test/logger.cpp @@ -5,6 +5,8 @@ #include +#include + #include #include #include diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index ab4408a53d..c445d0a280 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/nano/core_test/processor_service.cpp b/nano/core_test/processor_service.cpp index c873a80dc7..ddb59b6578 100644 --- a/nano/core_test/processor_service.cpp +++ b/nano/core_test/processor_service.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/nano/core_test/socket.cpp b/nano/core_test/socket.cpp index d0b126dafe..ea716bb3e1 100644 --- a/nano/core_test/socket.cpp +++ b/nano/core_test/socket.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/nano/core_test/system.cpp b/nano/core_test/system.cpp index 2673d4de1d..41e7f9c841 100644 --- a/nano/core_test/system.cpp +++ b/nano/core_test/system.cpp @@ -1,3 +1,4 @@ +#include #include #include #include diff --git a/nano/core_test/toml.cpp b/nano/core_test/toml.cpp index eb3f60b46d..b8098dd6ea 100644 --- a/nano/core_test/toml.cpp +++ b/nano/core_test/toml.cpp @@ -8,6 +8,8 @@ #include +#include + #include #include #include diff --git a/nano/core_test/utility.cpp b/nano/core_test/utility.cpp index 3d418e91a7..652ea8e486 100644 --- a/nano/core_test/utility.cpp +++ b/nano/core_test/utility.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include diff --git a/nano/core_test/wallet.cpp b/nano/core_test/wallet.cpp index e3d82d68d2..1e0363fcdd 100644 --- a/nano/core_test/wallet.cpp +++ b/nano/core_test/wallet.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include diff --git a/nano/ipc_flatbuffers_lib/CMakeLists.txt b/nano/ipc_flatbuffers_lib/CMakeLists.txt index 9b0d2e5685..f5323c47e5 100644 --- a/nano/ipc_flatbuffers_lib/CMakeLists.txt +++ b/nano/ipc_flatbuffers_lib/CMakeLists.txt @@ -46,7 +46,8 @@ file(GLOB files foreach(file ${files}) get_filename_component(flatbuffers_filename ${file} NAME_WE) message( - "Generating flatbuffers code for: ${flatbuffers_filename} into ${CMAKE_CURRENT_SOURCE_DIR}/generated/flatbuffers" + STATUS + "Generating flatbuffers code for: ${flatbuffers_filename} into ${CMAKE_CURRENT_SOURCE_DIR}/generated/flatbuffers" ) configure_file( diff --git a/nano/lib/CMakeLists.txt b/nano/lib/CMakeLists.txt index 2002406120..d0207325cb 100644 --- a/nano/lib/CMakeLists.txt +++ b/nano/lib/CMakeLists.txt @@ -74,8 +74,12 @@ add_library( stats_enums.hpp stats_enums.cpp stream.hpp + thread_pool.hpp + thread_pool.cpp thread_roles.hpp thread_roles.cpp + thread_runner.hpp + thread_runner.cpp threading.hpp threading.cpp timer.hpp diff --git a/nano/lib/errors.cpp b/nano/lib/errors.cpp index f4eabbd6ac..822722be62 100644 --- a/nano/lib/errors.cpp +++ b/nano/lib/errors.cpp @@ -282,48 +282,11 @@ std::string nano::error_config_messages::message (int ev) const return "Invalid error code"; } -#if defined(NANO_USE_BOOST_TO_STD_ERROR_BRIDGE) -char const * nano::error_conversion::detail::generic_category::name () const noexcept -{ - return boost::system::generic_category ().name (); -} - -std::string nano::error_conversion::detail::generic_category::message (int value) const -{ - return boost::system::generic_category ().message (value); -} - -std::error_category const & nano::error_conversion::generic_category () -{ - static detail::generic_category instance; - return instance; -} - -std::error_code nano::error_conversion::convert (boost::system::error_code const & error) -{ - if (error.category () == boost::system::generic_category ()) - { - return std::error_code (error.value (), - nano::error_conversion::generic_category ()); - } - - debug_assert (false); - return nano::error_common::invalid_type_conversion; -} -#endif - nano::error::error (std::error_code code_a) { code = code_a; } -#if defined(NANO_USE_BOOST_TO_STD_ERROR_BRIDGE) -nano::error::error (boost::system::error_code const & code_a) -{ - code = std::make_error_code (static_cast (code_a.value ())); -} -#endif - nano::error::error (std::string message_a) { code = nano::error_common::generic; @@ -358,24 +321,6 @@ nano::error & nano::error::operator= (std::error_code const code_a) return *this; } -#if defined(NANO_USE_BOOST_TO_STD_ERROR_BRIDGE) -/** Assign boost error code (as converted to std::error_code) */ -nano::error & nano::error::operator= (boost::system::error_code const & code_a) -{ - code = nano::error_conversion::convert (code_a); - message.clear (); - return *this; -} - -/** Assign boost error code (as converted to std::error_code) */ -nano::error & nano::error::operator= (boost::system::errc::errc_t const & code_a) -{ - code = nano::error_conversion::convert (boost::system::errc::make_error_code (code_a)); - message.clear (); - return *this; -} -#endif - /** Set the error to nano::error_common::generic and the error message to \p message_a */ nano::error & nano::error::operator= (std::string message_a) { @@ -398,14 +343,6 @@ bool nano::error::operator== (std::error_code const code_a) const return code == code_a; } -#if defined(NANO_USE_BOOST_TO_STD_ERROR_BRIDGE) -/** Return true if this#error_code equals the parameter */ -bool nano::error::operator== (boost::system::error_code const code_a) const -{ - return code.value () == code_a.value (); -} -#endif - /** Call the function iff the current error is zero */ nano::error & nano::error::then (std::function next) { @@ -495,14 +432,3 @@ nano::error & nano::error::clear () message.clear (); return *this; } - -#if defined(NANO_USE_BOOST_TO_STD_ERROR_BRIDGE) -// TODO: theoretically, nothing besides template (partial) specializations should ever be added inside std... -namespace std -{ -std::error_code make_error_code (boost::system::errc::errc_t const & e) -{ - return std::error_code (static_cast (e), ::nano::error_conversion::generic_category ()); -} -} -#endif diff --git a/nano/lib/errors.hpp b/nano/lib/errors.hpp index 27e8c6c5f5..d06b5d02b9 100644 --- a/nano/lib/errors.hpp +++ b/nano/lib/errors.hpp @@ -1,8 +1,5 @@ #pragma once -#include -#include - #include #include #include @@ -197,51 +194,6 @@ REGISTER_ERROR_CODES (nano, error_rpc); REGISTER_ERROR_CODES (nano, error_process); REGISTER_ERROR_CODES (nano, error_config); -#if BOOST_VERSION >= 107800 -/* no need for error_code bridge */ -#else -#define NANO_USE_BOOST_TO_STD_ERROR_BRIDGE -#endif - -#if defined(NANO_USE_BOOST_TO_STD_ERROR_BRIDGE) -/* boost->std error_code bridge */ -namespace nano -{ -namespace error_conversion -{ - std::error_category const & generic_category (); -} -} - -namespace std -{ -template <> -struct is_error_code_enum - : public std::true_type -{ -}; - -std::error_code make_error_code (boost::system::errc::errc_t const & e); -} -namespace nano -{ -namespace error_conversion -{ - namespace detail - { - class generic_category : public std::error_category - { - public: - char const * name () const noexcept override; - std::string message (int value) const override; - }; - } - std::error_category const & generic_category (); - std::error_code convert (boost::system::error_code const & error); -} -} -#endif - namespace nano { /** Adapter for std/boost::error_code, std::exception and bool flags to facilitate unified error handling */ @@ -253,24 +205,14 @@ class error error (nano::error && error_a) = default; error (std::error_code code_a); -#if defined(NANO_USE_BOOST_TO_STD_ERROR_BRIDGE) - error (boost::system::error_code const & code_a); -#endif error (std::string message_a); error (std::exception const & exception_a); error & operator= (nano::error const & err_a); error & operator= (nano::error && err_a); error & operator= (std::error_code code_a); -#if defined(NANO_USE_BOOST_TO_STD_ERROR_BRIDGE) - error & operator= (boost::system::error_code const & code_a); - error & operator= (boost::system::errc::errc_t const & code_a); -#endif error & operator= (std::string message_a); error & operator= (std::exception const & exception_a); bool operator== (std::error_code code_a) const; -#if defined(NANO_USE_BOOST_TO_STD_ERROR_BRIDGE) - bool operator== (boost::system::error_code code_a) const; -#endif error & then (std::function next); template error & accept (ErrorCode... err) diff --git a/nano/lib/plat/darwin/thread_role.cpp b/nano/lib/plat/darwin/thread_role.cpp index dd9bdc6199..4726e8f51d 100644 --- a/nano/lib/plat/darwin/thread_role.cpp +++ b/nano/lib/plat/darwin/thread_role.cpp @@ -1,4 +1,4 @@ -#include +#include #include diff --git a/nano/lib/plat/linux/thread_role.cpp b/nano/lib/plat/linux/thread_role.cpp index 46d2952250..d95a158d78 100644 --- a/nano/lib/plat/linux/thread_role.cpp +++ b/nano/lib/plat/linux/thread_role.cpp @@ -1,4 +1,4 @@ -#include +#include #include diff --git a/nano/lib/plat/windows/thread_role.cpp b/nano/lib/plat/windows/thread_role.cpp index a604e67baa..5b0e33442e 100644 --- a/nano/lib/plat/windows/thread_role.cpp +++ b/nano/lib/plat/windows/thread_role.cpp @@ -1,4 +1,4 @@ -#include +#include #include diff --git a/nano/lib/processing_queue.hpp b/nano/lib/processing_queue.hpp index 4fa89584e3..e9f317373e 100644 --- a/nano/lib/processing_queue.hpp +++ b/nano/lib/processing_queue.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -189,4 +190,4 @@ class processing_queue final nano::condition_variable condition; std::vector threads; }; -} \ No newline at end of file +} diff --git a/nano/lib/thread_pool.cpp b/nano/lib/thread_pool.cpp new file mode 100644 index 0000000000..571a840718 --- /dev/null +++ b/nano/lib/thread_pool.cpp @@ -0,0 +1,97 @@ +#include + +#include +#include +#include + +/* + * thread_pool + */ + +nano::thread_pool::thread_pool (unsigned num_threads, nano::thread_role::name thread_name) : + num_threads (num_threads), + thread_pool_m (std::make_unique (num_threads)), + thread_names_latch{ num_threads } +{ + set_thread_names (thread_name); +} + +nano::thread_pool::~thread_pool () +{ + stop (); +} + +void nano::thread_pool::stop () +{ + nano::unique_lock lk (mutex); + if (!stopped) + { + stopped = true; +#if defined(BOOST_ASIO_HAS_IOCP) + // A hack needed for Windows to prevent deadlock during destruction, described here: https://github.com/chriskohlhoff/asio/issues/431 + boost::asio::use_service (*thread_pool_m).stop (); +#endif + lk.unlock (); + thread_pool_m->stop (); + thread_pool_m->join (); + lk.lock (); + thread_pool_m = nullptr; + } +} + +void nano::thread_pool::push_task (std::function task) +{ + ++num_tasks; + nano::lock_guard guard (mutex); + if (!stopped) + { + boost::asio::post (*thread_pool_m, [this, task] () { + task (); + --num_tasks; + }); + } +} + +void nano::thread_pool::add_timed_task (std::chrono::steady_clock::time_point const & expiry_time, std::function task) +{ + nano::lock_guard guard (mutex); + if (!stopped && thread_pool_m) + { + auto timer = std::make_shared (thread_pool_m->get_executor (), expiry_time); + timer->async_wait ([this, task, timer] (boost::system::error_code const & ec) { + if (!ec) + { + push_task (task); + } + }); + } +} + +unsigned nano::thread_pool::get_num_threads () const +{ + return num_threads; +} + +uint64_t nano::thread_pool::num_queued_tasks () const +{ + return num_tasks; +} + +void nano::thread_pool::set_thread_names (nano::thread_role::name thread_name) +{ + for (auto i = 0u; i < num_threads; ++i) + { + boost::asio::post (*thread_pool_m, [this, thread_name] () { + nano::thread_role::set (thread_name); + thread_names_latch.arrive_and_wait (); + }); + } + thread_names_latch.wait (); +} + +std::unique_ptr nano::collect_container_info (thread_pool & thread_pool, std::string const & name) +{ + auto composite = std::make_unique (name); + composite->add_component (std::make_unique (container_info{ "count", thread_pool.num_queued_tasks (), sizeof (std::function) })); + return composite; +} diff --git a/nano/lib/thread_pool.hpp b/nano/lib/thread_pool.hpp new file mode 100644 index 0000000000..f56a6271e0 --- /dev/null +++ b/nano/lib/thread_pool.hpp @@ -0,0 +1,53 @@ +#pragma once + +#include +#include +#include + +#include +#include +#include +#include + +namespace boost::asio +{ +class thread_pool; +} + +namespace nano +{ +class thread_pool final +{ +public: + explicit thread_pool (unsigned, nano::thread_role::name); + ~thread_pool (); + + /** This will run when there is an available thread for execution */ + void push_task (std::function); + + /** Run a task at a certain point in time */ + void add_timed_task (std::chrono::steady_clock::time_point const & expiry_time, std::function task); + + /** Stops any further pushed tasks from executing */ + void stop (); + + /** Number of threads in the thread pool */ + unsigned get_num_threads () const; + + /** Returns the number of tasks which are awaiting execution by the thread pool **/ + uint64_t num_queued_tasks () const; + +private: + nano::mutex mutex; + std::atomic stopped{ false }; + unsigned num_threads; + std::unique_ptr thread_pool_m; + nano::relaxed_atomic_integral num_tasks{ 0 }; + + /** Set the names of all the threads in the thread pool for easier identification */ + std::latch thread_names_latch; + void set_thread_names (nano::thread_role::name thread_name); +}; + +std::unique_ptr collect_container_info (thread_pool & thread_pool, std::string const & name); +} // namespace nano diff --git a/nano/lib/thread_runner.cpp b/nano/lib/thread_runner.cpp new file mode 100644 index 0000000000..8e2c308718 --- /dev/null +++ b/nano/lib/thread_runner.cpp @@ -0,0 +1,82 @@ +#include + +#include + +/* + * thread_runner + */ + +nano::thread_runner::thread_runner (boost::asio::io_context & io_ctx_a, unsigned num_threads, const nano::thread_role::name thread_role_a) : + io_guard{ boost::asio::make_work_guard (io_ctx_a) }, + role{ thread_role_a } +{ + for (auto i (0u); i < num_threads; ++i) + { + threads.emplace_back (nano::thread_attributes::get_default (), [this, &io_ctx_a] () { + nano::thread_role::set (role); + try + { + run (io_ctx_a); + } + catch (std::exception const & ex) + { + std::cerr << ex.what () << std::endl; +#ifndef NDEBUG + throw; // Re-throw to debugger in debug mode +#endif + } + catch (...) + { +#ifndef NDEBUG + throw; // Re-throw to debugger in debug mode +#endif + } + }); + } +} + +nano::thread_runner::~thread_runner () +{ + join (); +} + +void nano::thread_runner::run (boost::asio::io_context & io_ctx_a) +{ +#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 +} + +void nano::thread_runner::join () +{ + io_guard.reset (); + for (auto & i : threads) + { + if (i.joinable ()) + { + i.join (); + } + } +} + +void nano::thread_runner::stop_event_processing () +{ + io_guard.get_executor ().context ().stop (); +} diff --git a/nano/lib/thread_runner.hpp b/nano/lib/thread_runner.hpp new file mode 100644 index 0000000000..7fbba2e082 --- /dev/null +++ b/nano/lib/thread_runner.hpp @@ -0,0 +1,31 @@ +#pragma once +#include +#include +#include +#include +#include + +#include + +namespace nano +{ +class thread_runner final +{ +public: + thread_runner (boost::asio::io_context &, unsigned num_threads, nano::thread_role::name thread_role = nano::thread_role::name::io); + ~thread_runner (); + + /** Tells the IO context to stop processing events.*/ + void stop_event_processing (); + /** Wait for IO threads to complete */ + void join (); + +private: + nano::thread_role::name const role; + std::vector threads; + boost::asio::executor_work_guard io_guard; + +private: + void run (boost::asio::io_context &); +}; +} // namespace nano diff --git a/nano/lib/threading.cpp b/nano/lib/threading.cpp index d6ef17e71d..6da0e000af 100644 --- a/nano/lib/threading.cpp +++ b/nano/lib/threading.cpp @@ -1,11 +1,7 @@ -#include #include +#include #include -#include - -#include -#include #include /* @@ -19,179 +15,6 @@ boost::thread::attributes nano::thread_attributes::get_default () return attrs; } -/* - * thread_runner - */ - -nano::thread_runner::thread_runner (boost::asio::io_context & io_ctx_a, unsigned num_threads, const nano::thread_role::name thread_role_a) : - io_guard{ boost::asio::make_work_guard (io_ctx_a) }, - role{ thread_role_a } -{ - for (auto i (0u); i < num_threads; ++i) - { - threads.emplace_back (nano::thread_attributes::get_default (), [this, &io_ctx_a] () { - nano::thread_role::set (role); - - // In a release build, catch and swallow any exceptions, - // In debug mode let if fall through - -#ifndef NDEBUG - run (io_ctx_a); -#else - try - { - run (io_ctx_a); - } - catch (std::exception const & ex) - { - std::cerr << ex.what () << std::endl; - } - catch (...) - { - } -#endif - }); - } -} - -nano::thread_runner::~thread_runner () -{ - join (); -} - -void nano::thread_runner::run (boost::asio::io_context & io_ctx_a) -{ -#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 -} - -void nano::thread_runner::join () -{ - io_guard.reset (); - for (auto & i : threads) - { - if (i.joinable ()) - { - i.join (); - } - } -} - -void nano::thread_runner::stop_event_processing () -{ - io_guard.get_executor ().context ().stop (); -} - -/* - * thread_pool - */ - -nano::thread_pool::thread_pool (unsigned num_threads, nano::thread_role::name thread_name) : - num_threads (num_threads), - thread_pool_m (std::make_unique (num_threads)), - thread_names_latch{ num_threads } -{ - set_thread_names (thread_name); -} - -nano::thread_pool::~thread_pool () -{ - stop (); -} - -void nano::thread_pool::stop () -{ - nano::unique_lock lk (mutex); - if (!stopped) - { - stopped = true; -#if defined(BOOST_ASIO_HAS_IOCP) - // A hack needed for Windows to prevent deadlock during destruction, described here: https://github.com/chriskohlhoff/asio/issues/431 - boost::asio::use_service (*thread_pool_m).stop (); -#endif - lk.unlock (); - thread_pool_m->stop (); - thread_pool_m->join (); - lk.lock (); - thread_pool_m = nullptr; - } -} - -void nano::thread_pool::push_task (std::function task) -{ - ++num_tasks; - nano::lock_guard guard (mutex); - if (!stopped) - { - boost::asio::post (*thread_pool_m, [this, task] () { - task (); - --num_tasks; - }); - } -} - -void nano::thread_pool::add_timed_task (std::chrono::steady_clock::time_point const & expiry_time, std::function task) -{ - nano::lock_guard guard (mutex); - if (!stopped && thread_pool_m) - { - auto timer = std::make_shared (thread_pool_m->get_executor (), expiry_time); - timer->async_wait ([this, task, timer] (boost::system::error_code const & ec) { - if (!ec) - { - push_task (task); - } - }); - } -} - -unsigned nano::thread_pool::get_num_threads () const -{ - return num_threads; -} - -uint64_t nano::thread_pool::num_queued_tasks () const -{ - return num_tasks; -} - -void nano::thread_pool::set_thread_names (nano::thread_role::name thread_name) -{ - for (auto i = 0u; i < num_threads; ++i) - { - boost::asio::post (*thread_pool_m, [this, thread_name] () { - nano::thread_role::set (thread_name); - thread_names_latch.arrive_and_wait (); - }); - } - thread_names_latch.wait (); -} - -std::unique_ptr nano::collect_container_info (thread_pool & thread_pool, std::string const & name) -{ - auto composite = std::make_unique (name); - composite->add_component (std::make_unique (container_info{ "count", thread_pool.num_queued_tasks (), sizeof (std::function) })); - return composite; -} - unsigned int nano::hardware_concurrency () { // Try to read overridden value from environment variable diff --git a/nano/lib/threading.hpp b/nano/lib/threading.hpp index 3b82a2f856..17b74a4cb2 100644 --- a/nano/lib/threading.hpp +++ b/nano/lib/threading.hpp @@ -1,80 +1,15 @@ #pragma once -#include -#include -#include -#include -#include -#include -#include #include #include -#include -#include - namespace nano { namespace thread_attributes { boost::thread::attributes get_default (); -} - -class thread_runner final -{ -public: - thread_runner (boost::asio::io_context &, unsigned num_threads, nano::thread_role::name thread_role = nano::thread_role::name::io); - ~thread_runner (); - - /** Tells the IO context to stop processing events.*/ - void stop_event_processing (); - /** Wait for IO threads to complete */ - void join (); - -private: - nano::thread_role::name const role; - std::vector threads; - boost::asio::executor_work_guard io_guard; - -private: - void run (boost::asio::io_context &); -}; - -class thread_pool final -{ -public: - explicit thread_pool (unsigned, nano::thread_role::name); - ~thread_pool (); - - /** This will run when there is an available thread for execution */ - void push_task (std::function); - - /** Run a task at a certain point in time */ - void add_timed_task (std::chrono::steady_clock::time_point const & expiry_time, std::function task); - - /** Stops any further pushed tasks from executing */ - void stop (); - - /** Number of threads in the thread pool */ - unsigned get_num_threads () const; - - /** Returns the number of tasks which are awaiting execution by the thread pool **/ - uint64_t num_queued_tasks () const; - -private: - nano::mutex mutex; - std::atomic stopped{ false }; - unsigned num_threads; - std::unique_ptr thread_pool_m; - nano::relaxed_atomic_integral num_tasks{ 0 }; - - /** Set the names of all the threads in the thread pool for easier identification */ - std::latch thread_names_latch; - void set_thread_names (nano::thread_role::name thread_name); -}; - -std::unique_ptr collect_container_info (thread_pool & thread_pool, std::string const & name); +} // namespace thread_attributes /** * Number of available logical processor cores. Might be overridden by setting `NANO_HARDWARE_CONCURRENCY` environment variable @@ -83,6 +18,7 @@ unsigned int hardware_concurrency (); /** * If thread is joinable joins it, otherwise does nothing + * Returns thread.joinable() */ bool join_or_pass (std::thread &); -} +} // namespace nano diff --git a/nano/lib/tlsconfig.cpp b/nano/lib/tlsconfig.cpp index d16efcfa31..34aade654d 100644 --- a/nano/lib/tlsconfig.cpp +++ b/nano/lib/tlsconfig.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include diff --git a/nano/lib/work.cpp b/nano/lib/work.cpp index 7e02981af2..07b27e3979 100644 --- a/nano/lib/work.cpp +++ b/nano/lib/work.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include diff --git a/nano/load_test/entry.cpp b/nano/load_test/entry.cpp index a2a37123b6..fcd067961d 100644 --- a/nano/load_test/entry.cpp +++ b/nano/load_test/entry.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/nano/nano_node/daemon.cpp b/nano/nano_node/daemon.cpp index a8431fc68a..50b4afdafd 100644 --- a/nano/nano_node/daemon.cpp +++ b/nano/nano_node/daemon.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include diff --git a/nano/nano_node/entry.cpp b/nano/nano_node/entry.cpp index 7869843223..f16fd1c922 100644 --- a/nano/nano_node/entry.cpp +++ b/nano/nano_node/entry.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/nano/nano_rpc/entry.cpp b/nano/nano_rpc/entry.cpp index 49f5bc88a2..0dd7b79d86 100644 --- a/nano/nano_rpc/entry.cpp +++ b/nano/nano_rpc/entry.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include diff --git a/nano/nano_wallet/entry.cpp b/nano/nano_wallet/entry.cpp index 39681540c5..906841cb79 100644 --- a/nano/nano_wallet/entry.cpp +++ b/nano/nano_wallet/entry.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/nano/node/CMakeLists.txt b/nano/node/CMakeLists.txt index 4e1f29cc02..d077a74769 100644 --- a/nano/node/CMakeLists.txt +++ b/nano/node/CMakeLists.txt @@ -143,6 +143,8 @@ add_library( lmdb/wallet_value.cpp logging.hpp logging.cpp + make_store.hpp + make_store.cpp network.hpp network.cpp nodeconfig.hpp diff --git a/nano/node/cli.cpp b/nano/node/cli.cpp index 5dd2c39f85..a1dc89c541 100644 --- a/nano/node/cli.cpp +++ b/nano/node/cli.cpp @@ -6,6 +6,7 @@ #include #include +#include #include namespace diff --git a/nano/node/confirmation_height_bounded.hpp b/nano/node/confirmation_height_bounded.hpp index 338223fba3..5676e49250 100644 --- a/nano/node/confirmation_height_bounded.hpp +++ b/nano/node/confirmation_height_bounded.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include diff --git a/nano/node/confirmation_height_processor.cpp b/nano/node/confirmation_height_processor.cpp index df4be6c490..6cf9772999 100644 --- a/nano/node/confirmation_height_processor.cpp +++ b/nano/node/confirmation_height_processor.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include diff --git a/nano/node/confirmation_height_unbounded.cpp b/nano/node/confirmation_height_unbounded.cpp index 5d8690c3b5..62f1036bab 100644 --- a/nano/node/confirmation_height_unbounded.cpp +++ b/nano/node/confirmation_height_unbounded.cpp @@ -1,3 +1,4 @@ +#include #include #include #include diff --git a/nano/node/confirmation_height_unbounded.hpp b/nano/node/confirmation_height_unbounded.hpp index de8f07c088..cf7f5afaa0 100644 --- a/nano/node/confirmation_height_unbounded.hpp +++ b/nano/node/confirmation_height_unbounded.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include diff --git a/nano/node/daemonconfig.cpp b/nano/node/daemonconfig.cpp index 3e232646aa..26e2f7fe7c 100644 --- a/nano/node/daemonconfig.cpp +++ b/nano/node/daemonconfig.cpp @@ -3,6 +3,8 @@ #include #include +#include + #include #include diff --git a/nano/node/ipc/ipc_access_config.cpp b/nano/node/ipc/ipc_access_config.cpp index 404ebe8049..e7909a2b6c 100644 --- a/nano/node/ipc/ipc_access_config.cpp +++ b/nano/node/ipc/ipc_access_config.cpp @@ -2,6 +2,7 @@ #include #include +#include namespace { diff --git a/nano/node/ipc/ipc_server.cpp b/nano/node/ipc/ipc_server.cpp index 7712871db6..9eaf1e7509 100644 --- a/nano/node/ipc/ipc_server.cpp +++ b/nano/node/ipc/ipc_server.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include diff --git a/nano/node/lmdb/lmdb.cpp b/nano/node/lmdb/lmdb.cpp index 62c6e11cf3..5a4bb45722 100644 --- a/nano/node/lmdb/lmdb.cpp +++ b/nano/node/lmdb/lmdb.cpp @@ -9,6 +9,7 @@ #include #include +#include #include diff --git a/nano/node/lmdb/lmdb_txn.cpp b/nano/node/lmdb/lmdb_txn.cpp index 5d577b384a..a8ef80d4cc 100644 --- a/nano/node/lmdb/lmdb_txn.cpp +++ b/nano/node/lmdb/lmdb_txn.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include diff --git a/nano/node/logging.cpp b/nano/node/logging.cpp index 6a414f0b8b..5b3427963e 100644 --- a/nano/node/logging.cpp +++ b/nano/node/logging.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include diff --git a/nano/node/make_store.cpp b/nano/node/make_store.cpp new file mode 100644 index 0000000000..eb3667a253 --- /dev/null +++ b/nano/node/make_store.cpp @@ -0,0 +1,15 @@ +#include +#include +#include + +#include + +std::unique_ptr nano::make_store (nano::logger_mt & logger, boost::filesystem::path const & path, nano::ledger_constants & constants, bool read_only, bool add_db_postfix, nano::rocksdb_config const & rocksdb_config, nano::txn_tracking_config const & txn_tracking_config_a, std::chrono::milliseconds block_processor_batch_max_time_a, nano::lmdb_config const & lmdb_config_a, bool backup_before_upgrade) +{ + if (rocksdb_config.enable) + { + return std::make_unique (logger, add_db_postfix ? path / "rocksdb" : path, constants, rocksdb_config, read_only); + } + + return std::make_unique (logger, add_db_postfix ? path / "data.ldb" : path, constants, txn_tracking_config_a, block_processor_batch_max_time_a, lmdb_config_a, backup_before_upgrade); +} diff --git a/nano/node/make_store.hpp b/nano/node/make_store.hpp new file mode 100644 index 0000000000..91192a798b --- /dev/null +++ b/nano/node/make_store.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include +#include + +#include + +namespace boost::filesystem +{ +class path; +} + +namespace nano +{ +class ledger_constants; +class lmdb_config; +class rocksdb_config; +class store; +class txn_tracking_config; +} + +namespace nano +{ +std::unique_ptr make_store (nano::logger_mt & logger, boost::filesystem::path const & path, nano::ledger_constants & constants, bool open_read_only = false, bool add_db_postfix = true, nano::rocksdb_config const & rocksdb_config = nano::rocksdb_config{}, nano::txn_tracking_config const & txn_tracking_config_a = nano::txn_tracking_config{}, std::chrono::milliseconds block_processor_batch_max_time_a = std::chrono::milliseconds (5000), nano::lmdb_config const & lmdb_config_a = nano::lmdb_config{}, bool backup_before_upgrade = false); +} diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 47fafd1ec8..4d6a8e355e 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -1570,13 +1571,3 @@ nano::node_flags const & nano::inactive_node_flag_defaults () node_flags.disable_tcp_realtime = true; return node_flags; } - -std::unique_ptr nano::make_store (nano::logger_mt & logger, boost::filesystem::path const & path, nano::ledger_constants & constants, bool read_only, bool add_db_postfix, nano::rocksdb_config const & rocksdb_config, nano::txn_tracking_config const & txn_tracking_config_a, std::chrono::milliseconds block_processor_batch_max_time_a, nano::lmdb_config const & lmdb_config_a, bool backup_before_upgrade) -{ - if (rocksdb_config.enable) - { - return std::make_unique (logger, add_db_postfix ? path / "rocksdb" : path, constants, rocksdb_config, read_only); - } - - return std::make_unique (logger, add_db_postfix ? path / "data.ldb" : path, constants, txn_tracking_config_a, block_processor_batch_max_time_a, lmdb_config_a, backup_before_upgrade); -} diff --git a/nano/node/node.hpp b/nano/node/node.hpp index a52a04d3d4..e4753bb5f1 100644 --- a/nano/node/node.hpp +++ b/nano/node/node.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include diff --git a/nano/node/rocksdb/rocksdb.cpp b/nano/node/rocksdb/rocksdb.cpp index 7beac09aa4..3d2fdb4dfc 100644 --- a/nano/node/rocksdb/rocksdb.cpp +++ b/nano/node/rocksdb/rocksdb.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include diff --git a/nano/node/rocksdb/rocksdb.hpp b/nano/node/rocksdb/rocksdb.hpp index 47f3e71858..5df0d9b4df 100644 --- a/nano/node/rocksdb/rocksdb.hpp +++ b/nano/node/rocksdb/rocksdb.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include diff --git a/nano/node/signatures.hpp b/nano/node/signatures.hpp index f1aa9f90cd..601948707e 100644 --- a/nano/node/signatures.hpp +++ b/nano/node/signatures.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include diff --git a/nano/node/unchecked_map.cpp b/nano/node/unchecked_map.cpp index 64b2b9cf0c..45d3b49563 100644 --- a/nano/node/unchecked_map.cpp +++ b/nano/node/unchecked_map.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include diff --git a/nano/qt/qt.cpp b/nano/qt/qt.cpp index 457d57c781..31fcf25d6e 100644 --- a/nano/qt/qt.cpp +++ b/nano/qt/qt.cpp @@ -1,7 +1,6 @@ #include #include -#include #include #include @@ -845,7 +844,7 @@ void nano_qt::stats_viewer::refresh_stats () if (json) { // Format the stat data to make totals and values easier to read - BOOST_FOREACH (boost::property_tree::ptree::value_type const & child, json->get_child ("entries")) + for (boost::property_tree::ptree::value_type const & child : json->get_child ("entries")) { auto time = child.second.get ("time"); auto type = child.second.get ("type"); diff --git a/nano/qt_test/qt.cpp b/nano/qt_test/qt.cpp index 97e9b911a8..8e3dea40b7 100644 --- a/nano/qt_test/qt.cpp +++ b/nano/qt_test/qt.cpp @@ -1,3 +1,4 @@ +#include #include #include #include diff --git a/nano/rpc/rpc_request_processor.cpp b/nano/rpc/rpc_request_processor.cpp index 964bcd2213..d7315890c4 100644 --- a/nano/rpc/rpc_request_processor.cpp +++ b/nano/rpc/rpc_request_processor.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index a48fe5454f..59b83a9fe0 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include diff --git a/nano/secure/ledger.cpp b/nano/secure/ledger.cpp index 91116c6487..3bf4a4c461 100644 --- a/nano/secure/ledger.cpp +++ b/nano/secure/ledger.cpp @@ -2,10 +2,13 @@ #include #include #include +#include #include #include #include +#include + #include namespace @@ -676,6 +679,69 @@ ledger_processor::ledger_processor (nano::ledger & ledger_a, nano::write_transac transaction (transaction_a) { } + +/** + * Determine the representative for this block + */ +class representative_visitor final : public nano::block_visitor +{ +public: + representative_visitor (nano::transaction const & transaction_a, nano::store & store_a); + ~representative_visitor () = default; + void compute (nano::block_hash const & hash_a); + void send_block (nano::send_block const & block_a) override; + void receive_block (nano::receive_block const & block_a) override; + void open_block (nano::open_block const & block_a) override; + void change_block (nano::change_block const & block_a) override; + void state_block (nano::state_block const & block_a) override; + nano::transaction const & transaction; + nano::store & store; + nano::block_hash current; + nano::block_hash result; +}; + +representative_visitor::representative_visitor (nano::transaction const & transaction_a, nano::store & store_a) : + transaction (transaction_a), + store (store_a), + result (0) +{ +} + +void representative_visitor::compute (nano::block_hash const & hash_a) +{ + current = hash_a; + while (result.is_zero ()) + { + auto block (store.block.get (transaction, current)); + debug_assert (block != nullptr); + block->visit (*this); + } +} + +void representative_visitor::send_block (nano::send_block const & block_a) +{ + current = block_a.previous (); +} + +void representative_visitor::receive_block (nano::receive_block const & block_a) +{ + current = block_a.previous (); +} + +void representative_visitor::open_block (nano::open_block const & block_a) +{ + result = block_a.hash (); +} + +void representative_visitor::change_block (nano::change_block const & block_a) +{ + result = block_a.hash (); +} + +void representative_visitor::state_block (nano::state_block const & block_a) +{ + result = block_a.hash (); +} } // namespace nano::ledger::ledger (nano::store & store_a, nano::stats & stat_a, nano::ledger_constants & constants, nano::generate_cache const & generate_cache_a) : diff --git a/nano/secure/parallel_traversal.hpp b/nano/secure/parallel_traversal.hpp index 3bc261f8ea..cf1a51ac4a 100644 --- a/nano/secure/parallel_traversal.hpp +++ b/nano/secure/parallel_traversal.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include diff --git a/nano/secure/plat/osx/working.mm b/nano/secure/plat/osx/working.mm index 48f8c50a62..28aa1005af 100644 --- a/nano/secure/plat/osx/working.mm +++ b/nano/secure/plat/osx/working.mm @@ -1,5 +1,7 @@ #include +#include + #include namespace nano @@ -12,4 +14,4 @@ [dir_string release]; return result; } -} \ No newline at end of file +} diff --git a/nano/secure/plat/posix/working.cpp b/nano/secure/plat/posix/working.cpp index 1d36b163ba..c962bd774b 100644 --- a/nano/secure/plat/posix/working.cpp +++ b/nano/secure/plat/posix/working.cpp @@ -1,6 +1,8 @@ #include #include +#include + #include #include diff --git a/nano/secure/store.cpp b/nano/secure/store.cpp index 28d4a4dc39..64bd19a260 100644 --- a/nano/secure/store.cpp +++ b/nano/secure/store.cpp @@ -1,50 +1,7 @@ -#include +#include #include #include -nano::representative_visitor::representative_visitor (nano::transaction const & transaction_a, nano::store & store_a) : - transaction (transaction_a), - store (store_a), - result (0) -{ -} - -void nano::representative_visitor::compute (nano::block_hash const & hash_a) -{ - current = hash_a; - while (result.is_zero ()) - { - auto block (store.block.get (transaction, current)); - debug_assert (block != nullptr); - block->visit (*this); - } -} - -void nano::representative_visitor::send_block (nano::send_block const & block_a) -{ - current = block_a.previous (); -} - -void nano::representative_visitor::receive_block (nano::receive_block const & block_a) -{ - current = block_a.previous (); -} - -void nano::representative_visitor::open_block (nano::open_block const & block_a) -{ - result = block_a.hash (); -} - -void nano::representative_visitor::change_block (nano::change_block const & block_a) -{ - result = block_a.hash (); -} - -void nano::representative_visitor::state_block (nano::state_block const & block_a) -{ - result = block_a.hash (); -} - nano::read_transaction::read_transaction (std::unique_ptr read_transaction_impl) : impl (std::move (read_transaction_impl)) { diff --git a/nano/secure/store.hpp b/nano/secure/store.hpp index 6798a695f6..89c86a74a7 100644 --- a/nano/secure/store.hpp +++ b/nano/secure/store.hpp @@ -1,11 +1,7 @@ #pragma once #include -#include -#include -#include #include -#include #include #include #include @@ -401,29 +397,6 @@ class db_val return result; } }; - -class transaction; -class store; - -/** - * Determine the representative for this block - */ -class representative_visitor final : public nano::block_visitor -{ -public: - representative_visitor (nano::transaction const & transaction_a, nano::store & store_a); - ~representative_visitor () = default; - void compute (nano::block_hash const & hash_a); - void send_block (nano::send_block const & block_a) override; - void receive_block (nano::receive_block const & block_a) override; - void open_block (nano::open_block const & block_a) override; - void change_block (nano::change_block const & block_a) override; - void state_block (nano::state_block const & block_a) override; - nano::transaction const & transaction; - nano::store & store; - nano::block_hash current; - nano::block_hash result; -}; template class store_iterator_impl { @@ -824,8 +797,6 @@ class store virtual std::string vendor_get () const = 0; }; - -std::unique_ptr make_store (nano::logger_mt & logger, boost::filesystem::path const & path, nano::ledger_constants & constants, bool open_read_only = false, bool add_db_postfix = true, nano::rocksdb_config const & rocksdb_config = nano::rocksdb_config{}, nano::txn_tracking_config const & txn_tracking_config_a = nano::txn_tracking_config{}, std::chrono::milliseconds block_processor_batch_max_time_a = std::chrono::milliseconds (5000), nano::lmdb_config const & lmdb_config_a = nano::lmdb_config{}, bool backup_before_upgrade = false); } namespace std diff --git a/nano/slow_test/bootstrap.cpp b/nano/slow_test/bootstrap.cpp index 7004a74cad..b722cf73e1 100644 --- a/nano/slow_test/bootstrap.cpp +++ b/nano/slow_test/bootstrap.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include diff --git a/nano/slow_test/node.cpp b/nano/slow_test/node.cpp index d63b2ac154..7cfea256f8 100644 --- a/nano/slow_test/node.cpp +++ b/nano/slow_test/node.cpp @@ -1,6 +1,8 @@ #include +#include #include #include +#include #include #include #include diff --git a/nano/test_common/ledger.cpp b/nano/test_common/ledger.cpp index c87c0f8fe8..840a463f88 100644 --- a/nano/test_common/ledger.cpp +++ b/nano/test_common/ledger.cpp @@ -1,3 +1,4 @@ +#include #include #include