dncurrency/nano/core_test/memory_pool.cpp

100 lines
3.5 KiB
C++

#include <nano/lib/memory.hpp>
#include <nano/node/active_transactions.hpp>
#include <nano/secure/common.hpp>
#include <gtest/gtest.h>
#include <memory>
#include <vector>
namespace
{
/** This allocator records the size of all allocations that happen */
template <class T>
class record_allocations_new_delete_allocator
{
public:
using value_type = T;
explicit record_allocations_new_delete_allocator (std::vector<size_t> * allocated) :
allocated (allocated)
{
}
template <typename U>
record_allocations_new_delete_allocator (const record_allocations_new_delete_allocator<U> & a)
{
allocated = a.allocated;
}
template <typename U>
record_allocations_new_delete_allocator & operator= (const record_allocations_new_delete_allocator<U> &) = delete;
T * allocate (size_t num_to_allocate)
{
auto size_allocated = (sizeof (T) * num_to_allocate);
allocated->push_back (size_allocated);
return static_cast<T *> (::operator new (size_allocated));
}
void deallocate (T * p, size_t num_to_deallocate)
{
::operator delete (p);
}
std::vector<size_t> * allocated;
};
template <typename T>
size_t get_allocated_size ()
{
std::vector<size_t> allocated;
record_allocations_new_delete_allocator<T> alloc (&allocated);
(void)std::allocate_shared<T, record_allocations_new_delete_allocator<T>> (alloc);
debug_assert (allocated.size () == 1);
return allocated.front ();
}
}
TEST (memory_pool, validate_cleanup)
{
// This might be turned off, e.g on Mac for instance, so don't do this test
if (!nano::get_use_memory_pools ())
{
return;
}
nano::make_shared<nano::open_block> ();
nano::make_shared<nano::receive_block> ();
nano::make_shared<nano::send_block> ();
nano::make_shared<nano::change_block> ();
nano::make_shared<nano::state_block> ();
nano::make_shared<nano::vote> ();
ASSERT_TRUE (nano::purge_shared_ptr_singleton_pool_memory<nano::open_block> ());
ASSERT_TRUE (nano::purge_shared_ptr_singleton_pool_memory<nano::receive_block> ());
ASSERT_TRUE (nano::purge_shared_ptr_singleton_pool_memory<nano::send_block> ());
ASSERT_TRUE (nano::purge_shared_ptr_singleton_pool_memory<nano::state_block> ());
ASSERT_TRUE (nano::purge_shared_ptr_singleton_pool_memory<nano::vote> ());
// Change blocks have the same size as open_block so won't deallocate any memory
ASSERT_FALSE (nano::purge_shared_ptr_singleton_pool_memory<nano::change_block> ());
ASSERT_EQ (nano::determine_shared_ptr_pool_size<nano::open_block> (), get_allocated_size<nano::open_block> () - sizeof (size_t));
ASSERT_EQ (nano::determine_shared_ptr_pool_size<nano::receive_block> (), get_allocated_size<nano::receive_block> () - sizeof (size_t));
ASSERT_EQ (nano::determine_shared_ptr_pool_size<nano::send_block> (), get_allocated_size<nano::send_block> () - sizeof (size_t));
ASSERT_EQ (nano::determine_shared_ptr_pool_size<nano::change_block> (), get_allocated_size<nano::change_block> () - sizeof (size_t));
ASSERT_EQ (nano::determine_shared_ptr_pool_size<nano::state_block> (), get_allocated_size<nano::state_block> () - sizeof (size_t));
ASSERT_EQ (nano::determine_shared_ptr_pool_size<nano::vote> (), get_allocated_size<nano::vote> () - sizeof (size_t));
{
nano::active_transactions::ordered_cache inactive_votes_cache;
nano::account representative{ 1 };
nano::block_hash hash{ 1 };
uint64_t timestamp{ 1 };
nano::inactive_cache_status default_status{};
inactive_votes_cache.emplace (std::chrono::steady_clock::now (), hash, representative, timestamp, default_status);
}
ASSERT_TRUE (nano::purge_singleton_inactive_votes_cache_pool_memory ());
}