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_SYNCHRONIZED_POOL_RESOURCE_HPP 12 #define BOOST_CONTAINER_PMR_SYNCHRONIZED_POOL_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/pmr/memory_resource.hpp> 22 #include <boost/container/detail/pool_resource.hpp> 23 #include <boost/container/detail/thread_mutex.hpp> 24 25 #include <cstddef> 26 27 namespace boost { 28 namespace container { 29 namespace pmr { 30 31 //! A synchronized_pool_resource is a general-purpose memory resources having 32 //! the following qualities: 33 //! 34 //! - Each resource owns the allocated memory, and frees it on destruction, 35 //! even if deallocate has not been called for some of the allocated blocks. 36 //! 37 //! - A pool resource consists of a collection of pools, serving 38 //! requests for different block sizes. Each individual pool manages a 39 //! collection of chunks that are in turn divided into blocks of uniform size, 40 //! returned via calls to do_allocate. Each call to do_allocate(size, alignment) 41 //! is dispatched to the pool serving the smallest blocks accommodating at 42 //! least size bytes. 43 //! 44 //! - When a particular pool is exhausted, allocating a block from that pool 45 //! results in the allocation of an additional chunk of memory from the upstream 46 //! allocator (supplied at construction), thus replenishing the pool. With 47 //! each successive replenishment, the chunk size obtained increases 48 //! geometrically. [ Note: By allocating memory in chunks, the pooling strategy 49 //! increases the chance that consecutive allocations will be close together 50 //! in memory. - end note ] 51 //! 52 //! - Allocation requests that exceed the largest block size of any pool are 53 //! fulfilled directly from the upstream allocator. 54 //! 55 //! - A pool_options struct may be passed to the pool resource constructors to 56 //! tune the largest block size and the maximum chunk size. 57 //! 58 //! A synchronized_pool_resource may be accessed from multiple threads without 59 //! external synchronization and may have thread-specific pools to reduce 60 //! synchronization costs. 61 class BOOST_CONTAINER_DECL synchronized_pool_resource 62 : public memory_resource 63 { 64 dtl::thread_mutex m_mut; 65 pool_resource m_pool_resource; 66 67 public: 68 69 //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::unsynchronized_pool_resource(const pool_options&,memory_resource*) 70 synchronized_pool_resource(const pool_options& opts, memory_resource* upstream) BOOST_NOEXCEPT; 71 72 //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::unsynchronized_pool_resource() 73 synchronized_pool_resource() BOOST_NOEXCEPT; 74 75 //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::unsynchronized_pool_resource(memory_resource*) 76 explicit synchronized_pool_resource(memory_resource* upstream) BOOST_NOEXCEPT; 77 78 //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::unsynchronized_pool_resource(const pool_options&) 79 explicit synchronized_pool_resource(const pool_options& opts) BOOST_NOEXCEPT; 80 81 #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) 82 synchronized_pool_resource(const synchronized_pool_resource&) = delete; 83 synchronized_pool_resource operator=(const synchronized_pool_resource&) = delete; 84 #else 85 private: 86 synchronized_pool_resource (const synchronized_pool_resource&); 87 synchronized_pool_resource operator=(const synchronized_pool_resource&); 88 public: 89 #endif 90 91 //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::~unsynchronized_pool_resource() 92 ~synchronized_pool_resource() BOOST_OVERRIDE; 93 94 //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::release() 95 void release(); 96 97 //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::upstream_resource()const 98 memory_resource* upstream_resource() const; 99 100 //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::options()const 101 pool_options options() const; 102 103 protected: 104 105 //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::do_allocate() 106 void* do_allocate(std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE; 107 108 //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::do_deallocate(void*,std::size_t,std::size_t) 109 void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) BOOST_OVERRIDE; 110 111 //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::do_is_equal(const memory_resource&)const 112 bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT BOOST_OVERRIDE; 113 114 //Non-standard observers 115 public: 116 117 //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::pool_count() 118 std::size_t pool_count() const; 119 120 //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::pool_index(std::size_t)const 121 std::size_t pool_index(std::size_t bytes) const; 122 123 //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::pool_next_blocks_per_chunk(std::size_t)const 124 std::size_t pool_next_blocks_per_chunk(std::size_t pool_idx) const; 125 126 //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::pool_block(std::size_t)const 127 std::size_t pool_block(std::size_t pool_idx) const; 128 129 //! @copydoc ::boost::container::pmr::unsynchronized_pool_resource::pool_cached_blocks(std::size_t)const 130 std::size_t pool_cached_blocks(std::size_t pool_idx) const; 131 }; 132 133 } //namespace pmr { 134 } //namespace container { 135 } //namespace boost { 136 137 #include <boost/container/detail/config_end.hpp> 138 139 #endif //BOOST_CONTAINER_PMR_SYNCHRONIZED_POOL_RESOURCE_HPP 140