📄 memory_algorithm_test_template.hpp
字号:
//Test allocated memory is zero for(int i = 0, max = buffers.size(); i < max; ++i){ for(int j = 0; j < i; ++j){ if(static_cast<char*>(buffers[i])[j]) return false; } } //Deallocate all for(int j = (int)buffers.size() ;j-- ;){ a.deallocate(buffers[j]); } if(!a.all_memory_deallocated() && a.check_sanity()) return false; return true;}//This test uses tests grow and shrink_to_fit functionstemplate<class Allocator>bool test_grow_shrink_to_fit(Allocator &a){ std::vector<void*> 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; std::size_t size = a.size(ptr); std::memset(ptr, 0, size); 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%5)*((int)buffers.size())/4; if(pos == int(buffers.size())) --pos; a.deallocate(buffers[pos]); buffers.erase(buffers.begin()+pos); 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; } //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 ordertemplate<class Allocator>bool test_many_equal_allocation(Allocator &a){ typedef typename Allocator::multiallocation_iterator multiallocation_iterator; for( deallocation_type t = DirectDeallocation ; t != EndDeallocationType ; t = (deallocation_type)((int)t + 1)){ std::size_t free_memory = a.get_free_memory(); std::vector<void*> buffers2; //Allocate buffers with extra memory for(int i = 0; true; ++i){ void *ptr = a.allocate(i, std::nothrow); if(!ptr) break; std::size_t size = a.size(ptr); std::memset(ptr, 0, size); if(!a.check_sanity()) return false; buffers2.push_back(ptr); } //Now deallocate the half of the blocks //so expand maybe can merge new free blocks for(int i = 0, max = (int)buffers2.size() ;i < max ;++i){ if(i%2){ a.deallocate(buffers2[i]); buffers2[i] = 0; } } if(!a.check_sanity()) return false; std::vector<void*> buffers; for(int i = 0; true; ++i){ multiallocation_iterator it = a.allocate_many(i+1, (i+1)*2, std::nothrow); if(!it) break; multiallocation_iterator itend; std::size_t n = 0; for(; it != itend; ++n){ buffers.push_back(&*it++); } if(n != std::size_t((i+1)*2)) return false; } if(!a.check_sanity()) return false; switch(t){ case DirectDeallocation: { for(int j = 0, max = (int)buffers.size() ;j < max ;++j){ a.deallocate(buffers[j]); } } break; case InverseDeallocation: { for(int j = (int)buffers.size() ;j-- ;){ a.deallocate(buffers[j]); } } break; case MixedDeallocation: { for(int j = 0, max = (int)buffers.size() ;j < max ;++j){ int pos = (j%4)*((int)buffers.size())/4; a.deallocate(buffers[pos]); buffers.erase(buffers.begin()+pos); } } break; default: break; } //Deallocate the rest of the blocks //Deallocate it in non sequential order for(int j = 0, max = (int)buffers2.size() ;j < max ;++j){ int pos = (j%4)*((int)buffers2.size())/4; a.deallocate(buffers2[pos]); buffers2.erase(buffers2.begin()+pos); } bool ok = free_memory == a.get_free_memory() && a.all_memory_deallocated() && a.check_sanity(); if(!ok) return ok; } return true;}//This test allocates multiple values until there is no more memory//and after that deallocates all in the inverse ordertemplate<class Allocator>bool test_many_different_allocation(Allocator &a){ typedef typename Allocator::multiallocation_iterator multiallocation_iterator; const std::size_t ArraySize = 11; std::size_t requested_sizes[ArraySize]; for(std::size_t i = 0; i < ArraySize; ++i){ requested_sizes[i] = 4*i; } for( deallocation_type t = DirectDeallocation ; t != EndDeallocationType ; t = (deallocation_type)((int)t + 1)){ std::size_t free_memory = a.get_free_memory(); std::vector<void*> buffers2; //Allocate buffers with extra memory for(int i = 0; true; ++i){ void *ptr = a.allocate(i, std::nothrow); if(!ptr) break; std::size_t size = a.size(ptr); std::memset(ptr, 0, size); buffers2.push_back(ptr); } //Now deallocate the half of the blocks //so expand maybe can merge new free blocks for(int i = 0, max = (int)buffers2.size() ;i < max ;++i){ if(i%2){ a.deallocate(buffers2[i]); buffers2[i] = 0; } } std::vector<void*> buffers; for(int i = 0; true; ++i){ multiallocation_iterator it = a.allocate_many(requested_sizes, ArraySize, 1, std::nothrow); if(!it) break; multiallocation_iterator itend; std::size_t n = 0; for(; it != itend; ++n){ buffers.push_back(&*it++); } if(n != ArraySize) return false; } switch(t){ case DirectDeallocation: { for(int j = 0, max = (int)buffers.size() ;j < max ;++j){ a.deallocate(buffers[j]); } } break; case InverseDeallocation: { for(int j = (int)buffers.size() ;j-- ;){ a.deallocate(buffers[j]); } } break; case MixedDeallocation: { for(int j = 0, max = (int)buffers.size() ;j < max ;++j){ int pos = (j%4)*((int)buffers.size())/4; a.deallocate(buffers[pos]); buffers.erase(buffers.begin()+pos); } } break; default: break; } //Deallocate the rest of the blocks //Deallocate it in non sequential order for(int j = 0, max = (int)buffers2.size() ;j < max ;++j){ int pos = (j%4)*((int)buffers2.size())/4; a.deallocate(buffers2[pos]); buffers2.erase(buffers2.begin()+pos); } bool ok = free_memory == a.get_free_memory() && a.all_memory_deallocated() && a.check_sanity(); if(!ok) return ok; } return true;}//This test allocates multiple values until there is no more memory//and after that deallocates all in the inverse ordertemplate<class Allocator>bool test_many_deallocation(Allocator &a){ typedef typename Allocator::multiallocation_iterator multiallocation_iterator; const std::size_t ArraySize = 11; std::vector<multiallocation_iterator> buffers; std::size_t requested_sizes[ArraySize]; for(std::size_t i = 0; i < ArraySize; ++i){ requested_sizes[i] = 4*i; } std::size_t free_memory = a.get_free_memory(); { for(int i = 0; true; ++i){ multiallocation_iterator it = a.allocate_many(requested_sizes, ArraySize, 1, std::nothrow); if(!it) break; buffers.push_back(it); } for(int i = 0, max = (int)buffers.size(); i != max; ++i){ a.deallocate_many(buffers[i]); } buffers.clear(); bool ok = free_memory == a.get_free_memory() && a.all_memory_deallocated() && a.check_sanity(); if(!ok) return ok; } { for(int i = 0; true; ++i){ multiallocation_iterator it = a.allocate_many(i*4, ArraySize, std::nothrow); if(!it) break; buffers.push_back(it); } for(int i = 0, max = (int)buffers.size(); i != max; ++i){ a.deallocate_many(buffers[i]); } buffers.clear(); bool ok = free_memory == a.get_free_memory() && a.all_memory_deallocated() && a.check_sanity(); if(!ok) return ok; } return true;}//This function calls all teststemplate<class Allocator>bool test_all_allocation(Allocator &a){ std::cout << "Starting test_allocation. Class: " << typeid(a).name() << std::endl; if(!test_allocation(a)){ std::cout << "test_allocation_direct_deallocation failed. Class: " << typeid(a).name() << std::endl; return false; } std::cout << "Starting test_many_equal_allocation. Class: " << typeid(a).name() << std::endl; if(!test_many_equal_allocation(a)){ std::cout << "test_many_equal_allocation failed. Class: " << typeid(a).name() << std::endl; return false; } std::cout << "Starting test_many_different_allocation. Class: " << typeid(a).name() << std::endl; if(!test_many_different_allocation(a)){ std::cout << "test_many_different_allocation failed. Class: " << typeid(a).name() << std::endl; return false; } if(!test_many_deallocation(a)){ std::cout << "test_many_deallocation failed. Class: " << typeid(a).name() << std::endl; return false; } std::cout << "Starting test_allocation_shrink. Class: " << typeid(a).name() << std::endl; if(!test_allocation_shrink(a)){ std::cout << "test_allocation_shrink failed. Class: " << typeid(a).name() << std::endl; return false; } if(!test_allocation_shrink_and_expand(a)){ std::cout << "test_allocation_shrink_and_expand failed. Class: " << typeid(a).name() << std::endl; return false; } std::cout << "Starting test_allocation_expand. Class: " << typeid(a).name() << std::endl; if(!test_allocation_expand(a)){ std::cout << "test_allocation_expand failed. Class: " << typeid(a).name() << std::endl; return false; } std::cout << "Starting test_allocation_deallocation_expand. Class: " << typeid(a).name() << std::endl; if(!test_allocation_deallocation_expand(a)){ std::cout << "test_allocation_deallocation_expand failed. Class: " << typeid(a).name() << std::endl; return false; } std::cout << "Starting test_allocation_with_reuse. Class: " << typeid(a).name() << std::endl; if(!test_allocation_with_reuse(a)){ std::cout << "test_allocation_with_reuse failed. Class: " << typeid(a).name() << std::endl; return false; } std::cout << "Starting test_aligned_allocation. Class: " << typeid(a).name() << std::endl; if(!test_aligned_allocation(a)){ std::cout << "test_aligned_allocation failed. Class: " << typeid(a).name() << std::endl; return false; } std::cout << "Starting test_continuous_aligned_allocation. Class: " << typeid(a).name() << std::endl; if(!test_continuous_aligned_allocation(a)){ std::cout << "test_continuous_aligned_allocation failed. Class: " << typeid(a).name() << std::endl; return false; } std::cout << "Starting test_clear_free_memory. Class: " << typeid(a).name() << std::endl; if(!test_clear_free_memory(a)){ std::cout << "test_clear_free_memory failed. Class: " << typeid(a).name() << std::endl; 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;}}}} //namespace boost { namespace interprocess { namespace test {#include <boost/interprocess/detail/config_end.hpp>#endif //BOOST_INTERPROCESS_TEST_MEMORY_ALGORITHM_TEST_TEMPLATE_HEADER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -