|
||||
File indexing completed on 2025-01-30 09:34:56
0001 ////////////////////////////////////////////////////////////////////////////// 0002 // 0003 // (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost 0004 // Software License, Version 1.0. (See accompanying file 0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 0006 // 0007 // See http://www.boost.org/libs/container for documentation. 0008 // 0009 ////////////////////////////////////////////////////////////////////////////// 0010 0011 #ifndef BOOST_CONTAINER_PMR_MONOTONIC_BUFFER_RESOURCE_HPP 0012 #define BOOST_CONTAINER_PMR_MONOTONIC_BUFFER_RESOURCE_HPP 0013 0014 #if defined (_MSC_VER) 0015 # pragma once 0016 #endif 0017 0018 #include <boost/container/detail/config_begin.hpp> 0019 #include <boost/container/detail/workaround.hpp> 0020 #include <boost/container/detail/auto_link.hpp> 0021 #include <boost/container/container_fwd.hpp> 0022 #include <boost/container/pmr/memory_resource.hpp> 0023 #include <boost/container/detail/block_slist.hpp> 0024 0025 #include <cstddef> 0026 0027 namespace boost { 0028 namespace container { 0029 namespace pmr { 0030 0031 //! A monotonic_buffer_resource is a special-purpose memory resource intended for 0032 //! very fast memory allocations in situations where memory is used to build up a 0033 //! few objects and then is released all at once when the memory resource object 0034 //! is destroyed. It has the following qualities: 0035 //! 0036 //! - A call to deallocate has no effect, thus the amount of memory consumed 0037 //! increases monotonically until the resource is destroyed. 0038 //! 0039 //! - The program can supply an initial buffer, which the allocator uses to satisfy 0040 //! memory requests. 0041 //! 0042 //! - When the initial buffer (if any) is exhausted, it obtains additional buffers 0043 //! from an upstream memory resource supplied at construction. Each additional 0044 //! buffer is larger than the previous one, following a geometric progression. 0045 //! 0046 //! - It is intended for access from one thread of control at a time. Specifically, 0047 //! calls to allocate and deallocate do not synchronize with one another. 0048 //! 0049 //! - It owns the allocated memory and frees it on destruction, even if deallocate has 0050 //! not been called for some of the allocated blocks. 0051 class BOOST_CONTAINER_DECL monotonic_buffer_resource 0052 : public memory_resource 0053 { 0054 block_slist m_memory_blocks; 0055 void * m_current_buffer; 0056 std::size_t m_current_buffer_size; 0057 std::size_t m_next_buffer_size; 0058 void * const m_initial_buffer; 0059 std::size_t const m_initial_buffer_size; 0060 0061 /// @cond 0062 void increase_next_buffer(); 0063 void increase_next_buffer_at_least_to(std::size_t minimum_size); 0064 void *allocate_from_current(std::size_t aligner, std::size_t bytes); 0065 /// @endcond 0066 0067 public: 0068 0069 //! The number of bytes that will be requested by the default in the first call 0070 //! to the upstream allocator 0071 //! 0072 //! <b>Note</b>: Non-standard extension. 0073 static const std::size_t initial_next_buffer_size = 32u*sizeof(void*); 0074 0075 //! <b>Requires</b>: `upstream` shall be the address of a valid memory resource or `nullptr` 0076 //! 0077 //! <b>Effects</b>: If `upstream` is not nullptr, sets the internal resource to `upstream`, 0078 //! to get_default_resource() otherwise. 0079 //! Sets the internal `current_buffer` to `nullptr` and the internal `next_buffer_size` to an 0080 //! implementation-defined size. 0081 explicit monotonic_buffer_resource(memory_resource* upstream = 0) BOOST_NOEXCEPT; 0082 0083 //! <b>Requires</b>: `upstream` shall be the address of a valid memory resource or `nullptr` 0084 //! and `initial_size` shall be greater than zero. 0085 //! 0086 //! <b>Effects</b>: If `upstream` is not nullptr, sets the internal resource to `upstream`, 0087 //! to get_default_resource() otherwise. Sets the internal `current_buffer` to `nullptr` and 0088 //! `next_buffer_size` to at least `initial_size`. 0089 explicit monotonic_buffer_resource(std::size_t initial_size, memory_resource* upstream = 0) BOOST_NOEXCEPT; 0090 0091 //! <b>Requires</b>: `upstream` shall be the address of a valid memory resource or `nullptr`, 0092 //! `buffer_size` shall be no larger than the number of bytes in buffer. 0093 //! 0094 //! <b>Effects</b>: If `upstream` is not nullptr, sets the internal resource to `upstream`, 0095 //! to get_default_resource() otherwise. Sets the internal `current_buffer` to `buffer`, 0096 //! and `next_buffer_size` to `buffer_size` (but not less than an implementation-defined size), 0097 //! then increases `next_buffer_size` by an implementation-defined growth factor (which need not be integral). 0098 monotonic_buffer_resource(void* buffer, std::size_t buffer_size, memory_resource* upstream = 0) BOOST_NOEXCEPT; 0099 0100 #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) 0101 monotonic_buffer_resource(const monotonic_buffer_resource&) = delete; 0102 monotonic_buffer_resource operator=(const monotonic_buffer_resource&) = delete; 0103 #else 0104 private: 0105 monotonic_buffer_resource (const monotonic_buffer_resource&); 0106 monotonic_buffer_resource operator=(const monotonic_buffer_resource&); 0107 public: 0108 #endif 0109 0110 //! <b>Effects</b>: Calls 0111 //! `this->release()`. 0112 ~monotonic_buffer_resource() BOOST_OVERRIDE; 0113 0114 //! <b>Effects</b>: `upstream_resource()->deallocate()` as necessary to release all allocated memory. 0115 //! [Note: memory is released back to `upstream_resource()` even if some blocks that were allocated 0116 //! from this have not been deallocated from this. - end note] 0117 void release() BOOST_NOEXCEPT; 0118 0119 //! <b>Returns</b>: The value of 0120 //! the internal resource. 0121 memory_resource* upstream_resource() const BOOST_NOEXCEPT; 0122 0123 //! <b>Returns</b>: 0124 //! The number of bytes of storage available for the specified alignment and 0125 //! the number of bytes wasted due to the requested alignment. 0126 //! 0127 //! <b>Note</b>: Non-standard extension. 0128 std::size_t remaining_storage(std::size_t alignment, std::size_t &wasted_due_to_alignment) const BOOST_NOEXCEPT; 0129 0130 //! <b>Returns</b>: 0131 //! The number of bytes of storage available for the specified alignment. 0132 //! 0133 //! <b>Note</b>: Non-standard extension. 0134 std::size_t remaining_storage(std::size_t alignment = 1u) const BOOST_NOEXCEPT; 0135 0136 //! <b>Returns</b>: 0137 //! The address pointing to the start of the current free storage. 0138 //! 0139 //! <b>Note</b>: Non-standard extension. 0140 const void *current_buffer() const BOOST_NOEXCEPT; 0141 0142 //! <b>Returns</b>: 0143 //! The number of bytes that will be requested for the next buffer once the 0144 //! current one is exhausted. 0145 //! 0146 //! <b>Note</b>: Non-standard extension. 0147 std::size_t next_buffer_size() const BOOST_NOEXCEPT; 0148 0149 protected: 0150 0151 //! <b>Returns</b>: A pointer to allocated storage with a size of at least `bytes`. The size 0152 //! and alignment of the allocated memory shall meet the requirements for a class derived 0153 //! from `memory_resource`. 0154 //! 0155 //! <b>Effects</b>: If the unused space in the internal `current_buffer` can fit a block with the specified 0156 //! bytes and alignment, then allocate the return block from the internal `current_buffer`; otherwise sets 0157 //! the internal `current_buffer` to `upstream_resource()->allocate(n, m)`, where `n` is not less than 0158 //! `max(bytes, next_buffer_size)` and `m` is not less than alignment, and increase 0159 //! `next_buffer_size` by an implementation-defined growth factor (which need not be integral), 0160 //! then allocate the return block from the newly-allocated internal `current_buffer`. 0161 //! 0162 //! <b>Throws</b>: Nothing unless `upstream_resource()->allocate()` throws. 0163 virtual void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE; 0164 0165 //! <b>Effects</b>: None 0166 //! 0167 //! <b>Throws</b>: Nothing 0168 //! 0169 //! <b>Remarks</b>: Memory used by this resource increases monotonically until its destruction. 0170 virtual void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_NOEXCEPT BOOST_OVERRIDE; 0171 0172 //! <b>Returns</b>: 0173 //! `this == dynamic_cast<const monotonic_buffer_resource*>(&other)`. 0174 virtual bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT BOOST_OVERRIDE; 0175 }; 0176 0177 } //namespace pmr { 0178 } //namespace container { 0179 } //namespace boost { 0180 0181 #include <boost/container/detail/config_end.hpp> 0182 0183 #endif //BOOST_CONTAINER_PMR_MONOTONIC_BUFFER_RESOURCE_HPP
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |