adaptive_node_pool.hpp 5.4 KB

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