• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://www.boost.org/libs/interprocess for documentation.
8 //
9 //////////////////////////////////////////////////////////////////////////////
10 
11 #include <algorithm>
12 #include <vector>
13 #include <list>
14 #include <iostream>
15 #include <functional>
16 #include <boost/interprocess/managed_external_buffer.hpp>
17 #include <boost/interprocess/managed_heap_memory.hpp>
18 #include <boost/interprocess/containers/list.hpp>
19 #include <boost/interprocess/detail/type_traits.hpp>
20 #include <boost/move/detail/type_traits.hpp>
21 #include <boost/interprocess/allocators/node_allocator.hpp>
22 #include "print_container.hpp"
23 
24 /******************************************************************************/
25 /*                                                                            */
26 /*  This example constructs repeats the same operations with std::list,       */
27 /*  shmem_list in user provided buffer, and shmem_list in heap memory         */
28 /*                                                                            */
29 /******************************************************************************/
30 
31 using namespace boost::interprocess;
32 
33 //We will work with wide characters for user memory objects
34 //Alias <integer> node allocator type
35 typedef node_allocator
36    <int, wmanaged_external_buffer::segment_manager> user_node_allocator_t;
37 typedef node_allocator
38    <int, wmanaged_heap_memory::segment_manager> heap_node_allocator_t;
39 
40 //Alias list types
41 typedef list<int, user_node_allocator_t>    MyUserList;
42 typedef list<int, heap_node_allocator_t>    MyHeapList;
43 typedef std::list<int>                      MyStdList;
44 
45 //Function to check if both lists are equal
CheckEqual(MyUserList * userlist,MyStdList * stdlist,MyHeapList * heaplist)46 bool CheckEqual(MyUserList *userlist, MyStdList *stdlist, MyHeapList *heaplist)
47 {
48    return std::equal(userlist->begin(), userlist->end(), stdlist->begin()) &&
49           std::equal(heaplist->begin(), heaplist->end(), stdlist->begin());
50 }
51 
main()52 int main ()
53 {
54    //Create the user memory who will store all objects
55    const int size_aligner  = sizeof(::boost::container::dtl::max_align_t);
56    const int memsize       = 65536/size_aligner*size_aligner;
57    static ::boost::container::dtl::max_align_t static_buffer[memsize/size_aligner];
58 
59    {
60       //Now test move semantics
61       managed_heap_memory original(memsize);
62       managed_heap_memory move_ctor(boost::move(original));
63       managed_heap_memory move_assign;
64       move_assign = boost::move(move_ctor);
65       original.swap(move_assign);
66    }
67    {
68       //Now test move semantics
69       managed_external_buffer original(create_only, static_buffer, memsize);
70       managed_external_buffer move_ctor(boost::move(original));
71       managed_external_buffer move_assign;
72       move_assign = boost::move(move_ctor);
73       original.swap(move_assign);
74    }
75 
76    //Named new capable user mem allocator
77    wmanaged_external_buffer user_buffer(create_only, static_buffer, memsize);
78 
79    //Named new capable heap mem allocator
80    wmanaged_heap_memory heap_buffer(memsize);
81 
82    //Test move semantics
83    {
84       wmanaged_external_buffer user_default;
85       wmanaged_external_buffer temp_external(boost::move(user_buffer));
86       user_default = boost::move(temp_external);
87       user_buffer  = boost::move(user_default);
88       wmanaged_heap_memory heap_default;
89       wmanaged_heap_memory temp_heap(boost::move(heap_buffer));
90       heap_default = boost::move(temp_heap);
91       heap_buffer  = boost::move(heap_default);
92    }
93 
94    //Initialize memory
95    user_buffer.reserve_named_objects(100);
96    heap_buffer.reserve_named_objects(100);
97 
98    //User memory allocator must be always be initialized
99    //since it has no default constructor
100    MyUserList *userlist = user_buffer.construct<MyUserList>(L"MyUserList")
101                            (user_buffer.get_segment_manager());
102 
103    MyHeapList *heaplist = heap_buffer.construct<MyHeapList>(L"MyHeapList")
104                            (heap_buffer.get_segment_manager());
105 
106    //Alias heap list
107    MyStdList *stdlist = new MyStdList;
108 
109    int i;
110    const int max = 100;
111    for(i = 0; i < max; ++i){
112       userlist->push_back(i);
113       heaplist->push_back(i);
114       stdlist->push_back(i);
115    }
116    if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
117 
118    userlist->erase(userlist->begin()++);
119    heaplist->erase(heaplist->begin()++);
120    stdlist->erase(stdlist->begin()++);
121    if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
122 
123    userlist->pop_back();
124    heaplist->pop_back();
125    stdlist->pop_back();
126    if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
127 
128    userlist->pop_front();
129    heaplist->pop_front();
130    stdlist->pop_front();
131    if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
132 
133    std::vector<int> aux_vect;
134    #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
135    aux_vect.assign(50, -1);
136    userlist->assign(aux_vect.begin(), aux_vect.end());
137    heaplist->assign(aux_vect.begin(), aux_vect.end());
138    stdlist->assign(aux_vect.begin(), aux_vect.end());
139    if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
140    #endif
141 
142    userlist->sort();
143    heaplist->sort();
144    stdlist->sort();
145    if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
146 
147    #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
148    aux_vect.assign(50, 0);
149    #endif
150    userlist->insert(userlist->begin(), aux_vect.begin(), aux_vect.end());
151    heaplist->insert(heaplist->begin(), aux_vect.begin(), aux_vect.end());
152    stdlist->insert(stdlist->begin(), aux_vect.begin(), aux_vect.end());
153 
154    userlist->unique();
155    heaplist->unique();
156    stdlist->unique();
157    if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
158 
159    userlist->sort(std::greater<int>());
160    heaplist->sort(std::greater<int>());
161    stdlist->sort(std::greater<int>());
162    if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
163 
164    userlist->resize(userlist->size()/2);
165    heaplist->resize(heaplist->size()/2);
166    stdlist->resize(stdlist->size()/2);
167    if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
168 
169    userlist->remove(*userlist->begin());
170    heaplist->remove(*heaplist->begin());
171    stdlist->remove(*stdlist->begin());
172    if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
173 
174    for(i = 0; i < max; ++i){
175       userlist->push_back(i);
176       heaplist->push_back(i);
177       stdlist->push_back(i);
178    }
179 
180    MyUserList otheruserlist(*userlist);
181    MyHeapList otherheaplist(*heaplist);
182    MyStdList otherstdlist(*stdlist);
183    userlist->splice(userlist->begin(), otheruserlist);
184    heaplist->splice(heaplist->begin(), otherheaplist);
185    stdlist->splice(stdlist->begin(), otherstdlist);
186    if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
187 
188    otheruserlist = *userlist;
189    otherheaplist = *heaplist;
190    otherstdlist = *stdlist;
191 
192    userlist->sort(std::greater<int>());
193    heaplist->sort(std::greater<int>());
194    stdlist->sort(std::greater<int>());
195    otheruserlist.sort(std::greater<int>());
196    otherheaplist.sort(std::greater<int>());
197    otherstdlist.sort(std::greater<int>());
198    userlist->merge(otheruserlist, std::greater<int>());
199    heaplist->merge(otherheaplist, std::greater<int>());
200    stdlist->merge(otherstdlist, std::greater<int>());
201    if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
202 
203    user_buffer.destroy<MyUserList>(L"MyUserList");
204    delete stdlist;
205 
206    //Fill heap buffer until is full
207    try{
208       while(1){
209          heaplist->insert(heaplist->end(), 0);
210       }
211    }
212    catch(boost::interprocess::bad_alloc &){}
213 
214    MyHeapList::size_type heap_list_size = heaplist->size();
215 
216    //Copy heap buffer to another
217    const char *insert_beg = static_cast<char*>(heap_buffer.get_address());
218    const char *insert_end = insert_beg + heap_buffer.get_size();
219    std::vector<char> grow_copy (insert_beg, insert_end);
220 
221    //Destroy old list
222    heap_buffer.destroy<MyHeapList>(L"MyHeapList");
223 
224    //Resize copy buffer
225    grow_copy.resize(memsize*2);
226 
227    //Open Interprocess machinery in the new managed external buffer
228    wmanaged_external_buffer user_buffer2(open_only, &grow_copy[0], memsize);
229 
230    //Expand old Interprocess machinery to the new size
231    user_buffer2.grow(memsize);
232 
233    //Get a pointer to the full list
234    userlist = user_buffer2.find<MyUserList>(L"MyHeapList").first;
235    if(!userlist){
236       return 1;
237    }
238 
239    //Fill user buffer until is full
240    try{
241       while(1){
242          userlist->insert(userlist->end(), 0);
243       }
244    }
245    catch(boost::interprocess::bad_alloc &){}
246 
247    MyUserList::size_type user_list_size = userlist->size();
248 
249    if(user_list_size <= heap_list_size){
250       return 1;
251    }
252 
253    user_buffer2.destroy_ptr(userlist);
254 
255    return 0;
256 }
257