diff --git a/test/adaptive_node_pool_test.cpp b/test/adaptive_node_pool_test.cpp index 0b47434..024a008 100644 --- a/test/adaptive_node_pool_test.cpp +++ b/test/adaptive_node_pool_test.cpp @@ -7,15 +7,21 @@ // See http://www.boost.org/libs/interprocess for documentation. // ////////////////////////////////////////////////////////////////////////////// - #include -#include +#include "node_pool_test.hpp" #include -using namespace boost::interprocess; - int main () { + using namespace boost::interprocess; + typedef managed_shared_memory::segment_manager segment_manager; + + typedef detail::private_adaptive_node_pool + node_pool_t; + + if(!test::test_all_node_pool()) + return 1; + return 0; } diff --git a/test/data_test.cpp b/test/data_test.cpp index 1fecf86..66bb0dc 100644 --- a/test/data_test.cpp +++ b/test/data_test.cpp @@ -17,6 +17,7 @@ #include #include #include +#include //std::remove #include "print_container.hpp" #include "get_process_id_name.hpp" diff --git a/test/dummy_test_allocator.hpp b/test/dummy_test_allocator.hpp index 2c7393f..af691f9 100644 --- a/test/dummy_test_allocator.hpp +++ b/test/dummy_test_allocator.hpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include //!\file //!Describes an allocator to test expand capabilities @@ -75,12 +75,12 @@ class dummy_test_allocator {} //!Constructor from other dummy_test_allocator. Never throws - dummy_test_allocator(const dummy_test_allocator &other) + dummy_test_allocator(const dummy_test_allocator &) {} //!Constructor from related dummy_test_allocator. Never throws template - dummy_test_allocator(const dummy_test_allocator &other) + dummy_test_allocator(const dummy_test_allocator &) {} /* pointer address(reference value) @@ -137,14 +137,14 @@ class dummy_test_allocator //!Equality test for same type of dummy_test_allocator template inline -bool operator==(const dummy_test_allocator &alloc1, - const dummy_test_allocator &alloc2) +bool operator==(const dummy_test_allocator &, + const dummy_test_allocator &) { return false; } //!Inequality test for same type of dummy_test_allocator template inline -bool operator!=(const dummy_test_allocator &alloc1, - const dummy_test_allocator &alloc2) +bool operator!=(const dummy_test_allocator &, + const dummy_test_allocator &) { return true; } } //namespace test { diff --git a/test/expand_bwd_test_allocator.hpp b/test/expand_bwd_test_allocator.hpp index 41c1c84..840a45e 100644 --- a/test/expand_bwd_test_allocator.hpp +++ b/test/expand_bwd_test_allocator.hpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include //!\file //!Describes an allocator to test expand capabilities @@ -147,7 +147,6 @@ class expand_bwd_test_allocator assert(0); throw std::bad_alloc(); } - return std::pair(0, true); } //!Returns maximum the number of objects the previously allocated memory diff --git a/test/file_mapping_test.cpp b/test/file_mapping_test.cpp index c0e8f13..b9851c9 100644 --- a/test/file_mapping_test.cpp +++ b/test/file_mapping_test.cpp @@ -16,6 +16,7 @@ #include #include #include +#include //std::remove #include "get_process_id_name.hpp" using namespace boost::interprocess; diff --git a/test/flat_tree_test.cpp b/test/flat_tree_test.cpp index 95acd84..80df430 100644 --- a/test/flat_tree_test.cpp +++ b/test/flat_tree_test.cpp @@ -123,6 +123,16 @@ int main() std::cout << "Error in set_test" << std::endl; return 1; } + + if (0 != set_test_copyable()){ + std::cout << "Error in set_test" << std::endl; + return 1; + } + if (0 != set_test()){ + std::cout << "Error in set_test" << std::endl; + return 1; + } + // if (0 != map_test("MyShmMultiMap2") (detail::make_move_iterator(&aux_vect3[0]) , detail::make_move_iterator(aux_vect3 + 50) , std::less(), segment.get_segment_manager()); - MyStdMultiMap *stdmultiset2 = new MyStdMultiMap(aux_vect2, aux_vect2 + 50); + MyStdMultiMap *stdmultimap2 = new MyStdMultiMap(aux_vect2, aux_vect2 + 50); if(!CheckEqualContainers(shmmap2, stdmap2)) return 1; - if(!CheckEqualContainers(shmmultiset2, stdmultiset2)) return 1; + if(!CheckEqualContainers(shmmultimap2, stdmultimap2)) return 1; + segment.destroy_ptr(shmmap2); - segment.destroy_ptr(shmmultiset2); + segment.destroy_ptr(shmmultimap2); delete stdmap2; - delete stdmultiset2; + delete stdmultimap2; } int i, j; diff --git a/test/memory_algorithm_test_template.hpp b/test/memory_algorithm_test_template.hpp index 5d62af4..817283f 100644 --- a/test/memory_algorithm_test_template.hpp +++ b/test/memory_algorithm_test_template.hpp @@ -17,6 +17,7 @@ #include #include #include +#include //std::remove namespace boost { namespace interprocess { namespace test { @@ -508,6 +509,102 @@ bool test_clear_free_memory(Allocator &a) return true; } + +//This test uses tests grow and shrink_to_fit functions +template +bool test_grow_shrink_to_fit(Allocator &a) +{ + std::vector buffers; + + std::size_t original_size = a.get_size(); + std::size_t original_free = a.get_free_memory(); + + a.shrink_to_fit(); + + if(!a.all_memory_deallocated() && a.check_sanity()) + return false; + + std::size_t shrunk_size = a.get_size(); + std::size_t shrunk_free_memory = a.get_free_memory(); + if(shrunk_size != a.get_min_size()) + return 1; + + a.grow(original_size - shrunk_size); + + if(!a.all_memory_deallocated() && a.check_sanity()) + return false; + + if(original_size != a.get_size()) + return false; + if(original_free != a.get_free_memory()) + return false; + + //Allocate memory + for(int i = 0; true; ++i){ + void *ptr = a.allocate(i, std::nothrow); + if(!ptr) + break; + buffers.push_back(ptr); + } + + //Now deallocate the half of the blocks + //so expand maybe can merge new free blocks + for(int i = 0, max = (int)buffers.size() + ;i < max + ;++i){ + if(i%2){ + a.deallocate(buffers[i]); + buffers[i] = 0; + } + } + + //Deallocate the rest of the blocks + + //Deallocate it in non sequential order + for(int j = 0, max = (int)buffers.size() + ;j < max + ;++j){ + int pos = (j%4)*((int)buffers.size())/4; + std::size_t old_free = a.get_free_memory(); + a.shrink_to_fit(); + if(!a.check_sanity()) return false; + if(original_size < a.get_size()) return false; + if(old_free < a.get_free_memory()) return false; + + a.grow(original_size - a.get_size()); + + if(!a.check_sanity()) return false; + if(original_size != a.get_size()) return false; + if(old_free != a.get_free_memory()) return false; + + a.deallocate(buffers[pos]); + buffers.erase(buffers.begin()+pos); + } + + //Now shrink it to the maximum + a.shrink_to_fit(); + + if(a.get_size() != a.get_min_size()) + return 1; + + if(shrunk_free_memory != a.get_free_memory()) + return 1; + + if(!a.all_memory_deallocated() && a.check_sanity()) + return false; + + a.grow(original_size - shrunk_size); + + if(original_size != a.get_size()) + return false; + if(original_free != a.get_free_memory()) + return false; + + if(!a.all_memory_deallocated() && a.check_sanity()) + return false; + return true; +} + //This test allocates multiple values until there is no more memory //and after that deallocates all in the inverse order template @@ -526,6 +623,8 @@ bool test_many_equal_allocation(Allocator &a) void *ptr = a.allocate(i, std::nothrow); if(!ptr) break; + if(!a.check_sanity()) + return false; buffers2.push_back(ptr); } @@ -540,6 +639,9 @@ bool test_many_equal_allocation(Allocator &a) } } + if(!a.check_sanity()) + return false; + std::vector buffers; for(int i = 0; true; ++i){ multiallocation_iterator it = a.allocate_many(i+1, (i+1)*2, std::nothrow); @@ -555,6 +657,9 @@ bool test_many_equal_allocation(Allocator &a) return false; } + if(!a.check_sanity()) + return false; + switch(t){ case DirectDeallocation: { @@ -811,6 +916,15 @@ bool test_all_allocation(Allocator &a) return false; } + std::cout << "Starting test_grow_shrink_to_fit. Class: " + << typeid(a).name() << std::endl; + + if(!test_grow_shrink_to_fit(a)){ + std::cout << "test_grow_shrink_to_fit failed. Class: " + << typeid(a).name() << std::endl; + return false; + } + return true; } diff --git a/test/node_pool_test.cpp b/test/node_pool_test.cpp index 58899c3..418ce4d 100644 --- a/test/node_pool_test.cpp +++ b/test/node_pool_test.cpp @@ -8,157 +8,19 @@ // ////////////////////////////////////////////////////////////////////////////// #include -#include +#include "node_pool_test.hpp" #include -#include -#include -#include -#include -#include -#include -#include "get_process_id_name.hpp" -using namespace boost::interprocess; -template -struct test_node_pool -{ - static bool allocate_then_deallocate(NodePool &pool); - static bool deallocate_free_chunks(NodePool &pool); -}; - -template -bool test_node_pool::allocate_then_deallocate(NodePool &pool) -{ - const std::size_t num_alloc = 1 + 3*NodePool::nodes_per_chunk; - - std::vector nodes; - - //Precondition, the pool must be empty - if(0 != pool.num_free_nodes()){ - return false; - } - - //First allocate nodes - for(std::size_t i = 0; i < num_alloc; ++i){ - nodes.push_back(pool.allocate(1)); - } - - //Check that the free count is correct - if((NodePool::nodes_per_chunk - 1) != pool.num_free_nodes()){ - return false; - } - - //Now deallocate all and check again - for(std::size_t i = 0; i < num_alloc; ++i){ - pool.deallocate(nodes[i], 1); - } - - //Check that the free count is correct - if(4*NodePool::nodes_per_chunk != pool.num_free_nodes()){ - return false; - } - - pool.deallocate_free_chunks(); - - if(0 != pool.num_free_nodes()){ - return false; - } - - return true; -} - -template -bool test_node_pool::deallocate_free_chunks(NodePool &pool) -{ - const std::size_t max_chunks = 10; - const std::size_t max_nodes = max_chunks*NodePool::nodes_per_chunk; - const std::size_t nodes_per_chunk = NodePool::nodes_per_chunk; - - std::vector nodes; - - //Precondition, the pool must be empty - if(0 != pool.num_free_nodes()){ - return false; - } - - //First allocate nodes - for(std::size_t i = 0; i < max_nodes; ++i){ - nodes.push_back(pool.allocate(1)); - } - - //Check that the free count is correct - if(0 != pool.num_free_nodes()){ - return false; - } - - //Now deallocate one of each chunk per iteration - for(std::size_t node_i = 0; node_i < nodes_per_chunk; ++node_i){ - //Deallocate a node per chunk - for(std::size_t i = 0; i < max_chunks; ++i){ - pool.deallocate(nodes[i*nodes_per_chunk + node_i], 1); - } - - //Check that the free count is correct - if(max_chunks*(node_i+1) != pool.num_free_nodes()){ - return false; - } - - //Now try to deallocate free chunks - pool.deallocate_free_chunks(); - - //Until we don't deallocate the last node of every chunk - //no node should be deallocated - if(node_i != (nodes_per_chunk - 1)){ - if(max_chunks*(node_i+1) != pool.num_free_nodes()){ - return false; - } - } - else{ - //If this is the last iteration, all the memory should - //have been deallocated. - if(0 != pool.num_free_nodes()){ - return false; - } - } - } - - return true; -} - -template -bool test_all_node_pool() -{ - typedef managed_shared_memory::segment_manager segment_manager; - typedef detail::private_node_pool - node_pool_t; - - typedef test_node_pool test_node_pool_t; - shared_memory_object::remove(test::get_process_id_name()); - { - managed_shared_memory shm(create_only, test::get_process_id_name(), 16*1024); - - typedef deleter deleter_t; - typedef unique_ptr unique_ptr_t; - - //Delete the pool when the tests end - unique_ptr_t p - (shm.construct(anonymous_instance)(shm.get_segment_manager()) - ,deleter_t(shm.get_segment_manager())); - - //Now call each test - if(!test_node_pool_t::allocate_then_deallocate(*p)) - return false; - if(!test_node_pool_t::deallocate_free_chunks(*p)) - return false; - } - shared_memory_object::remove(test::get_process_id_name()); - return true; -} int main () { - if(!test_all_node_pool<4, 64>()) + using namespace boost::interprocess; + typedef managed_shared_memory::segment_manager segment_manager; + typedef detail::private_node_pool + node_pool_t; + + if(!test::test_all_node_pool()) return 1; return 0; diff --git a/test/node_pool_test.hpp b/test/node_pool_test.hpp new file mode 100644 index 0000000..e4bc832 --- /dev/null +++ b/test/node_pool_test.hpp @@ -0,0 +1,163 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#include +#include +#include +#include +#include +#include +#include +#include +#include "get_process_id_name.hpp" + +namespace boost { +namespace interprocess { +namespace test { + +template +struct test_node_pool +{ + static bool allocate_then_deallocate(NodePool &pool); + static bool deallocate_free_chunks(NodePool &pool); +}; + +template +bool test_node_pool::allocate_then_deallocate(NodePool &pool) +{ + const std::size_t num_alloc = 1 + 3*pool.get_real_num_node(); + + std::vector nodes; + + //Precondition, the pool must be empty + if(0 != pool.num_free_nodes()){ + return false; + } + + //First allocate nodes + for(std::size_t i = 0; i < num_alloc; ++i){ + nodes.push_back(pool.allocate(1)); + } + + //Check that the free count is correct + if((pool.get_real_num_node() - 1) != pool.num_free_nodes()){ + return false; + } + + //Now deallocate all and check again + for(std::size_t i = 0; i < num_alloc; ++i){ + pool.deallocate(nodes[i], 1); + } + + //Check that the free count is correct + if(4*pool.get_real_num_node() != pool.num_free_nodes()){ + return false; + } + + pool.deallocate_free_chunks(); + + if(0 != pool.num_free_nodes()){ + return false; + } + + return true; +} + +template +bool test_node_pool::deallocate_free_chunks(NodePool &pool) +{ + const std::size_t max_chunks = 10; + const std::size_t max_nodes = max_chunks*pool.get_real_num_node(); + const std::size_t nodes_per_chunk = pool.get_real_num_node(); + + std::vector nodes; + + //Precondition, the pool must be empty + if(0 != pool.num_free_nodes()){ + return false; + } + + //First allocate nodes + for(std::size_t i = 0; i < max_nodes; ++i){ + nodes.push_back(pool.allocate(1)); + } + + //Check that the free count is correct + if(0 != pool.num_free_nodes()){ + return false; + } + + //Now deallocate one of each chunk per iteration + for(std::size_t node_i = 0; node_i < nodes_per_chunk; ++node_i){ + //Deallocate a node per chunk + for(std::size_t i = 0; i < max_chunks; ++i){ + pool.deallocate(nodes[i*nodes_per_chunk + node_i], 1); + } + + //Check that the free count is correct + if(max_chunks*(node_i+1) != pool.num_free_nodes()){ + return false; + } + + //Now try to deallocate free chunks + pool.deallocate_free_chunks(); + + //Until we don't deallocate the last node of every chunk + //no node should be deallocated + if(node_i != (nodes_per_chunk - 1)){ + if(max_chunks*(node_i+1) != pool.num_free_nodes()){ + return false; + } + } + else{ + //If this is the last iteration, all the memory should + //have been deallocated. + if(0 != pool.num_free_nodes()){ + return false; + } + } + } + + return true; +} + +template +bool test_all_node_pool() +{ + using namespace boost::interprocess; + typedef managed_shared_memory::segment_manager segment_manager; + + typedef boost::interprocess::test::test_node_pool test_node_pool_t; + shared_memory_object::remove(test::get_process_id_name()); + { + managed_shared_memory shm(create_only, test::get_process_id_name(), 16*1024); + + typedef deleter deleter_t; + typedef unique_ptr unique_ptr_t; + + //Delete the pool when the tests end + unique_ptr_t p + (shm.construct(anonymous_instance)(shm.get_segment_manager()) + ,deleter_t(shm.get_segment_manager())); + + //Now call each test + if(!test_node_pool_t::allocate_then_deallocate(*p)) + return false; + if(!test_node_pool_t::deallocate_free_chunks(*p)) + return false; + } + shared_memory_object::remove(test::get_process_id_name()); + return true; +} + +} //namespace test { +} //namespace interprocess { +} //namespace boost { + +#include diff --git a/test/null_index_test.cpp b/test/null_index_test.cpp index de31b7d..e428361 100644 --- a/test/null_index_test.cpp +++ b/test/null_index_test.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include "get_process_id_name.hpp" diff --git a/test/set_test.hpp b/test/set_test.hpp index c06a642..01c90f6 100644 --- a/test/set_test.hpp +++ b/test/set_test.hpp @@ -98,6 +98,7 @@ int set_test () std::cout << "Error in construct(MyShmMultiSet2)" << std::endl; return 1; } + segment.destroy_ptr(shmset2); segment.destroy_ptr(shmmultiset2); delete stdset2; diff --git a/test/sharable_mutex_test_template.hpp b/test/sharable_mutex_test_template.hpp index e6a2d70..4858646 100644 --- a/test/sharable_mutex_test_template.hpp +++ b/test/sharable_mutex_test_template.hpp @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include "util.hpp" namespace boost { namespace interprocess { namespace test { diff --git a/test/shared_memory_mapping_test.cpp b/test/shared_memory_mapping_test.cpp index 98a5ae8..47ece77 100644 --- a/test/shared_memory_mapping_test.cpp +++ b/test/shared_memory_mapping_test.cpp @@ -117,6 +117,7 @@ int main () catch(std::exception &exc){ shared_memory_object::remove(test::get_process_id_name()); std::cout << "Unhandled exception: " << exc.what() << std::endl; + return 1; } shared_memory_object::remove(test::get_process_id_name()); return 0; diff --git a/test/shared_memory_test.cpp b/test/shared_memory_test.cpp index 012e619..f336409 100644 --- a/test/shared_memory_test.cpp +++ b/test/shared_memory_test.cpp @@ -79,6 +79,7 @@ int main () catch(std::exception &ex){ shared_memory_object::remove(ShmName); std::cout << ex.what() << std::endl; + return 1; } shared_memory_object::remove(ShmName); return 0; diff --git a/test/tree_test.cpp b/test/tree_test.cpp index d8722cc..eea66a1 100644 --- a/test/tree_test.cpp +++ b/test/tree_test.cpp @@ -132,7 +132,6 @@ int main () return 1; } - using namespace boost::interprocess::detail; if(0 != test::set_test_copyable