1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2007. 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)
7 // See http://www.boost.org/libs/interprocess for documentation.
9 //////////////////////////////////////////////////////////////////////////////
11 #include <boost/interprocess/detail/config_begin.hpp>
12 #include <boost/interprocess/detail/intersegment_ptr.hpp>
13 #include <boost/interprocess/detail/type_traits.hpp>
14 #include <boost/interprocess/mapped_region.hpp> //mapped_region
15 #include <boost/interprocess/anonymous_shared_memory.hpp> //anonymous_shared_memory
16 #include <boost/interprocess/detail/managed_multi_shared_memory.hpp> //managed_multi_shared_memory
17 #include <boost/static_assert.hpp> //static_assert
18 #include <cstddef> //std::size_t
21 using namespace boost::interprocess;
23 bool test_types_and_convertions()
25 typedef intersegment_ptr<int> pint_t;
26 typedef intersegment_ptr<const int> pcint_t;
27 typedef intersegment_ptr<volatile int> pvint_t;
28 typedef intersegment_ptr<const volatile int> pcvint_t;
30 BOOST_STATIC_ASSERT((ipcdetail::is_same<pint_t::value_type, int>::value));
31 BOOST_STATIC_ASSERT((ipcdetail::is_same<pcint_t::value_type, const int>::value));
32 BOOST_STATIC_ASSERT((ipcdetail::is_same<pvint_t::value_type, volatile int>::value));
33 BOOST_STATIC_ASSERT((ipcdetail::is_same<pcvint_t::value_type, const volatile int>::value));
36 { pint_t pint(&dummy_int); pcint_t pcint(pint);
37 if(pcint.get() != &dummy_int) return false; }
38 { pint_t pint(&dummy_int); pvint_t pvint(pint);
39 if(pvint.get() != &dummy_int) return false; }
40 { pint_t pint(&dummy_int); pcvint_t pcvint(pint);
41 if(pcvint.get() != &dummy_int) return false; }
42 { pcint_t pcint(&dummy_int); pcvint_t pcvint(pcint);
43 if(pcvint.get() != &dummy_int) return false; }
44 { pvint_t pvint(&dummy_int); pcvint_t pcvint(pvint);
45 if(pcvint.get() != &dummy_int) return false; }
57 { pcint = pint; if(pcint.get() != &dummy_int) return false; }
58 { pvint = pint; if(pvint.get() != &dummy_int) return false; }
59 { pcvint = pint; if(pcvint.get() != &dummy_int) return false; }
60 { pcvint = pcint; if(pcvint.get() != &dummy_int) return false; }
61 { pcvint = pvint; if(pcvint.get() != &dummy_int) return false; }
73 bool test_arithmetic()
75 typedef intersegment_ptr<int> pint_t;
76 const int NumValues = 5;
77 int values[NumValues];
84 //Initialize p + NumValues
85 pint_t pe = &values[NumValues];
88 if(pe.get() != &values[NumValues])
92 if((pe - p) != NumValues)
95 if((pe - NumValues) != p)
98 if((p + NumValues) != pe)
101 if((NumValues + p) != pe)
104 if(pint_t(&p[NumValues]) != pe)
106 if(pint_t(&pe[-NumValues]) != p)
122 for(int j = 0; j != NumValues; ++j, ++penew);
127 for(int j = 0; j != NumValues; ++j, --p0);
132 for(int j = 0; j != NumValues; ++j){
139 for(int j = 0; j != NumValues; ++j){
148 bool test_comparison()
150 typedef intersegment_ptr<int> pint_t;
151 const int NumValues = 5;
152 int values[NumValues];
156 if(p.get() != values)
159 //Initialize p + NumValues
160 pint_t pe = &values[NumValues];
163 if(pe.get() != &values[NumValues])
187 intersegment_ptr<int> ptr0;
192 bool test_basic_comparisons()
194 //Create aligned sections
195 const std::size_t PageSize = mapped_region::get_page_size();
196 mapped_region reg_0_0(anonymous_shared_memory(PageSize));
197 mapped_region reg_0_1(anonymous_shared_memory(PageSize));
198 mapped_region reg_1_0(anonymous_shared_memory(PageSize));
199 mapped_region reg_1_1(anonymous_shared_memory(PageSize));
201 if(sizeof(segment_data) > mapped_region::get_page_size())
204 segment_data &seg_0_0 = *static_cast<segment_data *>(reg_0_0.get_address());
205 segment_data &seg_0_1 = *static_cast<segment_data *>(reg_0_1.get_address());
206 segment_data &seg_1_0 = *static_cast<segment_data *>(reg_1_0.get_address());
207 segment_data &seg_1_1 = *static_cast<segment_data *>(reg_1_1.get_address());
209 //Some dummy multi_segment_services
210 multi_segment_services *services0 = static_cast<multi_segment_services *>(0);
211 multi_segment_services *services1 = reinterpret_cast<multi_segment_services *>(1);
213 const intersegment_ptr<int>::segment_group_id group_0_id =
214 intersegment_ptr<int>::new_segment_group(services0);
215 const intersegment_ptr<int>::segment_group_id group_1_id =
216 intersegment_ptr<int>::new_segment_group(services1);
220 //Now register the segments in the segment data-base
221 intersegment_ptr<int>::insert_mapping(group_0_id, &seg_0_0, PageSize);
222 intersegment_ptr<int>::insert_mapping(group_0_id, &seg_0_1, PageSize);
223 intersegment_ptr<int>::insert_mapping(group_1_id, &seg_1_0, PageSize);
224 intersegment_ptr<int>::insert_mapping(group_1_id, &seg_1_1, PageSize);
227 //Now do some testing...
230 seg_0_0.ptr0 = &seg_0_0.int0;
231 seg_0_1.ptr0 = &seg_0_1.int0;
233 if(seg_0_0.ptr0.get() != &seg_0_0.int0)
235 if(seg_0_1.ptr0.get() != &seg_0_1.int0)
238 //Try it again to make use of the already established relative addressing
239 seg_0_0.ptr0 = &seg_0_0.int1;
240 seg_0_1.ptr0 = &seg_0_1.int1;
242 if(seg_0_0.ptr0.get() != &seg_0_0.int1)
244 if(seg_0_1.ptr0.get() != &seg_0_1.int1)
247 //Set to null and try again
251 seg_0_0.ptr0 = &seg_0_0.int1;
252 seg_0_1.ptr0 = &seg_0_1.int1;
254 if(seg_0_0.ptr0.get() != &seg_0_0.int1)
256 if(seg_0_1.ptr0.get() != &seg_0_1.int1)
259 //Set to null and try again
261 seg_0_0.ptr0 = &stack_int;
262 seg_0_1.ptr0 = &stack_int;
264 if(seg_0_0.ptr0.get() != &stack_int)
266 if(seg_0_1.ptr0.get() != &stack_int)
271 //Now use stack variables
272 intersegment_ptr<int> stack_0 = &seg_0_0.int2;
273 intersegment_ptr<int> stack_1 = &seg_1_1.int2;
275 if(stack_0.get() != &seg_0_0.int2)
277 if(stack_1.get() != &seg_1_1.int2)
280 //Now reuse stack variables knowing that there are on stack
281 stack_0 = &seg_0_0.int3;
282 stack_1 = &seg_1_1.int3;
284 if(stack_0.get() != &seg_0_0.int3)
286 if(stack_1.get() != &seg_1_1.int3)
289 //Now set to null and try it again
293 stack_0 = &seg_0_0.int3;
294 stack_1 = &seg_1_1.int3;
296 if(stack_0.get() != &seg_0_0.int3)
298 if(stack_1.get() != &seg_1_1.int3)
302 //Different segments in the same group
303 seg_0_0.ptr0 = &seg_0_1.int0;
304 seg_0_1.ptr0 = &seg_0_0.int0;
306 if(seg_0_0.ptr0.get() != &seg_0_1.int0)
308 if(seg_0_1.ptr0.get() != &seg_0_0.int0)
311 //Try it again to make use of the already established segmented addressing
312 seg_0_0.ptr0 = &seg_0_1.int1;
313 seg_0_1.ptr0 = &seg_0_0.int1;
315 if(seg_0_0.ptr0.get() != &seg_0_1.int1)
317 if(seg_0_1.ptr0.get() != &seg_0_0.int1)
320 //Set to null and try it again
324 seg_0_0.ptr0 = &seg_0_1.int1;
325 seg_0_1.ptr0 = &seg_0_0.int1;
327 if(seg_0_0.ptr0.get() != &seg_0_1.int1)
329 if(seg_0_1.ptr0.get() != &seg_0_0.int1)
335 seg_0_0.ptr0 = &seg_1_0.int0;
336 seg_0_1.ptr0 = &seg_1_1.int0;
338 if(seg_0_0.ptr0.get() != &seg_1_0.int0)
340 if(seg_0_1.ptr0.get() != &seg_1_1.int0)
344 seg_0_0.ptr0 = &seg_1_0.int1;
345 seg_0_1.ptr0 = &seg_1_1.int1;
347 if(seg_0_0.ptr0.get() != &seg_1_0.int1)
349 if(seg_0_1.ptr0.get() != &seg_1_1.int1)
352 //Set null and try it again
356 seg_0_0.ptr0 = &seg_1_0.int1;
357 seg_0_1.ptr0 = &seg_1_1.int1;
359 if(seg_0_0.ptr0.get() != &seg_1_0.int1)
361 if(seg_0_1.ptr0.get() != &seg_1_1.int1)
367 intersegment_ptr<int>::delete_group(group_0_id);
368 intersegment_ptr<int>::delete_group(group_1_id);
373 bool test_multi_segment_shared_memory()
376 shared_memory_object::remove("kk0");
377 managed_multi_shared_memory mshm(create_only, "kk", 4096);
380 shared_memory_object::remove("kk0");
386 if(!test_types_and_convertions())
388 if(!test_arithmetic())
390 if(!test_comparison())
392 if(!test_basic_comparisons())
395 if(!test_multi_segment_shared_memory())
401 #include <boost/interprocess/detail/config_end.hpp>