Skip to content

Commit

Permalink
Merge pull request #679 from evoskuil/master
Browse files Browse the repository at this point in the history
Add initial memory allocation tests.
  • Loading branch information
evoskuil authored Aug 25, 2024
2 parents 3d3a915 + 6e6349b commit 936ad5a
Show file tree
Hide file tree
Showing 10 changed files with 594 additions and 27 deletions.
3 changes: 3 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,11 @@ check_PROGRAMS = test/libbitcoin-node-test
test_libbitcoin_node_test_CPPFLAGS = -I${srcdir}/include ${bitcoin_database_BUILD_CPPFLAGS} ${bitcoin_network_BUILD_CPPFLAGS}
test_libbitcoin_node_test_LDADD = src/libbitcoin-node.la ${boost_unit_test_framework_LIBS} ${bitcoin_database_LIBS} ${bitcoin_network_LIBS}
test_libbitcoin_node_test_SOURCES = \
test/block_arena.cpp \
test/block_memory.cpp \
test/configuration.cpp \
test/error.cpp \
test/full_node.cpp \
test/main.cpp \
test/node.cpp \
test/settings.cpp \
Expand Down
3 changes: 3 additions & 0 deletions builds/cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,11 @@ target_link_libraries( ${CANONICAL_LIB_NAME}
#------------------------------------------------------------------------------
if (with-tests)
add_executable( libbitcoin-node-test
"../../test/block_arena.cpp"
"../../test/block_memory.cpp"
"../../test/configuration.cpp"
"../../test/error.cpp"
"../../test/full_node.cpp"
"../../test/main.cpp"
"../../test/node.cpp"
"../../test/settings.cpp"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@
<Import Project="$(ProjectDir)$(ProjectName).props" />
</ImportGroup>
<ItemGroup>
<ClCompile Include="..\..\..\..\test\block_arena.cpp" />
<ClCompile Include="..\..\..\..\test\block_memory.cpp" />
<ClCompile Include="..\..\..\..\test\chasers\chaser.cpp" />
<ClCompile Include="..\..\..\..\test\chasers\chaser_block.cpp" />
<ClCompile Include="..\..\..\..\test\chasers\chaser_check.cpp" />
Expand All @@ -81,6 +83,7 @@
<ClCompile Include="..\..\..\..\test\chasers\chaser_validate.cpp" />
<ClCompile Include="..\..\..\..\test\configuration.cpp" />
<ClCompile Include="..\..\..\..\test\error.cpp" />
<ClCompile Include="..\..\..\..\test\full_node.cpp" />
<ClCompile Include="..\..\..\..\test\main.cpp" />
<ClCompile Include="..\..\..\..\test\node.cpp" />
<ClCompile Include="..\..\..\..\test\protocols\protocol.cpp" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\..\test\block_arena.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\test\block_memory.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\test\chasers\chaser.cpp">
<Filter>src\chasers</Filter>
</ClCompile>
Expand Down Expand Up @@ -54,6 +60,9 @@
<ClCompile Include="..\..\..\..\test\error.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\test\full_node.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\test\main.cpp">
<Filter>src</Filter>
</ClCompile>
Expand Down
43 changes: 29 additions & 14 deletions include/bitcoin/node/block_arena.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ namespace libbitcoin {
namespace node {

/// Thread UNSAFE detachable linked-linear memory arena.
class BCN_API block_arena final
class BCN_API block_arena
: public arena
{
public:
DELETE_COPY(block_arena);

block_arena(size_t multiple) NOEXCEPT;
block_arena(block_arena&& other) NOEXCEPT;
~block_arena() NOEXCEPT;
virtual ~block_arena() NOEXCEPT;

block_arena& operator=(block_arena&& other) NOEXCEPT;

Expand All @@ -49,6 +49,33 @@ class BCN_API block_arena final
void release(void* address) NOEXCEPT override;

protected:
/// Determine alignment offset.
static constexpr size_t to_aligned(size_t value, size_t align) NOEXCEPT
{
using namespace system;
BC_ASSERT_MSG(is_nonzero(align), "align zero");
BC_ASSERT_MSG(!is_add_overflow(value, sub1(align)), "overflow");
BC_ASSERT_MSG(power2(floored_log2(align)) == align, "align power");
BC_ASSERT_MSG(align <= alignof(std::max_align_t), "align overflow");
return (value + sub1(align)) & ~sub1(align);
}

/// Malloc throws if memory is not allocated.
virtual INLINE void* malloc(size_t bytes) THROWS
{
BC_PUSH_WARNING(NO_MALLOC_OR_FREE)
return std::malloc(bytes);
BC_POP_WARNING()
}

/// Free does not throw, behavior is undefined if address is incorrect.
virtual INLINE void free(void* address) NOEXCEPT
{
BC_PUSH_WARNING(NO_MALLOC_OR_FREE)
std::free(address);
BC_POP_WARNING()
}

/// Link a memory chunk to the allocated stack.
void push(size_t minimum=zero) THROWS;

Expand Down Expand Up @@ -79,17 +106,6 @@ class BCN_API block_arena final
return system::floored_subtract(size_, offset_);
}

private:
constexpr size_t to_aligned(size_t value, size_t align) NOEXCEPT
{
using namespace system;
BC_ASSERT_MSG(is_nonzero(align), "align zero");
BC_ASSERT_MSG(!is_add_overflow(value, sub1(align)), "overflow");
BC_ASSERT_MSG(power2(floored_log2(align)) == align, "align power");
BC_ASSERT_MSG(align <= alignof(std::max_align_t), "align overflow");
return (value + sub1(align)) & ~sub1(align);
}

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;
Expand All @@ -100,7 +116,6 @@ class BCN_API block_arena final
size_t offset_;
size_t total_;
size_t size_;

};

} // namespace node
Expand Down
6 changes: 3 additions & 3 deletions include/bitcoin/node/block_memory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace libbitcoin {
namespace node {

/// Thread SAFE linked-linear arena allocator.
class BCN_API block_memory final
class BCN_API block_memory
: public network::memory
{
public:
Expand All @@ -41,9 +41,9 @@ class BCN_API block_memory final
/// Each thread obtains an arena.
arena* get_arena() NOEXCEPT override;

private:
protected:
// This is thread safe.
std::atomic_size_t count_{};
std::atomic_size_t count_{ zero };

// This is protected by constructor init and thread_local indexation.
std::vector<block_arena> arenas_{};
Expand Down
12 changes: 2 additions & 10 deletions src/block_arena.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ block_arena::block_arena(block_arena&& other) NOEXCEPT

block_arena::~block_arena() NOEXCEPT
{
release(memory_map_);
}

block_arena& block_arena::operator=(block_arena&& other) NOEXCEPT
Expand Down Expand Up @@ -96,11 +95,7 @@ void block_arena::release(void* address) NOEXCEPT
while (!is_null(address))
{
const auto link = get_link(pointer_cast<uint8_t>(address));

BC_PUSH_WARNING(NO_MALLOC_OR_FREE)
std::free(address);
BC_POP_WARNING()

free(address);
address = link;
}
}
Expand All @@ -115,10 +110,7 @@ void block_arena::push(size_t minimum) THROWS
// Ensure next allocation accomodates link plus current request.
BC_ASSERT(!is_add_overflow(minimum, link_size));
size_ = std::max(size_, minimum + link_size);

BC_PUSH_WARNING(NO_MALLOC_OR_FREE)
const auto map = pointer_cast<uint8_t>(std::malloc(size_));
BC_POP_WARNING()
const auto map = pointer_cast<uint8_t>(malloc(size_));

if (is_null(map))
throw allocation_exception{};
Expand Down
Loading

0 comments on commit 936ad5a

Please sign in to comment.