interprocess/test/user_buffer_test.cpp
2017-11-07 00:52:46 +01:00

260 lines
8.6 KiB
C++

//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-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.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/interprocess/detail/config_begin.hpp>
#include <algorithm>
#include <vector>
#include <list>
#include <iostream>
#include <functional>
#include <boost/interprocess/managed_external_buffer.hpp>
#include <boost/interprocess/managed_heap_memory.hpp>
#include <boost/interprocess/containers/list.hpp>
#include <boost/interprocess/detail/type_traits.hpp>
#include <boost/move/detail/type_traits.hpp>
#include <boost/interprocess/allocators/node_allocator.hpp>
#include "print_container.hpp"
/******************************************************************************/
/* */
/* This example constructs repeats the same operations with std::list, */
/* shmem_list in user provided buffer, and shmem_list in heap memory */
/* */
/******************************************************************************/
using namespace boost::interprocess;
//We will work with wide characters for user memory objects
//Alias <integer> node allocator type
typedef node_allocator
<int, wmanaged_external_buffer::segment_manager> user_node_allocator_t;
typedef node_allocator
<int, wmanaged_heap_memory::segment_manager> heap_node_allocator_t;
//Alias list types
typedef list<int, user_node_allocator_t> MyUserList;
typedef list<int, heap_node_allocator_t> MyHeapList;
typedef std::list<int> MyStdList;
//Function to check if both lists are equal
bool CheckEqual(MyUserList *userlist, MyStdList *stdlist, MyHeapList *heaplist)
{
return std::equal(userlist->begin(), userlist->end(), stdlist->begin()) &&
std::equal(heaplist->begin(), heaplist->end(), stdlist->begin());
}
int main ()
{
//Create the user memory who will store all objects
const int size_aligner = sizeof(::boost::container::dtl::max_align_t);
const int memsize = 65536/size_aligner*size_aligner;
static ::boost::container::dtl::max_align_t static_buffer[memsize/size_aligner];
{
//Now test move semantics
managed_heap_memory original(memsize);
managed_heap_memory move_ctor(boost::move(original));
managed_heap_memory move_assign;
move_assign = boost::move(move_ctor);
original.swap(move_assign);
}
{
//Now test move semantics
managed_external_buffer original(create_only, static_buffer, memsize);
managed_external_buffer move_ctor(boost::move(original));
managed_external_buffer move_assign;
move_assign = boost::move(move_ctor);
original.swap(move_assign);
}
//Named new capable user mem allocator
wmanaged_external_buffer user_buffer(create_only, static_buffer, memsize);
//Named new capable heap mem allocator
wmanaged_heap_memory heap_buffer(memsize);
//Test move semantics
{
wmanaged_external_buffer user_default;
wmanaged_external_buffer temp_external(boost::move(user_buffer));
user_default = boost::move(temp_external);
user_buffer = boost::move(user_default);
wmanaged_heap_memory heap_default;
wmanaged_heap_memory temp_heap(boost::move(heap_buffer));
heap_default = boost::move(temp_heap);
heap_buffer = boost::move(heap_default);
}
//Initialize memory
user_buffer.reserve_named_objects(100);
heap_buffer.reserve_named_objects(100);
//User memory allocator must be always be initialized
//since it has no default constructor
MyUserList *userlist = user_buffer.construct<MyUserList>(L"MyUserList")
(user_buffer.get_segment_manager());
MyHeapList *heaplist = heap_buffer.construct<MyHeapList>(L"MyHeapList")
(heap_buffer.get_segment_manager());
//Alias heap list
MyStdList *stdlist = new MyStdList;
int i;
const int max = 100;
for(i = 0; i < max; ++i){
userlist->push_back(i);
heaplist->push_back(i);
stdlist->push_back(i);
}
if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
userlist->erase(userlist->begin()++);
heaplist->erase(heaplist->begin()++);
stdlist->erase(stdlist->begin()++);
if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
userlist->pop_back();
heaplist->pop_back();
stdlist->pop_back();
if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
userlist->pop_front();
heaplist->pop_front();
stdlist->pop_front();
if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
std::vector<int> aux_vect;
#if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
aux_vect.assign(50, -1);
userlist->assign(aux_vect.begin(), aux_vect.end());
heaplist->assign(aux_vect.begin(), aux_vect.end());
stdlist->assign(aux_vect.begin(), aux_vect.end());
if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
#endif
userlist->sort();
heaplist->sort();
stdlist->sort();
if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
#if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
aux_vect.assign(50, 0);
#endif
userlist->insert(userlist->begin(), aux_vect.begin(), aux_vect.end());
heaplist->insert(heaplist->begin(), aux_vect.begin(), aux_vect.end());
stdlist->insert(stdlist->begin(), aux_vect.begin(), aux_vect.end());
userlist->unique();
heaplist->unique();
stdlist->unique();
if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
userlist->sort(std::greater<int>());
heaplist->sort(std::greater<int>());
stdlist->sort(std::greater<int>());
if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
userlist->resize(userlist->size()/2);
heaplist->resize(heaplist->size()/2);
stdlist->resize(stdlist->size()/2);
if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
userlist->remove(*userlist->begin());
heaplist->remove(*heaplist->begin());
stdlist->remove(*stdlist->begin());
if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
for(i = 0; i < max; ++i){
userlist->push_back(i);
heaplist->push_back(i);
stdlist->push_back(i);
}
MyUserList otheruserlist(*userlist);
MyHeapList otherheaplist(*heaplist);
MyStdList otherstdlist(*stdlist);
userlist->splice(userlist->begin(), otheruserlist);
heaplist->splice(heaplist->begin(), otherheaplist);
stdlist->splice(stdlist->begin(), otherstdlist);
if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
otheruserlist = *userlist;
otherheaplist = *heaplist;
otherstdlist = *stdlist;
userlist->sort(std::greater<int>());
heaplist->sort(std::greater<int>());
stdlist->sort(std::greater<int>());
otheruserlist.sort(std::greater<int>());
otherheaplist.sort(std::greater<int>());
otherstdlist.sort(std::greater<int>());
userlist->merge(otheruserlist, std::greater<int>());
heaplist->merge(otherheaplist, std::greater<int>());
stdlist->merge(otherstdlist, std::greater<int>());
if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
user_buffer.destroy<MyUserList>(L"MyUserList");
delete stdlist;
//Fill heap buffer until is full
try{
while(1){
heaplist->insert(heaplist->end(), 0);
}
}
catch(boost::interprocess::bad_alloc &){}
MyHeapList::size_type heap_list_size = heaplist->size();
//Copy heap buffer to another
const char *insert_beg = static_cast<char*>(heap_buffer.get_address());
const char *insert_end = insert_beg + heap_buffer.get_size();
std::vector<char> grow_copy (insert_beg, insert_end);
//Destroy old list
heap_buffer.destroy<MyHeapList>(L"MyHeapList");
//Resize copy buffer
grow_copy.resize(memsize*2);
//Open Interprocess machinery in the new managed external buffer
wmanaged_external_buffer user_buffer2(open_only, &grow_copy[0], memsize);
//Expand old Interprocess machinery to the new size
user_buffer2.grow(memsize);
//Get a pointer to the full list
userlist = user_buffer2.find<MyUserList>(L"MyHeapList").first;
if(!userlist){
return 1;
}
//Fill user buffer until is full
try{
while(1){
userlist->insert(userlist->end(), 0);
}
}
catch(boost::interprocess::bad_alloc &){}
MyUserList::size_type user_list_size = userlist->size();
if(user_list_size <= heap_list_size){
return 1;
}
user_buffer2.destroy_ptr(userlist);
return 0;
}
#include <boost/interprocess/detail/config_end.hpp>