cached_node_allocator.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  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_NODE_ALLOCATOR_HPP
  11. #define BOOST_INTERPROCESS_CACHED_NODE_ALLOCATOR_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/node_pool.hpp>
  23. #include <boost/interprocess/allocators/detail/allocator_common.hpp>
  24. #include <boost/interprocess/detail/workaround.hpp>
  25. #include <boost/interprocess/detail/utilities.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_cached_node_allocator 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. >
  39. class cached_node_allocator_v1
  40. : public ipcdetail::cached_allocator_impl
  41. < T
  42. , ipcdetail::shared_node_pool
  43. < SegmentManager
  44. , sizeof_value<T>::value
  45. , NodesPerBlock
  46. >
  47. , 1>
  48. {
  49. public:
  50. typedef ipcdetail::cached_allocator_impl
  51. < T
  52. , ipcdetail::shared_node_pool
  53. < SegmentManager
  54. , sizeof_value<T>::value
  55. , NodesPerBlock
  56. >
  57. , 1> base_t;
  58. template<class T2>
  59. struct rebind
  60. {
  61. typedef cached_node_allocator_v1
  62. <T2, SegmentManager, NodesPerBlock> other;
  63. };
  64. typedef typename base_t::size_type size_type;
  65. cached_node_allocator_v1(SegmentManager *segment_mngr,
  66. size_type max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
  67. : base_t(segment_mngr, max_cached_nodes)
  68. {}
  69. template<class T2>
  70. cached_node_allocator_v1
  71. (const cached_node_allocator_v1
  72. <T2, SegmentManager, NodesPerBlock> &other)
  73. : base_t(other)
  74. {}
  75. };
  76. } //namespace ipcdetail{
  77. #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
  78. template < class T
  79. , class SegmentManager
  80. , std::size_t NodesPerBlock
  81. >
  82. class cached_node_allocator
  83. #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
  84. : public ipcdetail::cached_allocator_impl
  85. < T
  86. , ipcdetail::shared_node_pool
  87. < SegmentManager
  88. , sizeof_value<T>::value
  89. , NodesPerBlock
  90. >
  91. , 2>
  92. #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
  93. {
  94. #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
  95. public:
  96. typedef ipcdetail::cached_allocator_impl
  97. < T
  98. , ipcdetail::shared_node_pool
  99. < SegmentManager
  100. , sizeof_value<T>::value
  101. , NodesPerBlock
  102. >
  103. , 2> base_t;
  104. public:
  105. typedef boost::interprocess::version_type<cached_node_allocator, 2> version;
  106. typedef typename base_t::size_type size_type;
  107. template<class T2>
  108. struct rebind
  109. {
  110. typedef cached_node_allocator<T2, SegmentManager, NodesPerBlock> other;
  111. };
  112. cached_node_allocator(SegmentManager *segment_mngr,
  113. size_type max_cached_nodes = base_t::DEFAULT_MAX_CACHED_NODES)
  114. : base_t(segment_mngr, max_cached_nodes)
  115. {}
  116. template<class T2>
  117. cached_node_allocator
  118. (const cached_node_allocator<T2, SegmentManager, NodesPerBlock> &other)
  119. : base_t(other)
  120. {}
  121. #else
  122. public:
  123. typedef implementation_defined::segment_manager segment_manager;
  124. typedef segment_manager::void_pointer void_pointer;
  125. typedef implementation_defined::pointer pointer;
  126. typedef implementation_defined::const_pointer const_pointer;
  127. typedef T value_type;
  128. typedef typename ipcdetail::add_reference
  129. <value_type>::type reference;
  130. typedef typename ipcdetail::add_reference
  131. <const value_type>::type const_reference;
  132. typedef typename SegmentManager::size_type size_type;
  133. typedef typename SegmentManager::difference_type difference_type;
  134. //!Obtains cached_node_allocator from
  135. //!cached_node_allocator
  136. template<class T2>
  137. struct rebind
  138. {
  139. typedef cached_node_allocator<T2, SegmentManager> other;
  140. };
  141. private:
  142. //!Not assignable from
  143. //!related cached_node_allocator
  144. template<class T2, class SegmentManager2, std::size_t N2>
  145. cached_node_allocator& operator=
  146. (const cached_node_allocator<T2, SegmentManager2, N2>&);
  147. //!Not assignable from
  148. //!other cached_node_allocator
  149. cached_node_allocator& operator=(const cached_node_allocator&);
  150. public:
  151. //!Constructor from a segment manager. If not present, constructs a node
  152. //!pool. Increments the reference count of the associated node pool.
  153. //!Can throw boost::interprocess::bad_alloc
  154. cached_node_allocator(segment_manager *segment_mngr);
  155. //!Copy constructor from other cached_node_allocator. Increments the reference
  156. //!count of the associated node pool. Never throws
  157. cached_node_allocator(const cached_node_allocator &other);
  158. //!Copy constructor from related cached_node_allocator. If not present, constructs
  159. //!a node pool. Increments the reference count of the associated node pool.
  160. //!Can throw boost::interprocess::bad_alloc
  161. template<class T2>
  162. cached_node_allocator
  163. (const cached_node_allocator<T2, SegmentManager, NodesPerBlock> &other);
  164. //!Destructor, removes node_pool_t from memory
  165. //!if its reference count reaches to zero. Never throws
  166. ~cached_node_allocator();
  167. //!Returns a pointer to the node pool.
  168. //!Never throws
  169. node_pool_t* get_node_pool() const;
  170. //!Returns the segment manager.
  171. //!Never throws
  172. segment_manager* get_segment_manager()const;
  173. //!Returns the number of elements that could be allocated.
  174. //!Never throws
  175. size_type max_size() const;
  176. //!Allocate memory for an array of count elements.
  177. //!Throws boost::interprocess::bad_alloc if there is no enough memory
  178. pointer allocate(size_type count, cvoid_pointer hint = 0);
  179. //!Deallocate allocated memory.
  180. //!Never throws
  181. void deallocate(const pointer &ptr, size_type count);
  182. //!Deallocates all free blocks
  183. //!of the pool
  184. void deallocate_free_blocks();
  185. //!Swaps allocators. Does not throw. If each allocator is placed in a
  186. //!different memory segment, the result is undefined.
  187. friend void swap(self_t &alloc1, self_t &alloc2);
  188. //!Returns address of mutable object.
  189. //!Never throws
  190. pointer address(reference value) const;
  191. //!Returns address of non mutable object.
  192. //!Never throws
  193. const_pointer address(const_reference value) const;
  194. //!Default construct an object.
  195. //!Throws if T's default constructor throws
  196. void construct(const pointer &ptr, const_reference v);
  197. //!Destroys object. Throws if object's
  198. //!destructor throws
  199. void destroy(const pointer &ptr);
  200. //!Returns maximum the number of objects the previously allocated memory
  201. //!pointed by p can hold. This size only works for memory allocated with
  202. //!allocate, allocation_command and allocate_many.
  203. size_type size(const pointer &p) const;
  204. pointer allocation_command(boost::interprocess::allocation_type command,
  205. size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse);
  206. //!Allocates many elements of size elem_size in a contiguous block
  207. //!of memory. The minimum number to be allocated is min_elements,
  208. //!the preferred and maximum number is
  209. //!preferred_elements. The number of actually allocated elements is
  210. //!will be assigned to received_size. The elements must be deallocated
  211. //!with deallocate(...)
  212. void allocate_many(size_type elem_size, size_type num_elements, multiallocation_chain &chain);
  213. //!Allocates n_elements elements, each one of size elem_sizes[i]in a
  214. //!contiguous block
  215. //!of memory. The elements must be deallocated
  216. void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain);
  217. //!Allocates many elements of size elem_size in a contiguous block
  218. //!of memory. The minimum number to be allocated is min_elements,
  219. //!the preferred and maximum number is
  220. //!preferred_elements. The number of actually allocated elements is
  221. //!will be assigned to received_size. The elements must be deallocated
  222. //!with deallocate(...)
  223. void deallocate_many(multiallocation_chain &chain);
  224. //!Allocates just one object. Memory allocated with this function
  225. //!must be deallocated only with deallocate_one().
  226. //!Throws boost::interprocess::bad_alloc if there is no enough memory
  227. pointer allocate_one();
  228. //!Allocates many elements of size == 1 in a contiguous block
  229. //!of memory. The minimum number to be allocated is min_elements,
  230. //!the preferred and maximum number is
  231. //!preferred_elements. The number of actually allocated elements is
  232. //!will be assigned to received_size. Memory allocated with this function
  233. //!must be deallocated only with deallocate_one().
  234. multiallocation_chain allocate_individual(size_type num_elements);
  235. //!Deallocates memory previously allocated with allocate_one().
  236. //!You should never use deallocate_one to deallocate memory allocated
  237. //!with other functions different from allocate_one(). Never throws
  238. void deallocate_one(const pointer &p);
  239. //!Allocates many elements of size == 1 in a contiguous block
  240. //!of memory. The minimum number to be allocated is min_elements,
  241. //!the preferred and maximum number is
  242. //!preferred_elements. The number of actually allocated elements is
  243. //!will be assigned to received_size. Memory allocated with this function
  244. //!must be deallocated only with deallocate_one().
  245. void deallocate_individual(multiallocation_chain it);
  246. //!Sets the new max cached nodes value. This can provoke deallocations
  247. //!if "newmax" is less than current cached nodes. Never throws
  248. void set_max_cached_nodes(size_type newmax);
  249. //!Returns the max cached nodes parameter.
  250. //!Never throws
  251. size_type get_max_cached_nodes() const;
  252. #endif
  253. };
  254. #ifdef BOOST_INTERPROCESS_DOXYGEN_INVOKED
  255. //!Equality test for same type
  256. //!of cached_node_allocator
  257. template<class T, class S, std::size_t NPC> inline
  258. bool operator==(const cached_node_allocator<T, S, NPC> &alloc1,
  259. const cached_node_allocator<T, S, NPC> &alloc2);
  260. //!Inequality test for same type
  261. //!of cached_node_allocator
  262. template<class T, class S, std::size_t NPC> inline
  263. bool operator!=(const cached_node_allocator<T, S, NPC> &alloc1,
  264. const cached_node_allocator<T, S, NPC> &alloc2);
  265. #endif
  266. } //namespace interprocess {
  267. } //namespace boost {
  268. #include <boost/interprocess/detail/config_end.hpp>
  269. #endif //#ifndef BOOST_INTERPROCESS_CACHED_NODE_ALLOCATOR_HPP