Skip to content

Commit

Permalink
node: custom stack size for non-main thread running block execution (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
canepat authored Aug 4, 2023
1 parent e63046c commit 4a61f8d
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 18 deletions.
5 changes: 3 additions & 2 deletions silkworm/infra/concurrency/active_component.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#pragma once

#include <atomic>
#include <optional>

#include <silkworm/infra/concurrency/coroutine.hpp>

Expand All @@ -39,10 +40,10 @@ class ActiveComponent : public Stoppable {
public:
virtual void execution_loop() = 0;

boost::asio::awaitable<void> async_run() {
boost::asio::awaitable<void> async_run(std::optional<std::size_t> stack_size = {}) {
auto run = [this] { this->execution_loop(); };
auto stop = [this] { this->stop(); };
co_await concurrency::async_thread(std::move(run), std::move(stop));
co_await concurrency::async_thread(std::move(run), std::move(stop), stack_size);
}
};

Expand Down
33 changes: 19 additions & 14 deletions silkworm/infra/concurrency/async_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,37 @@
#include <boost/asio/this_coro.hpp>
#include <boost/system/errc.hpp>
#include <boost/system/system_error.hpp>
#include <boost/thread.hpp>

#include <silkworm/infra/common/log.hpp>

#include "event_notifier.hpp"

namespace silkworm::concurrency {

boost::asio::awaitable<void> async_thread(std::function<void()> run, std::function<void()> stop) {
boost::asio::awaitable<void> async_thread(std::function<void()> run, std::function<void()> stop, std::optional<std::size_t> stack_size) {
std::exception_ptr run_exception;

auto executor = co_await boost::asio::this_coro::executor;
EventNotifier thread_finished_notifier{executor};

std::thread thread{[run = std::move(run), &run_exception, &thread_finished_notifier] {
try {
run();
} catch (...) {
run_exception = std::current_exception();
}

try {
thread_finished_notifier.notify();
} catch (const std::exception& ex) {
log::Error() << "async_thread thread_finished_notifier.notify exception: " << ex.what();
}
}};
boost::thread::attributes attributes;
if (stack_size) {
attributes.set_stack_size(*stack_size);
}
boost::thread thread{attributes, [run = std::move(run), &run_exception, &thread_finished_notifier] {
try {
run();
} catch (...) {
run_exception = std::current_exception();
}

try {
thread_finished_notifier.notify();
} catch (const std::exception& ex) {
log::Error() << "async_thread thread_finished_notifier.notify exception: " << ex.what();
}
}};

try {
co_await thread_finished_notifier.wait();
Expand Down
5 changes: 4 additions & 1 deletion silkworm/infra/concurrency/async_thread.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#pragma once

#include <functional>
#include <optional>

#include <silkworm/infra/concurrency/coroutine.hpp>

Expand All @@ -33,8 +34,10 @@ namespace silkworm::concurrency {
*
* @param run thread procedure
* @param stop a callback to signal the thread procedure to exit
* @param stack_size optional custom stack size for the created thread
* @return an awaitable that is pending until the thread finishes
*/
boost::asio::awaitable<void> async_thread(std::function<void()> run, std::function<void()> stop);
boost::asio::awaitable<void> async_thread(std::function<void()> run, std::function<void()> stop,
std::optional<std::size_t> stack_size = {});

} // namespace silkworm::concurrency
6 changes: 5 additions & 1 deletion silkworm/node/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ namespace silkworm::node {

constexpr uint64_t kMaxFileDescriptors{10'240};

//! Custom stack size for thread running block execution on EVM
constexpr uint64_t kExecutionThreadStackSize{16'777'216}; // 16MiB

using SentryClientPtr = std::shared_ptr<sentry::api::SentryClient>;

class NodeImpl final {
Expand Down Expand Up @@ -129,7 +132,8 @@ Task<void> NodeImpl::run_tasks() {
}

Task<void> NodeImpl::start_execution_server() {
return execution_server_.async_run();
// Thread running block execution requires custom stack size because of deep EVM call stacks
return execution_server_.async_run(/*stack_size=*/kExecutionThreadStackSize);
}

Task<void> NodeImpl::start_backend_kv_grpc_server() {
Expand Down

0 comments on commit 4a61f8d

Please sign in to comment.