709acd4dc63984a01c48616559e84825f50d1578
[platform/upstream/boost.git] / libs / interprocess / test / intersegment_ptr_test.cpp
1 //////////////////////////////////////////////////////////////////////////////
2 //
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)
6 //
7 // See http://www.boost.org/libs/interprocess for documentation.
8 //
9 //////////////////////////////////////////////////////////////////////////////
10
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
19
20
21 using namespace boost::interprocess;
22
23 bool test_types_and_convertions()
24 {
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;
29
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));
34    int dummy_int = 9;
35
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;  }
46
47    pint_t   pint(0);
48    pcint_t  pcint(0);
49    pvint_t  pvint(0);
50    pcvint_t pcvint(0);
51   
52    pint     = &dummy_int;
53    pcint    = &dummy_int;
54    pvint    = &dummy_int;
55    pcvint   = &dummy_int;
56
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;  }
62
63    if(!pint)
64       return false;
65
66    pint = 0;
67    if(pint)
68       return false;
69
70    return true;
71 }
72
73 bool test_arithmetic()
74 {
75    typedef intersegment_ptr<int> pint_t;
76    const int NumValues = 5;
77    int values[NumValues];
78   
79    //Initialize p
80    pint_t p = values;
81    if(p.get() != values)
82       return false;
83
84    //Initialize p + NumValues
85    pint_t pe = &values[NumValues];
86    if(pe == p)
87       return false;
88    if(pe.get() != &values[NumValues])
89       return false;
90
91    //ptr - ptr
92    if((pe - p) != NumValues)
93       return false;
94    //ptr - integer
95    if((pe - NumValues) != p)
96       return false;
97    //ptr + integer
98    if((p + NumValues) != pe)
99       return false;
100    //integer + ptr
101    if((NumValues + p) != pe)
102       return false;
103    //indexing
104    if(pint_t(&p[NumValues])   != pe)
105       return false;
106    if(pint_t(&pe[-NumValues]) != p)
107       return false;
108
109    //ptr -= integer
110    pint_t p0 = pe;
111    p0-= NumValues;
112    if(p != p0)
113       return false;
114    //ptr += integer
115    pint_t penew = p0;
116    penew += NumValues;
117    if(penew != pe)
118       return false;
119
120    //++ptr
121    penew = p0;
122    for(int j = 0; j != NumValues; ++j, ++penew);
123    if(penew != pe)
124       return false;
125    //--ptr
126    p0 = pe;
127    for(int j = 0; j != NumValues; ++j, --p0);
128    if(p != p0)
129       return false;
130    //ptr++
131    penew = p0;
132    for(int j = 0; j != NumValues; ++j){
133       pint_t p = penew;
134       if(p != penew++)
135          return false;
136    }
137    //ptr--
138    p0 = pe;
139    for(int j = 0; j != NumValues; ++j){
140       pint_t p = p0;
141       if(p != p0--)
142          return false;
143    }
144
145    return true;
146 }
147
148 bool test_comparison()
149 {
150    typedef intersegment_ptr<int> pint_t;
151    const int NumValues = 5;
152    int values[NumValues];
153
154    //Initialize p
155    pint_t p = values;
156    if(p.get() != values)
157       return false;
158
159    //Initialize p + NumValues
160    pint_t pe = &values[NumValues];
161    if(pe == p)
162       return false;
163    if(pe.get() != &values[NumValues])
164       return false;
165
166    //operators
167    if(p == pe)
168       return false;
169    if(p != p)
170       return false;
171    if(!(p < pe))
172       return false;
173    if(!(p <= pe))
174       return false;
175    if(!(pe > p))
176       return false;
177    if(!(pe >= p))
178       return false;
179
180    return true;
181 }
182
183 struct segment_data
184 {
185    int int0;
186    int int1;
187    intersegment_ptr<int> ptr0;
188    int int2;
189    int int3;
190 };
191
192 bool test_basic_comparisons()
193 {
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));
200
201    if(sizeof(segment_data) > mapped_region::get_page_size())
202       return false;
203
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());
208
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);
212
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);
217
218    {
219
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);
225    }
226
227    //Now do some testing...
228    {
229       //Same segment
230       seg_0_0.ptr0 = &seg_0_0.int0;
231       seg_0_1.ptr0 = &seg_0_1.int0;
232
233       if(seg_0_0.ptr0.get() != &seg_0_0.int0)
234          return false;
235       if(seg_0_1.ptr0.get() != &seg_0_1.int0)
236          return false;
237
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;
241
242       if(seg_0_0.ptr0.get() != &seg_0_0.int1)
243          return false;
244       if(seg_0_1.ptr0.get() != &seg_0_1.int1)
245          return false;
246
247       //Set to null and try again
248       seg_0_0.ptr0 = 0;
249       seg_0_1.ptr0 = 0;
250
251       seg_0_0.ptr0 = &seg_0_0.int1;
252       seg_0_1.ptr0 = &seg_0_1.int1;
253
254       if(seg_0_0.ptr0.get() != &seg_0_0.int1)
255          return false;
256       if(seg_0_1.ptr0.get() != &seg_0_1.int1)
257          return false;
258
259       //Set to null and try again
260       int stack_int;
261       seg_0_0.ptr0 = &stack_int;
262       seg_0_1.ptr0 = &stack_int;
263
264       if(seg_0_0.ptr0.get() != &stack_int)
265          return false;
266       if(seg_0_1.ptr0.get() != &stack_int)
267          return false;
268    }
269
270    {
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;
274
275       if(stack_0.get() != &seg_0_0.int2)
276          return false;
277       if(stack_1.get() != &seg_1_1.int2)
278          return false;
279
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;
283
284       if(stack_0.get() != &seg_0_0.int3)
285          return false;
286       if(stack_1.get() != &seg_1_1.int3)
287          return false;
288
289       //Now set to null and try it again
290       stack_0 = 0;
291       stack_1 = 0;
292
293       stack_0 = &seg_0_0.int3;
294       stack_1 = &seg_1_1.int3;
295
296       if(stack_0.get() != &seg_0_0.int3)
297          return false;
298       if(stack_1.get() != &seg_1_1.int3)
299          return false;
300    }
301    {
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;
305
306       if(seg_0_0.ptr0.get() != &seg_0_1.int0)
307          return false;
308       if(seg_0_1.ptr0.get() != &seg_0_0.int0)
309          return false;
310
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;
314
315       if(seg_0_0.ptr0.get() != &seg_0_1.int1)
316          return false;
317       if(seg_0_1.ptr0.get() != &seg_0_0.int1)
318          return false;
319
320       //Set to null and try it again
321       seg_0_0.ptr0 = 0;
322       seg_0_1.ptr0 = 0;
323
324       seg_0_0.ptr0 = &seg_0_1.int1;
325       seg_0_1.ptr0 = &seg_0_0.int1;
326
327       if(seg_0_0.ptr0.get() != &seg_0_1.int1)
328          return false;
329       if(seg_0_1.ptr0.get() != &seg_0_0.int1)
330          return false;
331    }
332
333    {
334       //Different groups
335       seg_0_0.ptr0 = &seg_1_0.int0;
336       seg_0_1.ptr0 = &seg_1_1.int0;
337
338       if(seg_0_0.ptr0.get() != &seg_1_0.int0)
339          return false;
340       if(seg_0_1.ptr0.get() != &seg_1_1.int0)
341          return false;
342
343       //Try it again
344       seg_0_0.ptr0 = &seg_1_0.int1;
345       seg_0_1.ptr0 = &seg_1_1.int1;
346
347       if(seg_0_0.ptr0.get() != &seg_1_0.int1)
348          return false;
349       if(seg_0_1.ptr0.get() != &seg_1_1.int1)
350          return false;
351
352       //Set null and try it again
353       seg_0_0.ptr0 = 0;
354       seg_0_1.ptr0 = 0;
355
356       seg_0_0.ptr0 = &seg_1_0.int1;
357       seg_0_1.ptr0 = &seg_1_1.int1;
358
359       if(seg_0_0.ptr0.get() != &seg_1_0.int1)
360          return false;
361       if(seg_0_1.ptr0.get() != &seg_1_1.int1)
362          return false;
363    }
364
365    {
366       //Erase mappings
367       intersegment_ptr<int>::delete_group(group_0_id);
368       intersegment_ptr<int>::delete_group(group_1_id);
369    }
370    return true;
371 }
372
373 bool test_multi_segment_shared_memory()
374 {
375    {
376       shared_memory_object::remove("kk0");
377       managed_multi_shared_memory mshm(create_only, "kk", 4096);
378    }
379   
380    shared_memory_object::remove("kk0");
381    return true;
382 }
383
384 int main()
385 {/*
386    if(!test_types_and_convertions())
387       return 1;
388    if(!test_arithmetic())
389       return 1;
390    if(!test_comparison())
391       return 1;
392    if(!test_basic_comparisons())
393       return 1;
394
395    if(!test_multi_segment_shared_memory())
396       return 1;
397 */
398    return 0;
399 }
400
401 #include <boost/interprocess/detail/config_end.hpp>