1//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2007-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#include <boost/interprocess/detail/config_begin.hpp>
11#include <boost/interprocess/managed_shared_memory.hpp>
12#include <boost/interprocess/smart_ptr/unique_ptr.hpp>
13#include <boost/interprocess/smart_ptr/deleter.hpp>
14#include <boost/interprocess/detail/type_traits.hpp>
15#include <vector>
16#include <cstddef>
17#include <string>
18#include "get_process_id_name.hpp"
19
20namespace boost {
21namespace interprocess {
22namespace test {
23
24template <class NodePool>
25struct test_node_pool
26{
27 static bool allocate_then_deallocate(NodePool &pool);
28 static bool deallocate_free_blocks(NodePool &pool);
29};
30
31template <class NodePool>
32bool test_node_pool<NodePool>::allocate_then_deallocate(NodePool &pool)
33{
34 const typename NodePool::size_type num_alloc = 1 + 3*pool.get_real_num_node();
35
36 std::vector<void*> nodes;
37
38 //Precondition, the pool must be empty
39 if(0 != pool.num_free_nodes()){
40 return false;
41 }
42
43 //First allocate nodes
44 for(std::size_t i = 0; i < num_alloc; ++i){
45 nodes.push_back(pool.allocate_node());
46 }
47
48 //Check that the free count is correct
49 if((pool.get_real_num_node() - 1) != pool.num_free_nodes()){
50 return false;
51 }
52
53 //Now deallocate all and check again
54 for(std::size_t i = 0; i < num_alloc; ++i){
55 pool.deallocate_node(nodes[i]);
56 }
57
58 //Check that the free count is correct
59 if(4*pool.get_real_num_node() != pool.num_free_nodes()){
60 return false;
61 }
62
63 pool.deallocate_free_blocks();
64
65 if(0 != pool.num_free_nodes()){
66 return false;
67 }
68
69 return true;
70}
71
72template <class NodePool>
73bool test_node_pool<NodePool>::deallocate_free_blocks(NodePool &pool)
74{
75 const std::size_t max_blocks = 10;
76 const std::size_t max_nodes = max_blocks*pool.get_real_num_node();
77 const std::size_t nodes_per_block = pool.get_real_num_node();
78
79 std::vector<void*> nodes;
80
81 //Precondition, the pool must be empty
82 if(0 != pool.num_free_nodes()){
83 return false;
84 }
85
86 //First allocate nodes
87 for(std::size_t i = 0; i < max_nodes; ++i){
88 nodes.push_back(pool.allocate_node());
89 }
90
91 //Check that the free count is correct
92 if(0 != pool.num_free_nodes()){
93 return false;
94 }
95
96 //Now deallocate one of each block per iteration
97 for(std::size_t node_i = 0; node_i < nodes_per_block; ++node_i){
98 //Deallocate a node per block
99 for(std::size_t i = 0; i < max_blocks; ++i){
100 pool.deallocate_node(nodes[i*nodes_per_block + node_i]);
101 }
102
103 //Check that the free count is correct
104 if(max_blocks*(node_i+1) != pool.num_free_nodes()){
105 return false;
106 }
107
108 //Now try to deallocate free blocks
109 pool.deallocate_free_blocks();
110
111 //Until we don't deallocate the last node of every block
112 //no node should be deallocated
113 if(node_i != (nodes_per_block - 1)){
114 if(max_blocks*(node_i+1) != pool.num_free_nodes()){
115 return false;
116 }
117 }
118 else{
119 //If this is the last iteration, all the memory should
120 //have been deallocated.
121 if(0 != pool.num_free_nodes()){
122 return false;
123 }
124 }
125 }
126
127 return true;
128}
129
130template<class node_pool_t>
131bool test_all_node_pool()
132{
133 using namespace boost::interprocess;
134 typedef managed_shared_memory::segment_manager segment_manager;
135
136 typedef boost::interprocess::test::test_node_pool<node_pool_t> test_node_pool_t;
137 shared_memory_object::remove(filename: test::get_process_id_name());
138 {
139 managed_shared_memory shm(create_only, test::get_process_id_name(), 4*1024*sizeof(segment_manager::void_pointer));
140
141 typedef deleter<node_pool_t, segment_manager> deleter_t;
142 typedef unique_ptr<node_pool_t, deleter_t> unique_ptr_t;
143
144 //Delete the pool when the tests end
145 unique_ptr_t p
146 (shm.construct<node_pool_t>(anonymous_instance)(shm.get_segment_manager())
147 ,deleter_t(shm.get_segment_manager()));
148
149 //Now call each test
150 if(!test_node_pool_t::allocate_then_deallocate(*p))
151 return false;
152 if(!test_node_pool_t::deallocate_free_blocks(*p))
153 return false;
154 }
155 shared_memory_object::remove(filename: test::get_process_id_name());
156 return true;
157}
158
159} //namespace test {
160} //namespace interprocess {
161} //namespace boost {
162
163#include <boost/interprocess/detail/config_end.hpp>
164

source code of boost/libs/interprocess/test/node_pool_test.hpp