]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | ////////////////////////////////////////////////////////////////////////////// |
2 | // | |
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) | |
6 | // | |
7 | // See http://www.boost.org/libs/container for documentation. | |
8 | // | |
9 | ////////////////////////////////////////////////////////////////////////////// | |
10 | ||
11 | #ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_HPP | |
12 | #define BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_HPP | |
13 | ||
14 | #ifndef BOOST_CONFIG_HPP | |
15 | # include <boost/config.hpp> | |
16 | #endif | |
17 | ||
18 | #if defined(BOOST_HAS_PRAGMA_ONCE) | |
19 | # pragma once | |
20 | #endif | |
21 | ||
22 | #include <boost/container/detail/config_begin.hpp> | |
23 | #include <boost/container/detail/workaround.hpp> | |
24 | ||
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> | |
32 | ||
33 | #include <cstddef> | |
34 | #include <cmath> | |
35 | #include <cassert> | |
36 | ||
37 | ||
38 | namespace boost { | |
39 | namespace container { | |
40 | namespace container_detail { | |
41 | ||
42 | template<bool AlignOnly> | |
43 | struct select_private_adaptive_node_pool_impl | |
44 | { | |
45 | typedef boost::container::container_detail:: | |
46 | private_adaptive_node_pool_impl | |
47 | < fake_segment_manager | |
48 | , unsigned(AlignOnly)*::boost::container::adaptive_pool_flag::align_only | |
49 | | ::boost::container::adaptive_pool_flag::size_ordered | ::boost::container::adaptive_pool_flag::address_ordered | |
50 | > type; | |
51 | }; | |
52 | ||
53 | //!Pooled memory allocator using an smart adaptive pool. Includes | |
54 | //!a reference count but the class does not delete itself, this is | |
55 | //!responsibility of user classes. Node size (NodeSize) and the number of | |
56 | //!nodes allocated per block (NodesPerBlock) are known at compile time. | |
57 | template< std::size_t NodeSize | |
58 | , std::size_t NodesPerBlock | |
59 | , std::size_t MaxFreeBlocks | |
60 | , std::size_t OverheadPercent | |
61 | > | |
62 | class private_adaptive_node_pool | |
63 | : public select_private_adaptive_node_pool_impl<(OverheadPercent == 0)>::type | |
64 | { | |
65 | typedef typename select_private_adaptive_node_pool_impl<OverheadPercent == 0>::type base_t; | |
66 | //Non-copyable | |
67 | private_adaptive_node_pool(const private_adaptive_node_pool &); | |
68 | private_adaptive_node_pool &operator=(const private_adaptive_node_pool &); | |
69 | ||
70 | public: | |
71 | typedef typename base_t::multiallocation_chain multiallocation_chain; | |
72 | static const std::size_t nodes_per_block = NodesPerBlock; | |
73 | ||
74 | //!Constructor. Never throws | |
75 | private_adaptive_node_pool() | |
76 | : base_t(0 | |
77 | , NodeSize | |
78 | , NodesPerBlock | |
79 | , MaxFreeBlocks | |
80 | , (unsigned char)OverheadPercent) | |
81 | {} | |
82 | }; | |
83 | ||
84 | //!Pooled memory allocator using adaptive pool. Includes | |
85 | //!a reference count but the class does not delete itself, this is | |
86 | //!responsibility of user classes. Node size (NodeSize) and the number of | |
87 | //!nodes allocated per block (NodesPerBlock) are known at compile time | |
88 | template< std::size_t NodeSize | |
89 | , std::size_t NodesPerBlock | |
90 | , std::size_t MaxFreeBlocks | |
91 | , std::size_t OverheadPercent | |
92 | > | |
93 | class shared_adaptive_node_pool | |
94 | : public private_adaptive_node_pool | |
95 | <NodeSize, NodesPerBlock, MaxFreeBlocks, OverheadPercent> | |
96 | { | |
97 | private: | |
98 | typedef private_adaptive_node_pool | |
99 | <NodeSize, NodesPerBlock, MaxFreeBlocks, OverheadPercent> private_node_allocator_t; | |
100 | public: | |
101 | typedef typename private_node_allocator_t::multiallocation_chain multiallocation_chain; | |
102 | ||
103 | //!Constructor. Never throws | |
104 | shared_adaptive_node_pool() | |
105 | : private_node_allocator_t(){} | |
106 | ||
107 | //!Destructor. Deallocates all allocated blocks. Never throws | |
108 | ~shared_adaptive_node_pool() | |
109 | {} | |
110 | ||
111 | //!Allocates array of count elements. Can throw std::bad_alloc | |
112 | void *allocate_node() | |
113 | { | |
114 | //----------------------- | |
115 | scoped_lock<default_mutex> guard(mutex_); | |
116 | //----------------------- | |
117 | return private_node_allocator_t::allocate_node(); | |
118 | } | |
119 | ||
120 | //!Deallocates an array pointed by ptr. Never throws | |
121 | void deallocate_node(void *ptr) | |
122 | { | |
123 | //----------------------- | |
124 | scoped_lock<default_mutex> guard(mutex_); | |
125 | //----------------------- | |
126 | private_node_allocator_t::deallocate_node(ptr); | |
127 | } | |
128 | ||
129 | //!Allocates a singly linked list of n nodes ending in null pointer. | |
130 | //!can throw std::bad_alloc | |
131 | void allocate_nodes(const std::size_t n, multiallocation_chain &chain) | |
132 | { | |
133 | //----------------------- | |
134 | scoped_lock<default_mutex> guard(mutex_); | |
135 | //----------------------- | |
136 | return private_node_allocator_t::allocate_nodes(n, chain); | |
137 | } | |
138 | ||
139 | void deallocate_nodes(multiallocation_chain &chain) | |
140 | { | |
141 | //----------------------- | |
142 | scoped_lock<default_mutex> guard(mutex_); | |
143 | //----------------------- | |
144 | private_node_allocator_t::deallocate_nodes(chain); | |
145 | } | |
146 | ||
147 | //!Deallocates all the free blocks of memory. Never throws | |
148 | void deallocate_free_blocks() | |
149 | { | |
150 | //----------------------- | |
151 | scoped_lock<default_mutex> guard(mutex_); | |
152 | //----------------------- | |
153 | private_node_allocator_t::deallocate_free_blocks(); | |
154 | } | |
155 | ||
156 | private: | |
157 | default_mutex mutex_; | |
158 | }; | |
159 | ||
160 | } //namespace container_detail { | |
161 | } //namespace container { | |
162 | } //namespace boost { | |
163 | ||
164 | #include <boost/container/detail/config_end.hpp> | |
165 | ||
166 | #endif //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_HPP |