123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495 |
- //////////////////////////////////////////////////////////////////////////////
- //
- // (C) Copyright Ion Gaztanaga 2006-2012. 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.
- //
- //////////////////////////////////////////////////////////////////////////////
- #ifndef BOOST_INTERPROCESS_NAMED_ALLOCATION_TEST_TEMPLATE_HEADER
- #define BOOST_INTERPROCESS_NAMED_ALLOCATION_TEST_TEMPLATE_HEADER
- #include <boost/interprocess/detail/config_begin.hpp>
- // interprocess
- #include <boost/interprocess/managed_shared_memory.hpp>
- #include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
- #include <boost/interprocess/streams/bufferstream.hpp>
- #include <boost/interprocess/sync/mutex_family.hpp>
- // container
- #include <boost/container/detail/iterator.hpp>
- #include <boost/container/detail/minimal_char_traits_header.hpp> //char_traits
- // std
- #include <cstdio>
- #include <iostream>
- #include <new>
- #include <set>
- #include <vector>
- // local
- #include "get_process_id_name.hpp"
- namespace boost { namespace interprocess { namespace test {
- namespace {
- const wchar_t *get_prefix(wchar_t)
- { return L"prefix_name_"; }
- const char *get_prefix(char)
- { return "prefix_name_"; }
- }
- //This test allocates until there is no more memory
- //and after that deallocates all in the same order
- template<class ManagedMemory>
- bool test_names_and_types(ManagedMemory &m)
- {
- typedef typename ManagedMemory::char_type char_type;
- typedef std::char_traits<char_type> char_traits_type;
- std::vector<char*> buffers;
- const int BufferLen = 100;
- char_type name[BufferLen];
- basic_bufferstream<char_type> formatter(name, BufferLen);
- for(int i = 0; true; ++i){
- formatter.seekp(0);
- formatter << get_prefix(char_type()) << i << std::ends;
- char *ptr = m.template construct<char>(name, std::nothrow)(i);
- if(!ptr)
- break;
- std::size_t namelen = char_traits_type::length(m.get_instance_name(ptr));
- if(namelen != char_traits_type::length(name)){
- return 1;
- }
- if(char_traits_type::compare(m.get_instance_name(ptr), name, namelen) != 0){
- return 1;
- }
- if(m.template find<char>(name).first == 0)
- return false;
- if(m.get_instance_type(ptr) != named_type)
- return false;
- buffers.push_back(ptr);
- }
- if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
- return false;
- for(int j = 0, max = (int)buffers.size()
- ;j < max
- ;++j){
- m.destroy_ptr(buffers[j]);
- }
- if(m.get_num_named_objects() != 0 || !m.check_sanity())
- return false;
- m.shrink_to_fit_indexes();
- if(!m.all_memory_deallocated())
- return false;
- return true;
- }
- //This test allocates until there is no more memory
- //and after that deallocates all in the same order
- template<class ManagedMemory>
- bool test_named_iterators(ManagedMemory &m)
- {
- typedef typename ManagedMemory::char_type char_type;
- std::vector<char*> buffers;
- const int BufferLen = 100;
- char_type name[BufferLen];
- typedef std::basic_string<char_type> string_type;
- std::set<string_type> names;
- basic_bufferstream<char_type> formatter(name, BufferLen);
- string_type aux_str;
- for(int i = 0; true; ++i){
- formatter.seekp(0);
- formatter << get_prefix(char_type()) << i << std::ends;
- char *ptr = m.template construct<char>(name, std::nothrow)(i);
- if(!ptr)
- break;
- aux_str = name;
- names.insert(aux_str);
- buffers.push_back(ptr);
- }
- if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
- return false;
- typedef typename ManagedMemory::const_named_iterator const_named_iterator;
- const_named_iterator named_beg = m.named_begin();
- const_named_iterator named_end = m.named_end();
- if((std::size_t)boost::container::iterator_distance(named_beg, named_end) != (std::size_t)buffers.size()){
- return 1;
- }
- for(; named_beg != named_end; ++named_beg){
- const char_type *name_str = named_beg->name();
- aux_str = name_str;
- if(names.find(aux_str) == names.end()){
- return 1;
- }
- if(aux_str.size() != named_beg->name_length()){
- return 1;
- }
- const void *found_value = m.template find<char>(name_str).first;
- if(found_value == 0)
- return false;
- if(found_value != named_beg->value())
- return false;
- }
- for(int j = 0, max = (int)buffers.size()
- ;j < max
- ;++j){
- m.destroy_ptr(buffers[j]);
- }
- if(m.get_num_named_objects() != 0 || !m.check_sanity())
- return false;
- m.shrink_to_fit_indexes();
- if(!m.all_memory_deallocated())
- return false;
- return true;
- }
- //This test allocates until there is no more memory
- //and after that deallocates all in the same order
- template<class ManagedMemory>
- bool test_shrink_to_fit(ManagedMemory &m)
- {
- typedef typename ManagedMemory::char_type char_type;
- std::vector<char*> buffers;
- const int BufferLen = 100;
- char_type name[BufferLen];
- basic_bufferstream<char_type> formatter(name, BufferLen);
- std::size_t free_memory_before = m.get_free_memory();
- for(int i = 0; true; ++i){
- formatter.seekp(0);
- formatter << get_prefix(char_type()) << i << std::ends;
- char *ptr = m.template construct<char>(name, std::nothrow)(i);
- if(!ptr)
- break;
- buffers.push_back(ptr);
- }
- for(int j = 0, max = (int)buffers.size()
- ;j < max
- ;++j){
- m.destroy_ptr(buffers[j]);
- }
- std::size_t free_memory_after = m.get_free_memory();
- if(free_memory_before != free_memory_after){
- m.shrink_to_fit_indexes();
- if(free_memory_before != free_memory_after)
- return false;
- }
- return true;
- }
- //This test allocates until there is no more memory
- //and after that deallocates all in the same order
- template<class ManagedMemory>
- bool test_direct_named_allocation_destruction(ManagedMemory &m)
- {
- typedef typename ManagedMemory::char_type char_type;
- std::vector<char*> buffers;
- const int BufferLen = 100;
- char_type name[BufferLen];
- basic_bufferstream<char_type> formatter(name, BufferLen);
- for(int i = 0; true; ++i){
- formatter.seekp(0);
- formatter << get_prefix(char_type()) << i << std::ends;
- char *ptr = m.template construct<char>(name, std::nothrow)(i);
- if(!ptr)
- break;
- if(m.template find<char>(name).first == 0)
- return false;
- buffers.push_back(ptr);
- }
- if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
- return false;
- for(int j = 0, max = (int)buffers.size()
- ;j < max
- ;++j){
- m.destroy_ptr(buffers[j]);
- }
- if(m.get_num_named_objects() != 0 || !m.check_sanity())
- return false;
- m.shrink_to_fit_indexes();
- if(!m.all_memory_deallocated())
- return false;
- return true;
- }
- //This test allocates until there is no more memory
- //and after that deallocates all in the inverse order
- template<class ManagedMemory>
- bool test_named_allocation_inverse_destruction(ManagedMemory &m)
- {
- typedef typename ManagedMemory::char_type char_type;
- std::vector<char*> buffers;
- const int BufferLen = 100;
- char_type name[BufferLen];
- basic_bufferstream<char_type> formatter(name, BufferLen);
- for(int i = 0; true; ++i){
- formatter.seekp(0);
- formatter << get_prefix(char_type()) << i << std::ends;
- char *ptr = m.template construct<char>(name, std::nothrow)(i);
- if(!ptr)
- break;
- buffers.push_back(ptr);
- }
- if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
- return false;
- for(int j = (int)buffers.size()
- ;j--
- ;){
- m.destroy_ptr(buffers[j]);
- }
- if(m.get_num_named_objects() != 0 || !m.check_sanity())
- return false;
- m.shrink_to_fit_indexes();
- if(!m.all_memory_deallocated())
- return false;
- return true;
- }
- //This test allocates until there is no more memory
- //and after that deallocates all following a pattern
- template<class ManagedMemory>
- bool test_named_allocation_mixed_destruction(ManagedMemory &m)
- {
- typedef typename ManagedMemory::char_type char_type;
- std::vector<char*> buffers;
- const int BufferLen = 100;
- char_type name[BufferLen];
- basic_bufferstream<char_type> formatter(name, BufferLen);
- for(int i = 0; true; ++i){
- formatter.seekp(0);
- formatter << get_prefix(char_type()) << i << std::ends;
- char *ptr = m.template construct<char>(name, std::nothrow)(i);
- if(!ptr)
- break;
- buffers.push_back(ptr);
- }
- if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
- return false;
- for(int j = 0, max = (int)buffers.size()
- ;j < max
- ;++j){
- int pos = (j%4)*((int)buffers.size())/4;
- m.destroy_ptr(buffers[pos]);
- buffers.erase(buffers.begin()+pos);
- }
- if(m.get_num_named_objects() != 0 || !m.check_sanity())
- return false;
- m.shrink_to_fit_indexes();
- if(!m.all_memory_deallocated())
- return false;
- return true;
- }
- //This test allocates until there is no more memory
- //and after that deallocates all in the same order
- template<class ManagedMemory>
- bool test_inverse_named_allocation_destruction(ManagedMemory &m)
- {
- typedef typename ManagedMemory::char_type char_type;
- std::vector<char*> buffers;
- const int BufferLen = 100;
- char_type name[BufferLen];
- basic_bufferstream<char_type> formatter(name, BufferLen);
- for(unsigned int i = 0; true; ++i){
- formatter.seekp(0);
- formatter << get_prefix(char_type()) << i << std::ends;
- char *ptr = m.template construct<char>(name, std::nothrow)(i);
- if(!ptr)
- break;
- buffers.push_back(ptr);
- }
- if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
- return false;
- for(unsigned int j = 0, max = (unsigned int)buffers.size()
- ;j < max
- ;++j){
- m.destroy_ptr(buffers[j]);
- }
- if(m.get_num_named_objects() != 0 || !m.check_sanity())
- return false;
- m.shrink_to_fit_indexes();
- if(!m.all_memory_deallocated())
- return false;
- return true;
- }
- ///This function calls all tests
- template<class ManagedMemory>
- bool test_all_named_allocation(ManagedMemory &m)
- {
- std::cout << "Starting test_names_and_types. Class: "
- << typeid(m).name() << std::endl;
- if(!test_names_and_types(m)){
- std::cout << "test_names_and_types failed. Class: "
- << typeid(m).name() << std::endl;
- return false;
- }
- std::cout << "Starting test_direct_named_allocation_destruction. Class: "
- << typeid(m).name() << std::endl;
- if(!test_direct_named_allocation_destruction(m)){
- std::cout << "test_direct_named_allocation_destruction failed. Class: "
- << typeid(m).name() << std::endl;
- return false;
- }
- std::cout << "Starting test_named_allocation_inverse_destruction. Class: "
- << typeid(m).name() << std::endl;
- if(!test_named_allocation_inverse_destruction(m)){
- std::cout << "test_named_allocation_inverse_destruction failed. Class: "
- << typeid(m).name() << std::endl;
- return false;
- }
- std::cout << "Starting test_named_allocation_mixed_destruction. Class: "
- << typeid(m).name() << std::endl;
- if(!test_named_allocation_mixed_destruction(m)){
- std::cout << "test_named_allocation_mixed_destruction failed. Class: "
- << typeid(m).name() << std::endl;
- return false;
- }
- std::cout << "Starting test_inverse_named_allocation_destruction. Class: "
- << typeid(m).name() << std::endl;
- if(!test_inverse_named_allocation_destruction(m)){
- std::cout << "test_inverse_named_allocation_destruction failed. Class: "
- << typeid(m).name() << std::endl;
- return false;
- }
- if(!test_named_iterators(m)){
- std::cout << "test_named_iterators failed. Class: "
- << typeid(m).name() << std::endl;
- return false;
- }
- return true;
- }
- //This function calls all tests
- template<template <class IndexConfig> class Index>
- bool test_named_allocation()
- {
- using namespace boost::interprocess;
- const int memsize = 163840;
- const char *const shMemName = test::get_process_id_name();
- try
- {
- //A shared memory with rbtree best fit algorithm
- typedef basic_managed_shared_memory
- <char
- ,rbtree_best_fit<mutex_family>
- ,Index
- > my_managed_shared_memory;
- //Create shared memory
- shared_memory_object::remove(shMemName);
- my_managed_shared_memory segment(create_only, shMemName, memsize);
- //Now take the segment manager and launch memory test
- if(!test::test_all_named_allocation(*segment.get_segment_manager())){
- return false;
- }
- }
- catch(...){
- shared_memory_object::remove(shMemName);
- throw;
- }
- shared_memory_object::remove(shMemName);
- //Now test it with wchar_t
- try
- {
- //A shared memory with simple sequential fit algorithm
- typedef basic_managed_shared_memory
- <wchar_t
- ,rbtree_best_fit<mutex_family>
- ,Index
- > my_managed_shared_memory;
- //Create shared memory
- shared_memory_object::remove(shMemName);
- my_managed_shared_memory segment(create_only, shMemName, memsize);
- //Now take the segment manager and launch memory test
- if(!test::test_all_named_allocation(*segment.get_segment_manager())){
- return false;
- }
- }
- catch(...){
- shared_memory_object::remove(shMemName);
- throw;
- }
- shared_memory_object::remove(shMemName);
- return true;
- }
- }}} //namespace boost { namespace interprocess { namespace test {
- #include <boost/interprocess/detail/config_end.hpp>
- #endif //BOOST_INTERPROCESS_NAMED_ALLOCATION_TEST_TEMPLATE_HEADER
|