1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2005-2013. 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/container for documentation.
9 //////////////////////////////////////////////////////////////////////////////
11 #ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_HPP
12 #define BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_HPP
14 #ifndef BOOST_CONFIG_HPP
15 # include <boost/config.hpp>
18 #if defined(BOOST_HAS_PRAGMA_ONCE)
22 #include <boost/container/detail/config_begin.hpp>
23 #include <boost/container/detail/workaround.hpp>
25 #include <boost/intrusive/set.hpp>
26 #include <boost/container/detail/multiallocation_chain.hpp>
27 #include <boost/container/detail/pool_common_alloc.hpp>
28 #include <boost/container/detail/mutex.hpp>
29 #include <boost/container/detail/adaptive_node_pool_impl.hpp>
30 #include <boost/container/detail/multiallocation_chain.hpp>
31 #include <boost/container/detail/type_traits.hpp>
42 //!Pooled memory allocator using an smart adaptive pool. Includes
43 //!a reference count but the class does not delete itself, this is
44 //!responsibility of user classes. Node size (NodeSize) and the number of
45 //!nodes allocated per block (NodesPerBlock) are known at compile time.
46 template< std::size_t NodeSize
47 , std::size_t NodesPerBlock
48 , std::size_t MaxFreeBlocks
49 , std::size_t OverheadPercent
51 class private_adaptive_node_pool
52 : public private_adaptive_node_pool_impl_ct
53 < fake_segment_manager
58 , unsigned(OverheadPercent == 0)*::boost::container::adaptive_pool_flag::align_only
59 | ::boost::container::adaptive_pool_flag::size_ordered
60 | ::boost::container::adaptive_pool_flag::address_ordered
63 typedef private_adaptive_node_pool_impl_ct
64 < fake_segment_manager
69 , unsigned(OverheadPercent == 0)*::boost::container::adaptive_pool_flag::align_only
70 | ::boost::container::adaptive_pool_flag::size_ordered
71 | ::boost::container::adaptive_pool_flag::address_ordered
75 private_adaptive_node_pool(const private_adaptive_node_pool &);
76 private_adaptive_node_pool &operator=(const private_adaptive_node_pool &);
79 static const std::size_t nodes_per_block = NodesPerBlock;
81 //!Constructor. Never throws
82 private_adaptive_node_pool()
87 //!Pooled memory allocator using adaptive pool. Includes
88 //!a reference count but the class does not delete itself, this is
89 //!responsibility of user classes. Node size (NodeSize) and the number of
90 //!nodes allocated per block (NodesPerBlock) are known at compile time
91 template< std::size_t NodeSize
92 , std::size_t NodesPerBlock
93 , std::size_t MaxFreeBlocks
94 , std::size_t OverheadPercent
96 class shared_adaptive_node_pool
97 : public private_adaptive_node_pool
98 <NodeSize, NodesPerBlock, MaxFreeBlocks, OverheadPercent>
101 typedef private_adaptive_node_pool
102 <NodeSize, NodesPerBlock, MaxFreeBlocks, OverheadPercent> private_node_allocator_t;
104 typedef typename private_node_allocator_t::multiallocation_chain multiallocation_chain;
106 //!Constructor. Never throws
107 shared_adaptive_node_pool()
108 : private_node_allocator_t(){}
110 //!Destructor. Deallocates all allocated blocks. Never throws
111 ~shared_adaptive_node_pool()
114 //!Allocates array of count elements. Can throw bad_alloc
115 void *allocate_node()
117 //-----------------------
118 scoped_lock<default_mutex> guard(mutex_);
119 //-----------------------
120 return private_node_allocator_t::allocate_node();
123 //!Deallocates an array pointed by ptr. Never throws
124 void deallocate_node(void *ptr)
126 //-----------------------
127 scoped_lock<default_mutex> guard(mutex_);
128 //-----------------------
129 private_node_allocator_t::deallocate_node(ptr);
132 //!Allocates a singly linked list of n nodes ending in null pointer.
133 //!can throw bad_alloc
134 void allocate_nodes(const std::size_t n, multiallocation_chain &chain)
136 //-----------------------
137 scoped_lock<default_mutex> guard(mutex_);
138 //-----------------------
139 return private_node_allocator_t::allocate_nodes(n, chain);
142 void deallocate_nodes(multiallocation_chain &chain)
144 //-----------------------
145 scoped_lock<default_mutex> guard(mutex_);
146 //-----------------------
147 private_node_allocator_t::deallocate_nodes(chain);
150 //!Deallocates all the free blocks of memory. Never throws
151 void deallocate_free_blocks()
153 //-----------------------
154 scoped_lock<default_mutex> guard(mutex_);
155 //-----------------------
156 private_node_allocator_t::deallocate_free_blocks();
160 default_mutex mutex_;
164 } //namespace container {
165 } //namespace boost {
167 #include <boost/container/detail/config_end.hpp>
169 #endif //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_HPP