cached_adaptive_pool.hpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2005-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. #ifndef BOOST_INTERPROCESS_CACHED_ADAPTIVE_POOL_HPP
  11. #define BOOST_INTERPROCESS_CACHED_ADAPTIVE_POOL_HPP
  12. #ifndef BOOST_CONFIG_HPP
  13. # include <boost/config.hpp>
  14. #endif
  15. #
  16. #if defined(BOOST_HAS_PRAGMA_ONCE)
  17. # pragma once
  18. #endif
  19. #include <boost/interprocess/detail/config_begin.hpp>
  20. #include <boost/interprocess/detail/workaround.hpp>
  21. #include <boost/interprocess/interprocess_fwd.hpp>
  22. #include <boost/interprocess/allocators/detail/adaptive_node_pool.hpp>
  23. #include <boost/interprocess/allocators/detail/allocator_common.hpp>
  24. #include <boost/interprocess/detail/utilities.hpp>
  25. #include <boost/interprocess/detail/workaround.hpp>
  26. #include <boost/interprocess/containers/version_type.hpp>
  27. #include <boost/interprocess/allocators/detail/node_tools.hpp>
  28. #include <cstddef>
  29. //!\file
  30. //!Describes cached_adaptive_pool pooled shared memory STL compatible allocator
  31. namespace boost {
  32. namespace interprocess {
  33. #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
  34. namespace ipcdetail {
  35. template < class T
  36. , class SegmentManager
  37. , std::size_t NodesPerBlock = 64
  38. , std::size_t MaxFreeBlocks = 2
  39. , unsigned char OverheadPercent = 5
  40. >
  41. class cached_adaptive_pool_v1
  42. : public ipcdetail::cached_allocator_impl
  43. < T
  44. , ipcdetail::shared_adaptive_node_pool
  45. < SegmentManager
  46. , sizeof_value<T>::value
  47. , NodesPerBlock
  48. , MaxFreeBlocks
  49. , OverheadPercent
  50. >
  51. , 1>
  52. {
  53. public:
  54. typedef ipcdetail::cached_allocator_impl
  55. < T
  56. , ipcdetail::shared_adaptive_node_pool
  57. < SegmentManager
  58. , sizeof_value<T>::value
  59. , NodesPerBlock
  60. , MaxFreeBlocks
  61. , OverheadPercent
  62. >
  63. , 1> base_t;
  64. template<class T2>
  65. struct rebind
  66. {
  67. typedef cached_adaptive_pool_v1
  68. <T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
  69. };
  70. typedef typename base_t::size_type size_type;
  71. cached_adaptive_pool_v1(SegmentManager *segment_mngr,
  72. size_type max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
  73. : base_t(segment_mngr, max_cached_nodes)
  74. {}
  75. template<class T2>
  76. cached_adaptive_pool_v1
  77. (const cached_adaptive_pool_v1
  78. <T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> &other)
  79. : base_t(other)
  80. {}
  81. };
  82. } //namespace ipcdetail{
  83. #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
  84. //!An STL node allocator that uses a segment manager as memory
  85. //!source. The internal pointer type will of the same type (raw, smart) as
  86. //!"typename SegmentManager::void_pointer" type. This allows
  87. //!placing the allocator in shared memory, memory mapped-files, etc...
  88. //!
  89. //!This node allocator shares a segregated storage between all instances of
  90. //!cached_adaptive_pool with equal sizeof(T) placed in the same
  91. //!memory segment. But also caches some nodes privately to
  92. //!avoid some synchronization overhead.
  93. //!
  94. //!NodesPerBlock is the minimum number of nodes of nodes allocated at once when
  95. //!the allocator needs runs out of nodes. MaxFreeBlocks is the maximum number of totally free blocks
  96. //!that the adaptive node pool will hold. The rest of the totally free blocks will be
  97. //!deallocated with the segment manager.
  98. //!
  99. //!OverheadPercent is the (approximated) maximum size overhead (1-20%) of the allocator:
  100. //!(memory usable for nodes / total memory allocated from the segment manager)
  101. template < class T
  102. , class SegmentManager
  103. , std::size_t NodesPerBlock
  104. , std::size_t MaxFreeBlocks
  105. , unsigned char OverheadPercent
  106. >
  107. class cached_adaptive_pool
  108. #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
  109. : public ipcdetail::cached_allocator_impl
  110. < T
  111. , ipcdetail::shared_adaptive_node_pool
  112. < SegmentManager
  113. , sizeof_value<T>::value
  114. , NodesPerBlock
  115. , MaxFreeBlocks
  116. , OverheadPercent
  117. >
  118. , 2>
  119. #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
  120. {
  121. #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
  122. public:
  123. typedef ipcdetail::cached_allocator_impl
  124. < T
  125. , ipcdetail::shared_adaptive_node_pool
  126. < SegmentManager
  127. , sizeof_value<T>::value
  128. , NodesPerBlock
  129. , MaxFreeBlocks
  130. , OverheadPercent
  131. >
  132. , 2> base_t;
  133. public:
  134. typedef boost::interprocess::version_type<cached_adaptive_pool, 2> version;
  135. template<class T2>
  136. struct rebind
  137. {
  138. typedef cached_adaptive_pool
  139. <T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
  140. };
  141. cached_adaptive_pool(SegmentManager *segment_mngr,
  142. std::size_t max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
  143. : base_t(segment_mngr, max_cached_nodes)
  144. {}
  145. template<class T2>
  146. cached_adaptive_pool
  147. (const cached_adaptive_pool<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> &other)
  148. : base_t(other)
  149. {}
  150. #else
  151. public:
  152. typedef implementation_defined::segment_manager segment_manager;
  153. typedef segment_manager::void_pointer void_pointer;
  154. typedef implementation_defined::pointer pointer;
  155. typedef implementation_defined::const_pointer const_pointer;
  156. typedef T value_type;
  157. typedef typename ipcdetail::add_reference
  158. <value_type>::type reference;
  159. typedef typename ipcdetail::add_reference
  160. <const value_type>::type const_reference;
  161. typedef typename segment_manager::size_type size_type;
  162. typedef typename segment_manager::difference_type difference_type;
  163. //!Obtains cached_adaptive_pool from
  164. //!cached_adaptive_pool
  165. template<class T2>
  166. struct rebind
  167. {
  168. typedef cached_adaptive_pool<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> other;
  169. };
  170. private:
  171. //!Not assignable from
  172. //!related cached_adaptive_pool
  173. template<class T2, class SegmentManager2, std::size_t N2, std::size_t F2, unsigned char OP2>
  174. cached_adaptive_pool& operator=
  175. (const cached_adaptive_pool<T2, SegmentManager2, N2, F2, OP2>&);
  176. //!Not assignable from
  177. //!other cached_adaptive_pool
  178. cached_adaptive_pool& operator=(const cached_adaptive_pool&);
  179. public:
  180. //!Constructor from a segment manager. If not present, constructs a node
  181. //!pool. Increments the reference count of the associated node pool.
  182. //!Can throw boost::interprocess::bad_alloc
  183. cached_adaptive_pool(segment_manager *segment_mngr);
  184. //!Copy constructor from other cached_adaptive_pool. Increments the reference
  185. //!count of the associated node pool. Never throws
  186. cached_adaptive_pool(const cached_adaptive_pool &other);
  187. //!Copy constructor from related cached_adaptive_pool. If not present, constructs
  188. //!a node pool. Increments the reference count of the associated node pool.
  189. //!Can throw boost::interprocess::bad_alloc
  190. template<class T2>
  191. cached_adaptive_pool
  192. (const cached_adaptive_pool<T2, SegmentManager, NodesPerBlock, MaxFreeBlocks, OverheadPercent> &other);
  193. //!Destructor, removes node_pool_t from memory
  194. //!if its reference count reaches to zero. Never throws
  195. ~cached_adaptive_pool();
  196. //!Returns a pointer to the node pool.
  197. //!Never throws
  198. node_pool_t* get_node_pool() const;
  199. //!Returns the segment manager.
  200. //!Never throws
  201. segment_manager* get_segment_manager()const;
  202. //!Returns the number of elements that could be allocated.
  203. //!Never throws
  204. size_type max_size() const;
  205. //!Allocate memory for an array of count elements.
  206. //!Throws boost::interprocess::bad_alloc if there is no enough memory
  207. pointer allocate(size_type count, cvoid_pointer hint = 0);
  208. //!Deallocate allocated memory.
  209. //!Never throws
  210. void deallocate(const pointer &ptr, size_type count);
  211. //!Deallocates all free blocks
  212. //!of the pool
  213. void deallocate_free_blocks();
  214. //!Swaps allocators. Does not throw. If each allocator is placed in a
  215. //!different memory segment, the result is undefined.
  216. friend void swap(self_t &alloc1, self_t &alloc2);
  217. //!Returns address of mutable object.
  218. //!Never throws
  219. pointer address(reference value) const;
  220. //!Returns address of non mutable object.
  221. //!Never throws
  222. const_pointer address(const_reference value) const;
  223. //!Copy construct an object.
  224. //!Throws if T's copy constructor throws
  225. void construct(const pointer &ptr, const_reference v);
  226. //!Destroys object. Throws if object's
  227. //!destructor throws
  228. void destroy(const pointer &ptr);
  229. //!Returns maximum the number of objects the previously allocated memory
  230. //!pointed by p can hold. This size only works for memory allocated with
  231. //!allocate, allocation_command and allocate_many.
  232. size_type size(const pointer &p) const;
  233. pointer allocation_command(boost::interprocess::allocation_type command,
  234. size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse);
  235. //!Allocates many elements of size elem_size in a contiguous block
  236. //!of memory. The minimum number to be allocated is min_elements,
  237. //!the preferred and maximum number is
  238. //!preferred_elements. The number of actually allocated elements is
  239. //!will be assigned to received_size. The elements must be deallocated
  240. //!with deallocate(...)
  241. void allocate_many(size_type elem_size, size_type num_elements, multiallocation_chain &chain);
  242. //!Allocates n_elements elements, each one of size elem_sizes[i]in a
  243. //!contiguous block
  244. //!of memory. The elements must be deallocated
  245. void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain);
  246. //!Allocates many elements of size elem_size in a contiguous block
  247. //!of memory. The minimum number to be allocated is min_elements,
  248. //!the preferred and maximum number is
  249. //!preferred_elements. The number of actually allocated elements is
  250. //!will be assigned to received_size. The elements must be deallocated
  251. //!with deallocate(...)
  252. void deallocate_many(multiallocation_chain &chain);
  253. //!Allocates just one object. Memory allocated with this function
  254. //!must be deallocated only with deallocate_one().
  255. //!Throws boost::interprocess::bad_alloc if there is no enough memory
  256. pointer allocate_one();
  257. //!Allocates many elements of size == 1 in a contiguous block
  258. //!of memory. The minimum number to be allocated is min_elements,
  259. //!the preferred and maximum number is
  260. //!preferred_elements. The number of actually allocated elements is
  261. //!will be assigned to received_size. Memory allocated with this function
  262. //!must be deallocated only with deallocate_one().
  263. multiallocation_chain allocate_individual(size_type num_elements);
  264. //!Deallocates memory previously allocated with allocate_one().
  265. //!You should never use deallocate_one to deallocate memory allocated
  266. //!with other functions different from allocate_one(). Never throws
  267. void deallocate_one(const pointer &p);
  268. //!Allocates many elements of size == 1 in a contiguous block
  269. //!of memory. The minimum number to be allocated is min_elements,
  270. //!the preferred and maximum number is
  271. //!preferred_elements. The number of actually allocated elements is
  272. //!will be assigned to received_size. Memory allocated with this function
  273. //!must be deallocated only with deallocate_one().
  274. void deallocate_individual(multiallocation_chain &chain);
  275. //!Sets the new max cached nodes value. This can provoke deallocations
  276. //!if "newmax" is less than current cached nodes. Never throws
  277. void set_max_cached_nodes(size_type newmax);
  278. //!Returns the max cached nodes parameter.
  279. //!Never throws
  280. size_type get_max_cached_nodes() const;
  281. #endif
  282. };
  283. #ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
  284. //!Equality test for same type
  285. //!of cached_adaptive_pool
  286. template<class T, class S, std::size_t NodesPerBlock, std::size_t F, std::size_t OP> inline
  287. bool operator==(const cached_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc1,
  288. const cached_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc2);
  289. //!Inequality test for same type
  290. //!of cached_adaptive_pool
  291. template<class T, class S, std::size_t NodesPerBlock, std::size_t F, std::size_t OP> inline
  292. bool operator!=(const cached_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc1,
  293. const cached_adaptive_pool<T, S, NodesPerBlock, F, OP> &alloc2);
  294. #endif
  295. } //namespace interprocess {
  296. } //namespace boost {
  297. #include <boost/interprocess/detail/config_end.hpp>
  298. #endif //#ifndef BOOST_INTERPROCESS_CACHED_ADAPTIVE_POOL_HPP