Back to home page

EIC code displayed by LXR

 
 

    


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