summaryrefslogtreecommitdiff
path: root/boost/container/detail/adaptive_node_pool.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/container/detail/adaptive_node_pool.hpp')
-rw-r--r--boost/container/detail/adaptive_node_pool.hpp162
1 files changed, 162 insertions, 0 deletions
diff --git a/boost/container/detail/adaptive_node_pool.hpp b/boost/container/detail/adaptive_node_pool.hpp
new file mode 100644
index 0000000000..4e7375412b
--- /dev/null
+++ b/boost/container/detail/adaptive_node_pool.hpp
@@ -0,0 +1,162 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_HPP
+#define BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif
+
+#include <boost/container/detail/config_begin.hpp>
+#include <boost/container/detail/workaround.hpp>
+
+#include <boost/intrusive/set.hpp>
+#include <boost/aligned_storage.hpp>
+#include <boost/container/detail/alloc_lib_auto_link.hpp>
+#include <boost/container/detail/multiallocation_chain.hpp>
+#include <boost/container/detail/pool_common_alloc.hpp>
+#include <boost/container/detail/mutex.hpp>
+#include <boost/container/detail/adaptive_node_pool_impl.hpp>
+#include <boost/container/detail/multiallocation_chain.hpp>
+#include <cstddef>
+#include <cmath>
+#include <cassert>
+
+
+namespace boost {
+namespace container {
+namespace container_detail {
+
+template<bool AlignOnly>
+struct select_private_adaptive_node_pool_impl
+{
+ typedef boost::container::container_detail::
+ private_adaptive_node_pool_impl
+ < fake_segment_manager
+ , unsigned(AlignOnly)*::boost::container::adaptive_pool_flag::align_only
+ | ::boost::container::adaptive_pool_flag::size_ordered | ::boost::container::adaptive_pool_flag::address_ordered
+ > type;
+};
+
+//!Pooled memory allocator using an smart adaptive pool. Includes
+//!a reference count but the class does not delete itself, this is
+//!responsibility of user classes. Node size (NodeSize) and the number of
+//!nodes allocated per block (NodesPerBlock) are known at compile time.
+template< std::size_t NodeSize
+ , std::size_t NodesPerBlock
+ , std::size_t MaxFreeBlocks
+ , std::size_t OverheadPercent
+ >
+class private_adaptive_node_pool
+ : public select_private_adaptive_node_pool_impl<(OverheadPercent == 0)>::type
+{
+ typedef typename select_private_adaptive_node_pool_impl<OverheadPercent == 0>::type base_t;
+ //Non-copyable
+ private_adaptive_node_pool(const private_adaptive_node_pool &);
+ private_adaptive_node_pool &operator=(const private_adaptive_node_pool &);
+
+ public:
+ typedef typename base_t::multiallocation_chain multiallocation_chain;
+ static const std::size_t nodes_per_block = NodesPerBlock;
+
+ //!Constructor. Never throws
+ private_adaptive_node_pool()
+ : base_t(0
+ , NodeSize
+ , NodesPerBlock
+ , MaxFreeBlocks
+ , (unsigned char)OverheadPercent)
+ {}
+};
+
+//!Pooled memory allocator using adaptive pool. Includes
+//!a reference count but the class does not delete itself, this is
+//!responsibility of user classes. Node size (NodeSize) and the number of
+//!nodes allocated per block (NodesPerBlock) are known at compile time
+template< std::size_t NodeSize
+ , std::size_t NodesPerBlock
+ , std::size_t MaxFreeBlocks
+ , std::size_t OverheadPercent
+ >
+class shared_adaptive_node_pool
+ : public private_adaptive_node_pool
+ <NodeSize, NodesPerBlock, MaxFreeBlocks, OverheadPercent>
+{
+ private:
+ typedef private_adaptive_node_pool
+ <NodeSize, NodesPerBlock, MaxFreeBlocks, OverheadPercent> private_node_allocator_t;
+ public:
+ typedef typename private_node_allocator_t::multiallocation_chain multiallocation_chain;
+
+ //!Constructor. Never throws
+ shared_adaptive_node_pool()
+ : private_node_allocator_t(){}
+
+ //!Destructor. Deallocates all allocated blocks. Never throws
+ ~shared_adaptive_node_pool()
+ {}
+
+ //!Allocates array of count elements. Can throw std::bad_alloc
+ void *allocate_node()
+ {
+ //-----------------------
+ scoped_lock<default_mutex> guard(mutex_);
+ //-----------------------
+ return private_node_allocator_t::allocate_node();
+ }
+
+ //!Deallocates an array pointed by ptr. Never throws
+ void deallocate_node(void *ptr)
+ {
+ //-----------------------
+ scoped_lock<default_mutex> guard(mutex_);
+ //-----------------------
+ private_node_allocator_t::deallocate_node(ptr);
+ }
+
+ //!Allocates a singly linked list of n nodes ending in null pointer.
+ //!can throw std::bad_alloc
+ void allocate_nodes(const std::size_t n, multiallocation_chain &chain)
+ {
+ //-----------------------
+ scoped_lock<default_mutex> guard(mutex_);
+ //-----------------------
+ return private_node_allocator_t::allocate_nodes(n, chain);
+ }
+
+ void deallocate_nodes(multiallocation_chain &chain)
+ {
+ //-----------------------
+ scoped_lock<default_mutex> guard(mutex_);
+ //-----------------------
+ private_node_allocator_t::deallocate_nodes(chain);
+ }
+
+ //!Deallocates all the free blocks of memory. Never throws
+ void deallocate_free_blocks()
+ {
+ //-----------------------
+ scoped_lock<default_mutex> guard(mutex_);
+ //-----------------------
+ private_node_allocator_t::deallocate_free_blocks();
+ }
+
+ private:
+ default_mutex mutex_;
+};
+
+} //namespace container_detail {
+} //namespace container {
+} //namespace boost {
+
+#include <boost/container/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_HPP