node_pool.hpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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_NODE_POOL_HPP
  11. #define BOOST_CONTAINER_DETAIL_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/container/detail/mutex.hpp>
  21. #include <boost/container/detail/pool_common_alloc.hpp>
  22. #include <boost/container/detail/node_pool_impl.hpp>
  23. #include <boost/container/detail/mutex.hpp>
  24. #include <boost/move/utility_core.hpp>
  25. #include <cstddef>
  26. #include <cassert>
  27. namespace boost {
  28. namespace container {
  29. namespace dtl {
  30. //!Pooled memory allocator using single segregated storage. Includes
  31. //!a reference count but the class does not delete itself, this is
  32. //!responsibility of user classes. Node size (NodeSize) and the number of
  33. //!nodes allocated per block (NodesPerBlock) are known at compile time
  34. template< std::size_t NodeSize, std::size_t NodesPerBlock >
  35. class private_node_pool
  36. //Inherit from the implementation to avoid template bloat
  37. : public boost::container::dtl::
  38. private_node_pool_impl<fake_segment_manager>
  39. {
  40. typedef boost::container::dtl::
  41. private_node_pool_impl<fake_segment_manager> base_t;
  42. //Non-copyable
  43. private_node_pool(const private_node_pool &);
  44. private_node_pool &operator=(const private_node_pool &);
  45. public:
  46. typedef typename base_t::multiallocation_chain multiallocation_chain;
  47. static const std::size_t nodes_per_block = NodesPerBlock;
  48. //!Constructor from a segment manager. Never throws
  49. private_node_pool()
  50. : base_t(0, NodeSize, NodesPerBlock)
  51. {}
  52. };
  53. template< std::size_t NodeSize
  54. , std::size_t NodesPerBlock
  55. >
  56. class shared_node_pool
  57. : public private_node_pool<NodeSize, NodesPerBlock>
  58. {
  59. private:
  60. typedef private_node_pool<NodeSize, NodesPerBlock> private_node_allocator_t;
  61. public:
  62. typedef typename private_node_allocator_t::free_nodes_t free_nodes_t;
  63. typedef typename private_node_allocator_t::multiallocation_chain multiallocation_chain;
  64. //!Constructor from a segment manager. Never throws
  65. shared_node_pool()
  66. : private_node_allocator_t(){}
  67. //!Destructor. Deallocates all allocated blocks. Never throws
  68. ~shared_node_pool()
  69. {}
  70. //!Allocates array of count elements. Can throw std::bad_alloc
  71. void *allocate_node()
  72. {
  73. //-----------------------
  74. scoped_lock<default_mutex> guard(mutex_);
  75. //-----------------------
  76. return private_node_allocator_t::allocate_node();
  77. }
  78. //!Deallocates an array pointed by ptr. Never throws
  79. void deallocate_node(void *ptr)
  80. {
  81. //-----------------------
  82. scoped_lock<default_mutex> guard(mutex_);
  83. //-----------------------
  84. private_node_allocator_t::deallocate_node(ptr);
  85. }
  86. //!Allocates a singly linked list of n nodes ending in null pointer.
  87. //!can throw std::bad_alloc
  88. void allocate_nodes(const std::size_t n, multiallocation_chain &chain)
  89. {
  90. //-----------------------
  91. scoped_lock<default_mutex> guard(mutex_);
  92. //-----------------------
  93. return private_node_allocator_t::allocate_nodes(n, chain);
  94. }
  95. void deallocate_nodes(multiallocation_chain &chain)
  96. {
  97. //-----------------------
  98. scoped_lock<default_mutex> guard(mutex_);
  99. //-----------------------
  100. private_node_allocator_t::deallocate_nodes(chain);
  101. }
  102. //!Deallocates all the free blocks of memory. Never throws
  103. void deallocate_free_blocks()
  104. {
  105. //-----------------------
  106. scoped_lock<default_mutex> guard(mutex_);
  107. //-----------------------
  108. private_node_allocator_t::deallocate_free_blocks();
  109. }
  110. //!Deallocates all blocks. Never throws
  111. void purge_blocks()
  112. {
  113. //-----------------------
  114. scoped_lock<default_mutex> guard(mutex_);
  115. //-----------------------
  116. private_node_allocator_t::purge_blocks();
  117. }
  118. std::size_t num_free_nodes()
  119. {
  120. //-----------------------
  121. scoped_lock<default_mutex> guard(mutex_);
  122. //-----------------------
  123. return private_node_allocator_t::num_free_nodes();
  124. }
  125. private:
  126. default_mutex mutex_;
  127. };
  128. } //namespace dtl {
  129. } //namespace container {
  130. } //namespace boost {
  131. #include <boost/container/detail/config_end.hpp>
  132. #endif //#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_HPP