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