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