]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/container/pmr/monotonic_buffer_resource.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / container / pmr / monotonic_buffer_resource.hpp
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2015-2015. 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_PMR_MONOTONIC_BUFFER_RESOURCE_HPP
12 #define BOOST_CONTAINER_PMR_MONOTONIC_BUFFER_RESOURCE_HPP
13
14 #if defined (_MSC_VER)
15 # pragma once
16 #endif
17
18 #include <boost/container/detail/config_begin.hpp>
19 #include <boost/container/detail/workaround.hpp>
20 #include <boost/container/detail/auto_link.hpp>
21 #include <boost/container/container_fwd.hpp>
22 #include <boost/container/pmr/memory_resource.hpp>
23 #include <boost/container/detail/block_slist.hpp>
24
25 #include <cstddef>
26
27 namespace boost {
28 namespace container {
29 namespace pmr {
30
31 //! A monotonic_buffer_resource is a special-purpose memory resource intended for
32 //! very fast memory allocations in situations where memory is used to build up a
33 //! few objects and then is released all at once when the memory resource object
34 //! is destroyed. It has the following qualities:
35 //!
36 //! - A call to deallocate has no effect, thus the amount of memory consumed
37 //! increases monotonically until the resource is destroyed.
38 //!
39 //! - The program can supply an initial buffer, which the allocator uses to satisfy
40 //! memory requests.
41 //!
42 //! - When the initial buffer (if any) is exhausted, it obtains additional buffers
43 //! from an upstream memory resource supplied at construction. Each additional
44 //! buffer is larger than the previous one, following a geometric progression.
45 //!
46 //! - It is intended for access from one thread of control at a time. Specifically,
47 //! calls to allocate and deallocate do not synchronize with one another.
48 //!
49 //! - It owns the allocated memory and frees it on destruction, even if deallocate has
50 //! not been called for some of the allocated blocks.
51 class BOOST_CONTAINER_DECL monotonic_buffer_resource
52 : public memory_resource
53 {
54 block_slist m_memory_blocks;
55 void * m_current_buffer;
56 std::size_t m_current_buffer_size;
57 std::size_t m_next_buffer_size;
58 void * const m_initial_buffer;
59 std::size_t const m_initial_buffer_size;
60
61 /// @cond
62 void increase_next_buffer();
63 void increase_next_buffer_at_least_to(std::size_t minimum_size);
64 void *allocate_from_current(std::size_t aligner, std::size_t bytes);
65 /// @endcond
66
67 public:
68
69 //! The number of bytes that will be requested by the default in the first call
70 //! to the upstream allocator
71 //!
72 //! <b>Note</b>: Non-standard extension.
73 static const std::size_t initial_next_buffer_size = 32u*sizeof(void*);
74
75 //! <b>Requires</b>: `upstream` shall be the address of a valid memory resource or `nullptr`
76 //!
77 //! <b>Effects</b>: If `upstream` is not nullptr, sets the internal resource to `upstream`,
78 //! to get_default_resource() otherwise.
79 //! Sets the internal `current_buffer` to `nullptr` and the internal `next_buffer_size` to an
80 //! implementation-defined size.
81 explicit monotonic_buffer_resource(memory_resource* upstream = 0) BOOST_NOEXCEPT;
82
83 //! <b>Requires</b>: `upstream` shall be the address of a valid memory resource or `nullptr`
84 //! and `initial_size` shall be greater than zero.
85 //!
86 //! <b>Effects</b>: If `upstream` is not nullptr, sets the internal resource to `upstream`,
87 //! to get_default_resource() otherwise. Sets the internal `current_buffer` to `nullptr` and
88 //! `next_buffer_size` to at least `initial_size`.
89 explicit monotonic_buffer_resource(std::size_t initial_size, memory_resource* upstream = 0) BOOST_NOEXCEPT;
90
91 //! <b>Requires</b>: `upstream` shall be the address of a valid memory resource or `nullptr`,
92 //! `buffer_size` shall be no larger than the number of bytes in buffer.
93 //!
94 //! <b>Effects</b>: If `upstream` is not nullptr, sets the internal resource to `upstream`,
95 //! to get_default_resource() otherwise. Sets the internal `current_buffer` to `buffer`,
96 //! and `next_buffer_size` to `buffer_size` (but not less than an implementation-defined size),
97 //! then increases `next_buffer_size` by an implementation-defined growth factor (which need not be integral).
98 monotonic_buffer_resource(void* buffer, std::size_t buffer_size, memory_resource* upstream = 0) BOOST_NOEXCEPT;
99
100 #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
101 monotonic_buffer_resource(const monotonic_buffer_resource&) = delete;
102 monotonic_buffer_resource operator=(const monotonic_buffer_resource&) = delete;
103 #else
104 private:
105 monotonic_buffer_resource (const monotonic_buffer_resource&);
106 monotonic_buffer_resource operator=(const monotonic_buffer_resource&);
107 public:
108 #endif
109
110 //! <b>Effects</b>: Calls
111 //! `this->release()`.
112 virtual ~monotonic_buffer_resource();
113
114 //! <b>Effects</b>: `upstream_resource()->deallocate()` as necessary to release all allocated memory.
115 //! [Note: memory is released back to `upstream_resource()` even if some blocks that were allocated
116 //! from this have not been deallocated from this. - end note]
117 void release() BOOST_NOEXCEPT;
118
119 //! <b>Returns</b>: The value of
120 //! the internal resource.
121 memory_resource* upstream_resource() const BOOST_NOEXCEPT;
122
123 //! <b>Returns</b>:
124 //! The number of bytes of storage available for the specified alignment and
125 //! the number of bytes wasted due to the requested alignment.
126 //!
127 //! <b>Note</b>: Non-standard extension.
128 std::size_t remaining_storage(std::size_t alignment, std::size_t &wasted_due_to_alignment) const BOOST_NOEXCEPT;
129
130 //! <b>Returns</b>:
131 //! The number of bytes of storage available for the specified alignment.
132 //!
133 //! <b>Note</b>: Non-standard extension.
134 std::size_t remaining_storage(std::size_t alignment = 1u) const BOOST_NOEXCEPT;
135
136 //! <b>Returns</b>:
137 //! The address pointing to the start of the current free storage.
138 //!
139 //! <b>Note</b>: Non-standard extension.
140 const void *current_buffer() const BOOST_NOEXCEPT;
141
142 //! <b>Returns</b>:
143 //! The number of bytes that will be requested for the next buffer once the
144 //! current one is exhausted.
145 //!
146 //! <b>Note</b>: Non-standard extension.
147 std::size_t next_buffer_size() const BOOST_NOEXCEPT;
148
149 protected:
150
151 //! <b>Returns</b>: A pointer to allocated storage with a size of at least `bytes`. The size
152 //! and alignment of the allocated memory shall meet the requirements for a class derived
153 //! from `memory_resource`.
154 //!
155 //! <b>Effects</b>: If the unused space in the internal `current_buffer` can fit a block with the specified
156 //! bytes and alignment, then allocate the return block from the internal `current_buffer`; otherwise sets
157 //! the internal `current_buffer` to `upstream_resource()->allocate(n, m)`, where `n` is not less than
158 //! `max(bytes, next_buffer_size)` and `m` is not less than alignment, and increase
159 //! `next_buffer_size` by an implementation-defined growth factor (which need not be integral),
160 //! then allocate the return block from the newly-allocated internal `current_buffer`.
161 //!
162 //! <b>Throws</b>: Nothing unless `upstream_resource()->allocate()` throws.
163 virtual void* do_allocate(std::size_t bytes, std::size_t alignment);
164
165 //! <b>Effects</b>: None
166 //!
167 //! <b>Throws</b>: Nothing
168 //!
169 //! <b>Remarks</b>: Memory used by this resource increases monotonically until its destruction.
170 virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_NOEXCEPT;
171
172 //! <b>Returns</b>:
173 //! `this == dynamic_cast<const monotonic_buffer_resource*>(&other)`.
174 virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT;
175 };
176
177 } //namespace pmr {
178 } //namespace container {
179 } //namespace boost {
180
181 #include <boost/container/detail/config_end.hpp>
182
183 #endif //BOOST_CONTAINER_PMR_MONOTONIC_BUFFER_RESOURCE_HPP