]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/interprocess/test/segment_manager_test.cpp
1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2004-2019. 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/indexes/flat_map_index.hpp>
12 #include <boost/interprocess/indexes/map_index.hpp>
13 #include <boost/interprocess/indexes/null_index.hpp>
14 #include <boost/interprocess/indexes/unordered_map_index.hpp>
15 #include <boost/interprocess/indexes/iset_index.hpp>
16 #include <boost/interprocess/indexes/iunordered_set_index.hpp>
18 #include <boost/interprocess/mem_algo/simple_seq_fit.hpp>
19 #include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
20 #include <boost/interprocess/mapped_region.hpp>
21 #include <boost/interprocess/segment_manager.hpp>
22 #include <boost/interprocess/shared_memory_object.hpp>
23 #include <boost/interprocess/sync/mutex_family.hpp>
24 #include <boost/interprocess/exceptions.hpp>
25 #include "get_process_id_name.hpp"
30 using namespace boost::interprocess
;
32 template <class SegmentManager
>
33 struct atomic_func_test
38 atomic_func_test(SegmentManager
&sm
)
44 object
= rsm
.template find
<int>("atomic_func_find_object").first
;
47 atomic_func_test
operator=(const atomic_func_test
&);
48 atomic_func_test(const atomic_func_test
&);
51 template <class SegmentManager
>
52 bool test_segment_manager()
54 typedef typename
SegmentManager::size_type size_type
;
55 const unsigned int ShmSizeSize
= 1024*64u;
56 std::string
shmname(test::get_process_id_name());
58 shared_memory_object::remove(shmname
.c_str());
59 shared_memory_object
sh_mem( create_only
, shmname
.c_str(), read_write
);
60 sh_mem
.truncate( ShmSizeSize
);
61 mapped_region
mapping( sh_mem
, read_write
);
63 SegmentManager
* seg_mgr
= new( mapping
.get_address() ) SegmentManager( ShmSizeSize
);
64 std::size_t free_mem_before
= seg_mgr
->get_free_memory();
65 std::size_t size_before
= seg_mgr
->get_size();
67 if(size_before
!= ShmSizeSize
)
69 if(!seg_mgr
->all_memory_deallocated())
71 if(seg_mgr
->get_min_size() >= ShmSizeSize
)
74 {//test get_free_memory() / allocate()/deallocate()
75 const size_type Size
= ShmSizeSize
/2;
76 void *mem
= seg_mgr
->allocate(Size
+1);
77 const size_type free_mem
= seg_mgr
->get_free_memory();
80 if(seg_mgr
->all_memory_deallocated())
82 const size_type Size2
= free_mem
/2;
83 void *mem2
= seg_mgr
->allocate(size_type(Size2
+1), std::nothrow
);
84 if(seg_mgr
->get_free_memory() >= Size2
)
86 if(seg_mgr
->size(mem
) < (Size
+1))
88 if(seg_mgr
->size(mem2
) < (Size2
+1))
90 seg_mgr
->deallocate(mem
);
91 seg_mgr
->deallocate(mem2
);
92 if(!seg_mgr
->all_memory_deallocated())
94 if(seg_mgr
->get_free_memory() != free_mem_before
)
96 BOOST_TRY
{ seg_mgr
->allocate(ShmSizeSize
*2); }BOOST_CATCH(interprocess_exception
&){} BOOST_CATCH_END
97 if(seg_mgr
->get_free_memory() != free_mem_before
)
99 if(seg_mgr
->allocate(ShmSizeSize
*2, std::nothrow
))
101 if(seg_mgr
->get_free_memory() != free_mem_before
)
104 {//test allocate_aligned
105 const std::size_t Alignment
= 128u;
106 void *mem
= seg_mgr
->allocate_aligned(ShmSizeSize
/4, Alignment
);
107 if(seg_mgr
->all_memory_deallocated())
109 std::size_t offset
= static_cast<std::size_t>
110 (static_cast<const char *>(mem
) - static_cast<const char *>(mapping
.get_address()));
111 if(offset
& (Alignment
-1))
113 void *mem2
= seg_mgr
->allocate_aligned(ShmSizeSize
/4, Alignment
, std::nothrow
);
114 std::size_t offset2
= static_cast<std::size_t>
115 (static_cast<const char *>(mem2
) - static_cast<const char *>(mapping
.get_address()));
116 if(offset2
& (Alignment
-1))
118 seg_mgr
->deallocate(mem
);
119 seg_mgr
->deallocate(mem2
);
120 if(!seg_mgr
->all_memory_deallocated())
122 if(seg_mgr
->get_free_memory() != free_mem_before
)
124 BOOST_TRY
{ seg_mgr
->allocate_aligned(ShmSizeSize
*2, Alignment
); }BOOST_CATCH(interprocess_exception
&){} BOOST_CATCH_END
125 if(seg_mgr
->get_free_memory() != free_mem_before
)
127 if(seg_mgr
->allocate_aligned(ShmSizeSize
*2, Alignment
, std::nothrow
))
129 if(seg_mgr
->get_free_memory() != free_mem_before
)
132 {//test shrink_to_fit
134 seg_mgr
->shrink_to_fit();
135 if(!seg_mgr
->all_memory_deallocated())
137 std::size_t empty_shrunk_size
= seg_mgr
->get_size();
138 std::size_t empty_shrunk_free_mem
= seg_mgr
->get_free_memory();
139 if(empty_shrunk_size
>= size_before
)
141 if(empty_shrunk_free_mem
>= size_before
)
143 seg_mgr
->grow(size_type(size_before
- empty_shrunk_size
));
144 if(seg_mgr
->get_size() != size_before
)
146 if(seg_mgr
->get_free_memory() != free_mem_before
)
148 if(!seg_mgr
->all_memory_deallocated())
151 {//test zero_free_memory
152 const size_type
Size(ShmSizeSize
/2+1), Size2(ShmSizeSize
/8);
153 void *mem
= seg_mgr
->allocate(Size
);
154 void *mem2
= seg_mgr
->allocate(Size2
);
155 //Mark memory to non-zero
156 std::memset(mem
, 0xFF, Size
);
157 std::memset(mem2
, 0xFF, Size2
);
158 //Deallocate and check still non-zero
159 seg_mgr
->deallocate(mem
);
160 seg_mgr
->deallocate(mem2
);
161 { //Use byte per byte comparison as "static unsigned char zerobuf[Size]"
162 //seems to be problematic in some compilers
163 unsigned char *const mem_uch_ptr
= static_cast<unsigned char *>(mem
);
164 unsigned char *const mem2_uch_ptr
= static_cast<unsigned char *>(mem2
);
165 size_type zeroes
= 0;
166 for(size_type i
= 0; i
!= Size
; ++i
){
174 for(size_type i
= 0; i
!= Size2
; ++i
){
181 //zero_free_memory and check it's zeroed
182 seg_mgr
->zero_free_memory();
183 //TODO: some parts are not zeroed because they are used
184 //as internal metadata, find a way to test this
185 //if(std::memcmp(mem, zerobuf, Size))
187 //if(std::memcmp(mem2, zerobuf, Size2))
189 if(seg_mgr
->get_free_memory() != free_mem_before
)
191 if(!seg_mgr
->all_memory_deallocated())
195 {//test anonymous object
196 int *int_object
= seg_mgr
->template construct
<int>(anonymous_instance
)();
197 if(1 != seg_mgr
->get_instance_length(int_object
))
199 if(anonymous_type
!= seg_mgr
->get_instance_type(int_object
))
201 if(seg_mgr
->get_instance_name(int_object
))
203 seg_mgr
->destroy_ptr(int_object
);
204 int const int_array_values
[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
205 int *int_array
= seg_mgr
->template construct_it
<int>(anonymous_instance
, std::nothrow
)[10](&int_array_values
[0]);
206 if(10 != seg_mgr
->get_instance_length(int_object
))
208 if(anonymous_type
!= seg_mgr
->get_instance_type(int_array
))
210 if(seg_mgr
->get_instance_name(int_array
))
212 seg_mgr
->destroy_ptr(int_array
);
213 BOOST_TRY
{ seg_mgr
->template construct
<int>(anonymous_instance
)[ShmSizeSize
](); }BOOST_CATCH(interprocess_exception
&){} BOOST_CATCH_END
214 if(seg_mgr
->template construct
<int>(anonymous_instance
, std::nothrow
)[ShmSizeSize
]())
215 BOOST_TRY
{ seg_mgr
->template construct_it
<long int>(anonymous_instance
)[ShmSizeSize
](&int_array_values
[0]); }BOOST_CATCH(interprocess_exception
&){} BOOST_CATCH_END
216 if(seg_mgr
->template construct_it
<int>(anonymous_instance
, std::nothrow
)[ShmSizeSize
](&int_array_values
[0]))
218 if(seg_mgr
->get_free_memory() != free_mem_before
)
220 if(!seg_mgr
->all_memory_deallocated())
225 const char *const object1_name
= "object1";
226 const char *const object2_name
= "object2";
227 int const int_array_values
[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
229 for(std::size_t i
= 0; i
!= 1/*4*/; ++i
){
230 if(seg_mgr
->template find
<unsigned int>(object1_name
).first
)
232 //Single element construction
233 unsigned int *uint_object
= 0;
236 uint_object
= seg_mgr
->template construct
<unsigned int>(object1_name
)();
239 uint_object
= seg_mgr
->template construct
<unsigned int>(object1_name
, std::nothrow
)();
242 uint_object
= seg_mgr
->template find_or_construct
<unsigned int>(object1_name
)();
245 uint_object
= seg_mgr
->template find_or_construct
<unsigned int>(object1_name
, std::nothrow
)();
248 std::pair
<unsigned int*, std::size_t> find_ret
= seg_mgr
->template find
<unsigned int>(object1_name
);
249 if(uint_object
!= find_ret
.first
)
251 if(1 != find_ret
.second
)
253 if(1 != seg_mgr
->get_instance_length(uint_object
))
255 if(named_type
!= seg_mgr
->get_instance_type(uint_object
))
257 if(std::strcmp(object1_name
, seg_mgr
->get_instance_name(uint_object
)))
260 if(seg_mgr
->template find
<int>(object2_name
).first
)
265 int_array
= seg_mgr
->template construct_it
<int>(object2_name
)[10](&int_array_values
[0]);
268 int_array
= seg_mgr
->template construct_it
<int>(object2_name
, std::nothrow
)[10](&int_array_values
[0]);
271 int_array
= seg_mgr
->template find_or_construct_it
<int>(object2_name
)[10](&int_array_values
[0]);
274 int_array
= seg_mgr
->template find_or_construct_it
<int>(object2_name
, std::nothrow
)[10](&int_array_values
[0]);
277 std::pair
<int*, std::size_t> find_ret2
= seg_mgr
->template find
<int>(object2_name
);
278 if(int_array
!= find_ret2
.first
)
280 if(10 != find_ret2
.second
)
282 if(10 != seg_mgr
->get_instance_length(int_array
))
284 if(named_type
!= seg_mgr
->get_instance_type(int_array
))
286 if(std::strcmp(object2_name
, seg_mgr
->get_instance_name(int_array
)))
288 if(seg_mgr
->get_num_named_objects() != 2)
290 typename
SegmentManager::const_named_iterator
nb(seg_mgr
->named_begin());
291 typename
SegmentManager::const_named_iterator
ne(seg_mgr
->named_end());
292 for(std::size_t j
= 0, imax
= seg_mgr
->get_num_named_objects(); j
!= imax
; ++j
){ ++nb
; }
295 seg_mgr
->destroy_ptr(uint_object
);
296 seg_mgr
->template destroy
<int>(object2_name
);
298 BOOST_TRY
{ seg_mgr
->template construct
<unsigned int>(object1_name
)[ShmSizeSize
](); }BOOST_CATCH(interprocess_exception
&){} BOOST_CATCH_END
299 if(seg_mgr
->template construct
<int>(object2_name
, std::nothrow
)[ShmSizeSize
]())
300 BOOST_TRY
{ seg_mgr
->template construct_it
<int>(object1_name
)[ShmSizeSize
](&int_array_values
[0]); }BOOST_CATCH(interprocess_exception
&){} BOOST_CATCH_END
301 if(seg_mgr
->template construct_it
<int>(object2_name
, std::nothrow
)[ShmSizeSize
](&int_array_values
[0]))
303 seg_mgr
->shrink_to_fit_indexes();
304 if(seg_mgr
->get_free_memory() != free_mem_before
)
306 if(!seg_mgr
->all_memory_deallocated())
308 seg_mgr
->reserve_named_objects(1);
309 //In indexes with no capacity() memory won't be allocated so don't check anything was allocated.
310 //if(seg_mgr->all_memory_deallocated()) return false;
311 seg_mgr
->shrink_to_fit_indexes();
312 if(!seg_mgr
->all_memory_deallocated())
316 {//test unique object
317 int const int_array_values
[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
319 for(std::size_t i
= 0; i
!= 4; ++i
){
320 if(seg_mgr
->template find
<unsigned int>(unique_instance
).first
)
322 //Single element construction
323 unsigned int *uint_object
= 0;
326 uint_object
= seg_mgr
->template construct
<unsigned int>(unique_instance
)();
329 uint_object
= seg_mgr
->template construct
<unsigned int>(unique_instance
, std::nothrow
)();
332 uint_object
= seg_mgr
->template find_or_construct
<unsigned int>(unique_instance
)();
335 uint_object
= seg_mgr
->template find_or_construct
<unsigned int>(unique_instance
, std::nothrow
)();
338 std::pair
<unsigned int*, std::size_t> find_ret
= seg_mgr
->template find
<unsigned int>(unique_instance
);
339 if(uint_object
!= find_ret
.first
)
341 if(1 != find_ret
.second
)
343 if(1 != seg_mgr
->get_instance_length(uint_object
))
345 if(unique_type
!= seg_mgr
->get_instance_type(uint_object
))
347 if(std::strcmp(typeid(unsigned int).name(), seg_mgr
->get_instance_name(uint_object
)))
350 if(seg_mgr
->template find
<int>(unique_instance
).first
)
355 int_array
= seg_mgr
->template construct_it
<int>(unique_instance
)[10](&int_array_values
[0]);
358 int_array
= seg_mgr
->template construct_it
<int>(unique_instance
, std::nothrow
)[10](&int_array_values
[0]);
361 int_array
= seg_mgr
->template find_or_construct_it
<int>(unique_instance
)[10](&int_array_values
[0]);
364 int_array
= seg_mgr
->template find_or_construct_it
<int>(unique_instance
, std::nothrow
)[10](&int_array_values
[0]);
367 std::pair
<int*, std::size_t> find_ret2
= seg_mgr
->template find
<int>(unique_instance
);
368 if(int_array
!= find_ret2
.first
)
370 if(10 != find_ret2
.second
)
372 if(10 != seg_mgr
->get_instance_length(int_array
))
374 if(unique_type
!= seg_mgr
->get_instance_type(int_array
))
376 if(std::strcmp(typeid(int).name(), seg_mgr
->get_instance_name(int_array
)))
378 if(seg_mgr
->get_num_unique_objects() != 2)
380 typename
SegmentManager::const_unique_iterator
nb(seg_mgr
->unique_begin());
381 typename
SegmentManager::const_unique_iterator
ne(seg_mgr
->unique_end());
382 for(std::size_t j
= 0, imax
= seg_mgr
->get_num_unique_objects(); j
!= imax
; ++j
){ ++nb
; }
385 seg_mgr
->destroy_ptr(uint_object
);
386 seg_mgr
->template destroy
<int>(unique_instance
);
388 BOOST_TRY
{ seg_mgr
->template construct
<unsigned int>(unique_instance
)[ShmSizeSize
](); }BOOST_CATCH(interprocess_exception
&){} BOOST_CATCH_END
389 if(seg_mgr
->template construct
<int>(unique_instance
, std::nothrow
)[ShmSizeSize
]())
390 BOOST_TRY
{ seg_mgr
->template construct_it
<long int>(unique_instance
)[ShmSizeSize
](&int_array_values
[0]); }BOOST_CATCH(interprocess_exception
&){} BOOST_CATCH_END
391 if(seg_mgr
->template construct_it
<int>(unique_instance
, std::nothrow
)[ShmSizeSize
](&int_array_values
[0]))
393 seg_mgr
->shrink_to_fit_indexes();
394 if(seg_mgr
->get_free_memory() != free_mem_before
)
396 if(!seg_mgr
->all_memory_deallocated())
398 seg_mgr
->reserve_unique_objects(1);
399 //In indexes with no capacity() memory won't be allocated so don't check anything was allocated.
400 //if(seg_mgr->all_memory_deallocated()) return false;
401 seg_mgr
->shrink_to_fit_indexes();
402 if(!seg_mgr
->all_memory_deallocated())
405 {//test allocator/deleter
406 if(!seg_mgr
->all_memory_deallocated())
408 typedef typename
SegmentManager::template allocator
<float>::type allocator_t
;
410 allocator_t
alloc(seg_mgr
->template get_allocator
<float>());
412 if(!seg_mgr
->all_memory_deallocated())
414 offset_ptr
<float> f
= alloc
.allocate(50);
415 if(seg_mgr
->all_memory_deallocated())
417 alloc
.deallocate(f
, 50);
418 if(!seg_mgr
->all_memory_deallocated())
420 typedef typename
SegmentManager::template deleter
<float>::type deleter_t
;
421 deleter_t
delet(seg_mgr
->template get_deleter
<float>());
422 delet(seg_mgr
->template construct
<float>(anonymous_instance
)());
423 if(!seg_mgr
->all_memory_deallocated())
426 {//test allocator/deleter
427 if(!seg_mgr
->all_memory_deallocated())
429 int *int_object
= seg_mgr
->template construct
<int>("atomic_func_find_object")();
430 atomic_func_test
<SegmentManager
> func(*seg_mgr
);
431 seg_mgr
->atomic_func(func
);
432 if(int_object
!= func
.object
)
434 seg_mgr
->destroy_ptr(int_object
);
435 seg_mgr
->shrink_to_fit_indexes();
436 if(!seg_mgr
->all_memory_deallocated())
439 {//test get_memory_algorithm
441 typename
SegmentManager::memory_algorithm
& mem_algo
=
442 seg_mgr
->get_memory_algorithm();
443 boost::ignore_unused(mem_algo
);
446 const typename
SegmentManager::memory_algorithm
& mem_algo
=
447 const_cast<const SegmentManager
*>(seg_mgr
)->get_memory_algorithm();
448 boost::ignore_unused(mem_algo
);
454 template<class MemoryAlgorithm
>
455 bool test_each_algo()
458 typedef segment_manager
< char, MemoryAlgorithm
, flat_map_index
> segment_manager_t
;
459 if(!test_segment_manager
<segment_manager_t
>())
463 typedef segment_manager
< char, MemoryAlgorithm
, map_index
> segment_manager_t
;
464 if(!test_segment_manager
<segment_manager_t
>())
469 typedef segment_manager< char, MemoryAlgorithm, null_index > segment_manager_t;
470 if(!test_segment_manager<segment_manager_t>())
475 typedef segment_manager< char, MemoryAlgorithm, unordered_map_index > segment_manager_t;
476 if(!test_segment_manager<segment_manager_t>())
480 typedef segment_manager
< char, MemoryAlgorithm
, iset_index
> segment_manager_t
;
481 if(!test_segment_manager
<segment_manager_t
>())
485 typedef segment_manager
< char, MemoryAlgorithm
, iunordered_set_index
> segment_manager_t
;
486 if(!test_segment_manager
<segment_manager_t
>())
494 if(!test_each_algo
< simple_seq_fit
< null_mutex_family
> >())
496 if(!test_each_algo
< rbtree_best_fit
< null_mutex_family
> >())