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 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/container/detail/config_begin.hpp>
19 #include <boost/container/detail/workaround.hpp>
21 #include <boost/intrusive/set.hpp>
22 #include <boost/aligned_storage.hpp>
23 #include <boost/container/detail/alloc_lib_auto_link.hpp>
24 #include <boost/container/detail/multiallocation_chain.hpp>
25 #include <boost/container/detail/pool_common_alloc.hpp>
26 #include <boost/container/detail/mutex.hpp>
27 #include <boost/container/detail/adaptive_node_pool_impl.hpp>
28 #include <boost/container/detail/multiallocation_chain.hpp>
36 namespace container_detail {
38 template<bool AlignOnly>
39 struct select_private_adaptive_node_pool_impl
41 typedef boost::container::container_detail::
42 private_adaptive_node_pool_impl
43 < fake_segment_manager
44 , unsigned(AlignOnly)*::boost::container::adaptive_pool_flag::align_only
45 | ::boost::container::adaptive_pool_flag::size_ordered | ::boost::container::adaptive_pool_flag::address_ordered
49 //!Pooled memory allocator using an smart adaptive pool. Includes
50 //!a reference count but the class does not delete itself, this is
51 //!responsibility of user classes. Node size (NodeSize) and the number of
52 //!nodes allocated per block (NodesPerBlock) are known at compile time.
53 template< std::size_t NodeSize
54 , std::size_t NodesPerBlock
55 , std::size_t MaxFreeBlocks
56 , std::size_t OverheadPercent
58 class private_adaptive_node_pool
59 : public select_private_adaptive_node_pool_impl<(OverheadPercent == 0)>::type
61 typedef typename select_private_adaptive_node_pool_impl<OverheadPercent == 0>::type base_t;
63 private_adaptive_node_pool(const private_adaptive_node_pool &);
64 private_adaptive_node_pool &operator=(const private_adaptive_node_pool &);
67 typedef typename base_t::multiallocation_chain multiallocation_chain;
68 static const std::size_t nodes_per_block = NodesPerBlock;
70 //!Constructor. Never throws
71 private_adaptive_node_pool()
76 , (unsigned char)OverheadPercent)
80 //!Pooled memory allocator using adaptive pool. Includes
81 //!a reference count but the class does not delete itself, this is
82 //!responsibility of user classes. Node size (NodeSize) and the number of
83 //!nodes allocated per block (NodesPerBlock) are known at compile time
84 template< std::size_t NodeSize
85 , std::size_t NodesPerBlock
86 , std::size_t MaxFreeBlocks
87 , std::size_t OverheadPercent
89 class shared_adaptive_node_pool
90 : public private_adaptive_node_pool
91 <NodeSize, NodesPerBlock, MaxFreeBlocks, OverheadPercent>
94 typedef private_adaptive_node_pool
95 <NodeSize, NodesPerBlock, MaxFreeBlocks, OverheadPercent> private_node_allocator_t;
97 typedef typename private_node_allocator_t::multiallocation_chain multiallocation_chain;
99 //!Constructor. Never throws
100 shared_adaptive_node_pool()
101 : private_node_allocator_t(){}
103 //!Destructor. Deallocates all allocated blocks. Never throws
104 ~shared_adaptive_node_pool()
107 //!Allocates array of count elements. Can throw std::bad_alloc
108 void *allocate_node()
110 //-----------------------
111 scoped_lock<default_mutex> guard(mutex_);
112 //-----------------------
113 return private_node_allocator_t::allocate_node();
116 //!Deallocates an array pointed by ptr. Never throws
117 void deallocate_node(void *ptr)
119 //-----------------------
120 scoped_lock<default_mutex> guard(mutex_);
121 //-----------------------
122 private_node_allocator_t::deallocate_node(ptr);
125 //!Allocates a singly linked list of n nodes ending in null pointer.
126 //!can throw std::bad_alloc
127 void allocate_nodes(const std::size_t n, multiallocation_chain &chain)
129 //-----------------------
130 scoped_lock<default_mutex> guard(mutex_);
131 //-----------------------
132 return private_node_allocator_t::allocate_nodes(n, chain);
135 void deallocate_nodes(multiallocation_chain &chain)
137 //-----------------------
138 scoped_lock<default_mutex> guard(mutex_);
139 //-----------------------
140 private_node_allocator_t::deallocate_nodes(chain);
143 //!Deallocates all the free blocks of memory. Never throws
144 void deallocate_free_blocks()
146 //-----------------------
147 scoped_lock<default_mutex> guard(mutex_);
148 //-----------------------
149 private_node_allocator_t::deallocate_free_blocks();
153 default_mutex mutex_;
156 } //namespace container_detail {
157 } //namespace container {
158 } //namespace boost {
160 #include <boost/container/detail/config_end.hpp>
162 #endif //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_HPP