]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/interprocess/test/named_allocation_test_template.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / interprocess / test / named_allocation_test_template.hpp
CommitLineData
7c673cae
FG
1//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2006-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#ifndef BOOST_INTERPROCESS_NAMED_ALLOCATION_TEST_TEMPLATE_HEADER
12#define BOOST_INTERPROCESS_NAMED_ALLOCATION_TEST_TEMPLATE_HEADER
13
14#include <boost/interprocess/detail/config_begin.hpp>
15
16// interprocess
17#include <boost/interprocess/managed_shared_memory.hpp>
18#include <boost/interprocess/mem_algo/rbtree_best_fit.hpp>
19#include <boost/interprocess/streams/bufferstream.hpp>
20#include <boost/interprocess/sync/mutex_family.hpp>
21// container
22#include <boost/container/detail/iterator.hpp>
23#include <boost/container/detail/minimal_char_traits_header.hpp> //char_traits
24// std
25#include <cstdio>
26#include <iostream>
27#include <new>
28#include <set>
29#include <vector>
30
31// local
32#include "get_process_id_name.hpp"
33
34namespace boost { namespace interprocess { namespace test {
35
36namespace {
37 const wchar_t *get_prefix(wchar_t)
38 { return L"prefix_name_"; }
39
40 const char *get_prefix(char)
41 { return "prefix_name_"; }
42}
43
44//This test allocates until there is no more memory
45//and after that deallocates all in the same order
46template<class ManagedMemory>
47bool test_names_and_types(ManagedMemory &m)
48{
49 typedef typename ManagedMemory::char_type char_type;
50 typedef std::char_traits<char_type> char_traits_type;
51 std::vector<char*> buffers;
1e59de90 52 const std::size_t BufferLen = 100u;
7c673cae
FG
53 char_type name[BufferLen];
54
55 basic_bufferstream<char_type> formatter(name, BufferLen);
56
1e59de90 57 for(std::size_t i = 0; true; ++i){
7c673cae
FG
58 formatter.seekp(0);
59 formatter << get_prefix(char_type()) << i << std::ends;
60
1e59de90 61 char *ptr = m.template construct<char>(name, std::nothrow)((char)i);
7c673cae
FG
62
63 if(!ptr)
64 break;
65
66 std::size_t namelen = char_traits_type::length(m.get_instance_name(ptr));
67 if(namelen != char_traits_type::length(name)){
68 return 1;
69 }
70
71 if(char_traits_type::compare(m.get_instance_name(ptr), name, namelen) != 0){
72 return 1;
73 }
74
75 if(m.template find<char>(name).first == 0)
76 return false;
77
78 if(m.get_instance_type(ptr) != named_type)
79 return false;
80
81 buffers.push_back(ptr);
82 }
83
84 if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
85 return false;
86
1e59de90 87 for(std::size_t j = 0, max = buffers.size()
7c673cae
FG
88 ;j < max
89 ;++j){
90 m.destroy_ptr(buffers[j]);
91 }
92
93 if(m.get_num_named_objects() != 0 || !m.check_sanity())
94 return false;
95 m.shrink_to_fit_indexes();
96 if(!m.all_memory_deallocated())
97 return false;
98 return true;
99}
100
101
102//This test allocates until there is no more memory
103//and after that deallocates all in the same order
104template<class ManagedMemory>
105bool test_named_iterators(ManagedMemory &m)
106{
107 typedef typename ManagedMemory::char_type char_type;
108 std::vector<char*> buffers;
1e59de90 109 const std::size_t BufferLen = 100;
7c673cae
FG
110 char_type name[BufferLen];
111 typedef std::basic_string<char_type> string_type;
112 std::set<string_type> names;
113
114 basic_bufferstream<char_type> formatter(name, BufferLen);
115
116 string_type aux_str;
117
1e59de90 118 for(std::size_t i = 0; true; ++i){
7c673cae
FG
119 formatter.seekp(0);
120 formatter << get_prefix(char_type()) << i << std::ends;
1e59de90 121 char *ptr = m.template construct<char>(name, std::nothrow)((char)i);
7c673cae
FG
122 if(!ptr)
123 break;
124 aux_str = name;
125 names.insert(aux_str);
126 buffers.push_back(ptr);
127 }
128
129 if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
130 return false;
131
132 typedef typename ManagedMemory::const_named_iterator const_named_iterator;
133 const_named_iterator named_beg = m.named_begin();
134 const_named_iterator named_end = m.named_end();
135
136 if((std::size_t)boost::container::iterator_distance(named_beg, named_end) != (std::size_t)buffers.size()){
137 return 1;
138 }
139
140 for(; named_beg != named_end; ++named_beg){
141 const char_type *name_str = named_beg->name();
142 aux_str = name_str;
143 if(names.find(aux_str) == names.end()){
144 return 1;
145 }
146
147 if(aux_str.size() != named_beg->name_length()){
148 return 1;
149 }
150
151 const void *found_value = m.template find<char>(name_str).first;
152
153 if(found_value == 0)
154 return false;
155 if(found_value != named_beg->value())
156 return false;
157 }
158
1e59de90 159 for(std::size_t j = 0, max = buffers.size()
7c673cae
FG
160 ;j < max
161 ;++j){
162 m.destroy_ptr(buffers[j]);
163 }
164
165 if(m.get_num_named_objects() != 0 || !m.check_sanity())
166 return false;
167 m.shrink_to_fit_indexes();
168 if(!m.all_memory_deallocated())
169 return false;
170 return true;
171}
172
173//This test allocates until there is no more memory
174//and after that deallocates all in the same order
175template<class ManagedMemory>
176bool test_shrink_to_fit(ManagedMemory &m)
177{
178 typedef typename ManagedMemory::char_type char_type;
179 std::vector<char*> buffers;
1e59de90 180 const std::size_t BufferLen = 100;
7c673cae
FG
181 char_type name[BufferLen];
182
183 basic_bufferstream<char_type> formatter(name, BufferLen);
184
185 std::size_t free_memory_before = m.get_free_memory();
186
1e59de90 187 for(std::size_t i = 0; true; ++i){
7c673cae
FG
188 formatter.seekp(0);
189 formatter << get_prefix(char_type()) << i << std::ends;
190
1e59de90 191 char *ptr = m.template construct<char>(name, std::nothrow)((char)i);
7c673cae
FG
192
193 if(!ptr)
194 break;
195 buffers.push_back(ptr);
196 }
197
1e59de90 198 for(std::size_t j = 0, max = buffers.size()
7c673cae
FG
199 ;j < max
200 ;++j){
201 m.destroy_ptr(buffers[j]);
202 }
203
204 std::size_t free_memory_after = m.get_free_memory();
205
206 if(free_memory_before != free_memory_after){
207 m.shrink_to_fit_indexes();
208 if(free_memory_before != free_memory_after)
209 return false;
210 }
211 return true;
212}
213
214//This test allocates until there is no more memory
215//and after that deallocates all in the same order
216template<class ManagedMemory>
217bool test_direct_named_allocation_destruction(ManagedMemory &m)
218{
219 typedef typename ManagedMemory::char_type char_type;
220 std::vector<char*> buffers;
1e59de90 221 const std::size_t BufferLen = 100;
7c673cae
FG
222 char_type name[BufferLen];
223
224 basic_bufferstream<char_type> formatter(name, BufferLen);
225
1e59de90 226 for(std::size_t i = 0; true; ++i){
7c673cae
FG
227 formatter.seekp(0);
228 formatter << get_prefix(char_type()) << i << std::ends;
1e59de90 229 char *ptr = m.template construct<char>(name, std::nothrow)((char)i);
7c673cae
FG
230 if(!ptr)
231 break;
232 if(m.template find<char>(name).first == 0)
233 return false;
234 buffers.push_back(ptr);
235 }
236
237 if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
238 return false;
239
1e59de90 240 for(std::size_t j = 0, max = buffers.size()
7c673cae
FG
241 ;j < max
242 ;++j){
243 m.destroy_ptr(buffers[j]);
244 }
245
246 if(m.get_num_named_objects() != 0 || !m.check_sanity())
247 return false;
248 m.shrink_to_fit_indexes();
249 if(!m.all_memory_deallocated())
250 return false;
251 return true;
252}
253
254//This test allocates until there is no more memory
255//and after that deallocates all in the inverse order
256template<class ManagedMemory>
257bool test_named_allocation_inverse_destruction(ManagedMemory &m)
258{
259 typedef typename ManagedMemory::char_type char_type;
260
261 std::vector<char*> buffers;
1e59de90 262 const std::size_t BufferLen = 100;
7c673cae
FG
263 char_type name[BufferLen];
264
265 basic_bufferstream<char_type> formatter(name, BufferLen);
266
1e59de90 267 for(std::size_t i = 0; true; ++i){
7c673cae
FG
268 formatter.seekp(0);
269 formatter << get_prefix(char_type()) << i << std::ends;
1e59de90 270 char *ptr = m.template construct<char>(name, std::nothrow)((char)i);
7c673cae
FG
271 if(!ptr)
272 break;
273 buffers.push_back(ptr);
274 }
275
276 if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
277 return false;
278
1e59de90 279 for(std::size_t j = buffers.size()
7c673cae
FG
280 ;j--
281 ;){
282 m.destroy_ptr(buffers[j]);
283 }
284
285 if(m.get_num_named_objects() != 0 || !m.check_sanity())
286 return false;
287 m.shrink_to_fit_indexes();
288 if(!m.all_memory_deallocated())
289 return false;
290 return true;
291}
292
293//This test allocates until there is no more memory
294//and after that deallocates all following a pattern
295template<class ManagedMemory>
296bool test_named_allocation_mixed_destruction(ManagedMemory &m)
297{
298 typedef typename ManagedMemory::char_type char_type;
299
300 std::vector<char*> buffers;
1e59de90 301 const std::size_t BufferLen = 100;
7c673cae
FG
302 char_type name[BufferLen];
303
304 basic_bufferstream<char_type> formatter(name, BufferLen);
305
1e59de90 306 for(std::size_t i = 0; true; ++i){
7c673cae
FG
307 formatter.seekp(0);
308 formatter << get_prefix(char_type()) << i << std::ends;
1e59de90 309 char *ptr = m.template construct<char>(name, std::nothrow)((char)i);
7c673cae
FG
310 if(!ptr)
311 break;
312 buffers.push_back(ptr);
313 }
314
315 if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
316 return false;
317
1e59de90 318 for(std::size_t j = 0, max = buffers.size()
7c673cae
FG
319 ;j < max
320 ;++j){
1e59de90 321 std::size_t pos = (j%4u)*(buffers.size())/4u;
7c673cae 322 m.destroy_ptr(buffers[pos]);
1e59de90 323 buffers.erase(buffers.begin()+std::ptrdiff_t(pos));
7c673cae
FG
324 }
325
326 if(m.get_num_named_objects() != 0 || !m.check_sanity())
327 return false;
328 m.shrink_to_fit_indexes();
329 if(!m.all_memory_deallocated())
330 return false;
331 return true;
332}
333
334//This test allocates until there is no more memory
335//and after that deallocates all in the same order
336template<class ManagedMemory>
337bool test_inverse_named_allocation_destruction(ManagedMemory &m)
338{
339 typedef typename ManagedMemory::char_type char_type;
340
341 std::vector<char*> buffers;
1e59de90 342 const std::size_t BufferLen = 100;
7c673cae
FG
343 char_type name[BufferLen];
344
345 basic_bufferstream<char_type> formatter(name, BufferLen);
346
1e59de90 347 for(std::size_t i = 0; true; ++i){
7c673cae
FG
348 formatter.seekp(0);
349 formatter << get_prefix(char_type()) << i << std::ends;
1e59de90 350 char *ptr = m.template construct<char>(name, std::nothrow)((char)i);
7c673cae
FG
351 if(!ptr)
352 break;
353 buffers.push_back(ptr);
354 }
355
356 if(m.get_num_named_objects() != buffers.size() || !m.check_sanity())
357 return false;
358
1e59de90 359 for(std::size_t j = 0, max = (unsigned int)buffers.size()
7c673cae
FG
360 ;j < max
361 ;++j){
362 m.destroy_ptr(buffers[j]);
363 }
364
365 if(m.get_num_named_objects() != 0 || !m.check_sanity())
366 return false;
367 m.shrink_to_fit_indexes();
368 if(!m.all_memory_deallocated())
369 return false;
370 return true;
371}
372
373///This function calls all tests
374template<class ManagedMemory>
375bool test_all_named_allocation(ManagedMemory &m)
376{
377 std::cout << "Starting test_names_and_types. Class: "
378 << typeid(m).name() << std::endl;
379
380 if(!test_names_and_types(m)){
381 std::cout << "test_names_and_types failed. Class: "
382 << typeid(m).name() << std::endl;
383 return false;
384 }
385
386 std::cout << "Starting test_direct_named_allocation_destruction. Class: "
387 << typeid(m).name() << std::endl;
388
389 if(!test_direct_named_allocation_destruction(m)){
390 std::cout << "test_direct_named_allocation_destruction failed. Class: "
391 << typeid(m).name() << std::endl;
392 return false;
393 }
394
395 std::cout << "Starting test_named_allocation_inverse_destruction. Class: "
396 << typeid(m).name() << std::endl;
397
398 if(!test_named_allocation_inverse_destruction(m)){
399 std::cout << "test_named_allocation_inverse_destruction failed. Class: "
400 << typeid(m).name() << std::endl;
401 return false;
402 }
403
404 std::cout << "Starting test_named_allocation_mixed_destruction. Class: "
405 << typeid(m).name() << std::endl;
406
407 if(!test_named_allocation_mixed_destruction(m)){
408 std::cout << "test_named_allocation_mixed_destruction failed. Class: "
409 << typeid(m).name() << std::endl;
410 return false;
411 }
412
413 std::cout << "Starting test_inverse_named_allocation_destruction. Class: "
414 << typeid(m).name() << std::endl;
415
416 if(!test_inverse_named_allocation_destruction(m)){
417 std::cout << "test_inverse_named_allocation_destruction failed. Class: "
418 << typeid(m).name() << std::endl;
419 return false;
420 }
421
422 if(!test_named_iterators(m)){
423 std::cout << "test_named_iterators failed. Class: "
424 << typeid(m).name() << std::endl;
425 return false;
426 }
427
428 return true;
429}
430
431//This function calls all tests
432template<template <class IndexConfig> class Index>
433bool test_named_allocation()
434{
435 using namespace boost::interprocess;
436
437 const int memsize = 163840;
438 const char *const shMemName = test::get_process_id_name();
1e59de90 439 BOOST_TRY
7c673cae
FG
440 {
441 //A shared memory with rbtree best fit algorithm
442 typedef basic_managed_shared_memory
443 <char
444 ,rbtree_best_fit<mutex_family>
445 ,Index
446 > my_managed_shared_memory;
447
448 //Create shared memory
449 shared_memory_object::remove(shMemName);
450 my_managed_shared_memory segment(create_only, shMemName, memsize);
451
452 //Now take the segment manager and launch memory test
453 if(!test::test_all_named_allocation(*segment.get_segment_manager())){
454 return false;
455 }
456 }
1e59de90 457 BOOST_CATCH(...){
7c673cae 458 shared_memory_object::remove(shMemName);
1e59de90
TL
459 BOOST_RETHROW
460 } BOOST_CATCH_END
7c673cae
FG
461 shared_memory_object::remove(shMemName);
462
463 //Now test it with wchar_t
1e59de90 464 BOOST_TRY
7c673cae
FG
465 {
466 //A shared memory with simple sequential fit algorithm
467 typedef basic_managed_shared_memory
468 <wchar_t
469 ,rbtree_best_fit<mutex_family>
470 ,Index
471 > my_managed_shared_memory;
472
473 //Create shared memory
474 shared_memory_object::remove(shMemName);
475 my_managed_shared_memory segment(create_only, shMemName, memsize);
476
477 //Now take the segment manager and launch memory test
478 if(!test::test_all_named_allocation(*segment.get_segment_manager())){
479 return false;
480 }
481 }
1e59de90 482 BOOST_CATCH(...){
7c673cae 483 shared_memory_object::remove(shMemName);
1e59de90
TL
484 BOOST_RETHROW
485 } BOOST_CATCH_END
7c673cae
FG
486 shared_memory_object::remove(shMemName);
487
488 return true;
489}
490
491}}} //namespace boost { namespace interprocess { namespace test {
492
493#include <boost/interprocess/detail/config_end.hpp>
494
495#endif //BOOST_INTERPROCESS_NAMED_ALLOCATION_TEST_TEMPLATE_HEADER