From 5981fcf3b3421acf03bfe512c669c94b0e361ce3 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sun, 4 Aug 2024 15:38:38 -0400 Subject: [PATCH 1/4] Comment. --- include/bitcoin/node/sessions/attach.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/bitcoin/node/sessions/attach.hpp b/include/bitcoin/node/sessions/attach.hpp index 5e8177e2..f618c343 100644 --- a/include/bitcoin/node/sessions/attach.hpp +++ b/include/bitcoin/node/sessions/attach.hpp @@ -106,6 +106,7 @@ class attach network::channel::ptr create_channel(const network::socket::ptr& socket, bool quiet) NOEXCEPT override { + // This memory arena is NOT thread safe. return std::make_shared(session::get_memory(), network::session::log, socket, network::session::settings(), network::session::create_key(), quiet); From ceac3515cc9e6b2b7bb3e8bb4cd8724b492c5cfd Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sun, 4 Aug 2024 15:39:16 -0400 Subject: [PATCH 2/4] Style, comments. --- include/bitcoin/node/full_node.hpp | 2 +- src/full_node.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/bitcoin/node/full_node.hpp b/include/bitcoin/node/full_node.hpp index 5ac7ca61..6794055f 100644 --- a/include/bitcoin/node/full_node.hpp +++ b/include/bitcoin/node/full_node.hpp @@ -166,10 +166,10 @@ class BCN_API full_node // These are thread safe. const configuration& config_; - block_memory memory_; query& query_; // These are protected by strand. + block_memory memory_; chaser_block chaser_block_; chaser_header chaser_header_; chaser_check chaser_check_; diff --git a/src/full_node.cpp b/src/full_node.cpp index 6332de7c..9603e482 100644 --- a/src/full_node.cpp +++ b/src/full_node.cpp @@ -40,8 +40,8 @@ full_node::full_node(query& query, const configuration& configuration, const logger& log) NOEXCEPT : p2p(configuration.network, log), config_(configuration), - memory_(configuration.node.allocation(), configuration.network.threads), query_(query), + memory_(configuration.node.allocation(), configuration.network.threads), chaser_block_(*this), chaser_header_(*this), chaser_check_(*this), From c363b14c7659a84401225d28392d0f99467a4315 Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sun, 4 Aug 2024 19:51:22 -0400 Subject: [PATCH 3/4] Comments. --- src/protocols/protocol_block_in_31800.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/protocols/protocol_block_in_31800.cpp b/src/protocols/protocol_block_in_31800.cpp index 5e3a43e1..96769d8a 100644 --- a/src/protocols/protocol_block_in_31800.cpp +++ b/src/protocols/protocol_block_in_31800.cpp @@ -373,7 +373,10 @@ bool protocol_block_in_31800::handle_receive_block(const code& ec, // protocol bind captures self, keeping channel alive until closure delete. ////populate(block, link, height, BIND(complete, _1, block, height)); notify(ec, chase::checked, height); - fire(events::block_archived, height); + fire(events::block_archived, height /*block->get_retainer()->allocation()*/); + + ////LOGA("Height: " << height << " size: " << size + //// << " bytes: " << block->get_retainer()->allocation()); count(size); map_->erase(it); From 33cb9fba639add0f5f243dac264b7e0492eb6b2c Mon Sep 17 00:00:00 2001 From: evoskuil Date: Sun, 4 Aug 2024 19:52:05 -0400 Subject: [PATCH 4/4] Add retainer allocation param, add arena::get_capacity(). --- include/bitcoin/node/block_arena.hpp | 2 ++ include/bitcoin/node/block_memory.hpp | 10 ++++------ src/block_arena.cpp | 23 +++++++++++++++++------ src/block_memory.cpp | 24 ++++++++++++------------ 4 files changed, 35 insertions(+), 24 deletions(-) diff --git a/include/bitcoin/node/block_arena.hpp b/include/bitcoin/node/block_arena.hpp index 7a1ceec8..b18b3101 100644 --- a/include/bitcoin/node/block_arena.hpp +++ b/include/bitcoin/node/block_arena.hpp @@ -39,6 +39,7 @@ class BCN_API block_arena final block_arena& operator=(block_arena&& other) NOEXCEPT; + /// Get memory block retainer mutex. inline std::shared_mutex& get_mutex() NOEXCEPT { return mutex_; @@ -48,6 +49,7 @@ class BCN_API block_arena final void* do_allocate(size_t bytes, size_t align) THROWS override; void do_deallocate(void* ptr, size_t bytes, size_t align) NOEXCEPT override; bool do_is_equal(const arena& other) const NOEXCEPT override; + size_t do_get_capacity() const NOEXCEPT override; // These are thread safe. std::shared_mutex mutex_{}; diff --git a/include/bitcoin/node/block_memory.hpp b/include/bitcoin/node/block_memory.hpp index 21f77173..a015246a 100644 --- a/include/bitcoin/node/block_memory.hpp +++ b/include/bitcoin/node/block_memory.hpp @@ -20,8 +20,6 @@ #define LIBBITCOIN_NODE_BLOCK_MEMORY_HPP #include -#include -#include #include #include #include @@ -43,17 +41,17 @@ class BCN_API block_memory final arena* get_arena() NOEXCEPT override; /// Each thread obtains its arena's retainer. - retainer::ptr get_retainer() NOEXCEPT override; + retainer::ptr get_retainer(size_t allocation=zero) NOEXCEPT override; protected: - block_arena* get_block_arena() THROWS; + block_arena* get_block_arena() const THROWS; private: // This is thread safe. - std::atomic_size_t count_; + mutable std::atomic_size_t count_; // This is protected by constructor init and thread_local indexation. - std::vector arenas_; + mutable std::vector arenas_; }; } // namespace node diff --git a/src/block_arena.cpp b/src/block_arena.cpp index d9ebaa21..9850e07e 100644 --- a/src/block_arena.cpp +++ b/src/block_arena.cpp @@ -18,7 +18,6 @@ */ #include -#include #include #include @@ -85,18 +84,25 @@ void* block_arena::do_allocate(size_t bytes, size_t align) THROWS BC_ASSERT_MSG(power2(floored_log2(align)) == align, "align power"); BC_ASSERT_MSG(!is_add_overflow(bytes, sub1(align)), "align overflow"); - auto aligned = to_aligned(offset_, align); - if (bytes > system::floored_subtract(capacity_, aligned)) + auto aligned_offset = to_aligned(offset_, align); + auto padding = aligned_offset - offset_; + auto allocation = padding + bytes; + + // Wraps if allocation would overflow. + if (allocation > get_capacity()) { + // Block until arena retainers are all released. std::unique_lock lock(mutex_); - aligned = offset_ = zero; + aligned_offset = offset_ = zero; + allocation = bytes; + // Throws if necessary allocation exceeds buffer. if (bytes > capacity_) throw allocation_exception(); } - offset_ = aligned + bytes; - return memory_map_ + aligned; + offset_ += allocation; + return memory_map_ + aligned_offset; } void block_arena::do_deallocate(void*, size_t, size_t) NOEXCEPT @@ -109,6 +115,11 @@ bool block_arena::do_is_equal(const arena& other) const NOEXCEPT return &other == this; } +size_t block_arena::do_get_capacity() const NOEXCEPT +{ + return system::floored_subtract(capacity_, offset_); +} + BC_POP_WARNING() BC_POP_WARNING() diff --git a/src/block_memory.cpp b/src/block_memory.cpp index 6fdf29e7..f7af4b48 100644 --- a/src/block_memory.cpp +++ b/src/block_memory.cpp @@ -18,13 +18,15 @@ */ #include +#include #include -#include #include namespace libbitcoin { namespace node { +BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT) + block_memory::block_memory(size_t bytes, size_t threads) NOEXCEPT : count_{}, arenas_{} { @@ -35,30 +37,28 @@ block_memory::block_memory(size_t bytes, size_t threads) NOEXCEPT arena* block_memory::get_arena() NOEXCEPT { - BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT) return get_block_arena(); - BC_POP_WARNING() } -retainer::ptr block_memory::get_retainer() NOEXCEPT +retainer::ptr block_memory::get_retainer(size_t allocation) NOEXCEPT { - BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT) - return std::make_shared(get_block_arena()->get_mutex()); - BC_POP_WARNING() + return std::make_shared(get_block_arena()->get_mutex(), + allocation); } // protected - -block_arena* block_memory::get_block_arena() THROWS +block_arena* block_memory::get_block_arena() const THROWS { - static thread_local auto index = count_.fetch_add(one); + static thread_local auto index = count_.fetch_add(one, + std::memory_order_relaxed); // More threads are requesting an arena than specified at construct. - if (index >= arenas_.size()) - throw allocation_exception(); + BC_ASSERT(index < arenas_.size()); return &arenas_.at(index); } +BC_POP_WARNING() + } // namespace node } // namespace libbitcoin