Line data Source code
1 : // The libMesh Finite Element Library. 2 : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 3 : 4 : // This library is free software; you can redistribute it and/or 5 : // modify it under the terms of the GNU Lesser General Public 6 : // License as published by the Free Software Foundation; either 7 : // version 2.1 of the License, or (at your option) any later version. 8 : 9 : // This library is distributed in the hope that it will be useful, 10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 : // Lesser General Public License for more details. 13 : 14 : // You should have received a copy of the GNU Lesser General Public 15 : // License along with this library; if not, write to the Free Software 16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 : 18 : #ifndef LIBMESH_POOL_ALLOCATOR_H 19 : #define LIBMESH_POOL_ALLOCATOR_H 20 : 21 : #include "libmesh/libmesh_config.h" 22 : 23 : #ifdef LIBMESH_HAVE_BOOST 24 : // See: http://stackoverflow.com/questions/17000542/boost-pool-can-i-wean-it-from-boost-system 25 : #define BOOST_POOL_NO_MT // disable multi-threading 26 : #define BOOST_THREAD_MUTEX_HPP // define the #include-guard to disable the header 27 : # include <boost/pool/pool.hpp> 28 : # include <boost/pool/object_pool.hpp> 29 : # include <boost/pool/pool_alloc.hpp> 30 : #endif 31 : 32 : #include <memory> // std::allocator 33 : 34 : namespace libMesh 35 : { 36 : // If Boost is enabled, wrappers to use their allocators. 37 : #ifdef LIBMESH_HAVE_BOOST 38 : 39 : /** 40 : * An allocator which can be used in standard containers. Uses 41 : * pool-based memory allocation to efficiently allocate many small 42 : * objects. 43 : * 44 : * \note Object destruction returns memory to the pool rather than 45 : * deallocate it. It must be explicitly deallocated prior to program 46 : * termination. 47 : * 48 : * \author Benjamin S. Kirk 49 : * \date 2011 50 : * \brief Boost-derived allocator that can be used with std::containers. 51 : */ 52 : template <typename T> 53 : class PoolAllocator : public boost::pool_allocator<T> 54 : { 55 : public: 56 : 57 : /** 58 : * Methods required for copy construction of containers using this allocator. 59 : */ 60 : template<typename U> 61 : struct rebind { 62 : typedef PoolAllocator<U> other; 63 : }; 64 : 65 : 66 : PoolAllocator() : 67 : boost::pool_allocator<T>() 68 : {} 69 : 70 : template <typename U> 71 : PoolAllocator(const PoolAllocator<U> & o) : 72 : boost::pool_allocator<T>(o) 73 : {} 74 : 75 : /** 76 : * Frees every memory block that doesn't have any allocated chunks. 77 : * \returns \p true if at least one memory block was freed. 78 : */ 79 : static bool release_memory () 80 : { 81 : return boost::singleton_pool<boost::pool_allocator_tag, sizeof(T)>::release_memory(); 82 : } 83 : 84 : /** 85 : * Frees every memory block. This function invalidates any pointers previously returned 86 : * by allocation functions. 87 : * 88 : * \returns \p true if at least one memory block was freed. 89 : */ 90 : static bool purge_memory () 91 : { 92 : return boost::singleton_pool<boost::pool_allocator_tag, sizeof(T)>::purge_memory(); 93 : } 94 : }; 95 : 96 : 97 : 98 : /** 99 : * An allocator which can be used in standard containers. Uses 100 : * pool-based memory allocation to efficiently allocate many small 101 : * objects. 102 : * 103 : * \note Object destruction returns memory to the pool rather than 104 : * deallocate it. It must be explicitly deallocated prior to program 105 : * termination. 106 : * 107 : * \author Benjamin S. Kirk 108 : * \date 2011 109 : * \brief Boost-derived allocator that can be used with std::containers. 110 : */ 111 : template <typename T> 112 : class FastPoolAllocator : public boost::fast_pool_allocator<T> 113 : { 114 : public: 115 : 116 : /** 117 : * Methods required for copy construction of containers using this allocator. 118 : */ 119 : template<typename U> 120 : struct rebind { 121 : typedef FastPoolAllocator<U> other; 122 : }; 123 : 124 : 125 : FastPoolAllocator() : 126 : boost::fast_pool_allocator<T>() 127 : {} 128 : 129 : template <typename U> 130 : FastPoolAllocator(const FastPoolAllocator<U> & o) : 131 : boost::fast_pool_allocator<T>(o) 132 : {} 133 : 134 : 135 : /** 136 : * Frees every memory block that doesn't have any allocated chunks. 137 : * \returns \p true if at least one memory block was freed. 138 : */ 139 : static bool release_memory () 140 : { 141 : return boost::singleton_pool<boost::fast_pool_allocator_tag, sizeof(T)>::release_memory(); 142 : } 143 : 144 : /** 145 : * Frees every memory block. This function invalidates any pointers previously returned 146 : * by allocation functions. 147 : * 148 : * \returns \p true if at least one memory block was freed. 149 : */ 150 : static bool purge_memory () 151 : { 152 : return boost::singleton_pool<boost::fast_pool_allocator_tag, sizeof(T)>::purge_memory(); 153 : } 154 : }; 155 : 156 : // Otherwise fall back to std::allocator<>. 157 : #else 158 : 159 : /** 160 : * An allocator which can be used in standard containers. 161 : * A wrapper for \p std::allocator<> when Boost is not available. 162 : * 163 : * \author Benjamin S. Kirk 164 : * \date 2011 165 : * \brief PoolAllocator is std::allocator when Boost is not available. 166 : */ 167 : template <typename T> 168 : class PoolAllocator : public std::allocator<T> 169 : { 170 : public: 171 : 172 : /** 173 : * Methods required for copy construction of containers using this allocator. 174 : */ 175 : template<typename U> 176 : struct rebind { 177 : typedef PoolAllocator<U> other; 178 : }; 179 : 180 : PoolAllocator() : 181 : std::allocator<T>() 182 : {} 183 : 184 : template <typename U> 185 : PoolAllocator(const PoolAllocator<U> & o) : 186 : std::allocator<T>(o) 187 : {} 188 : 189 : /** 190 : * Frees every memory block that doesn't have any allocated chunks. 191 : * \returns \p true if at least one memory block was freed. 192 : */ 193 : static bool release_memory () { /* no-op for std::allocator<> - already freed. */ return false; } 194 : 195 : /** 196 : * Frees every memory block. This function invalidates any pointers previously returned 197 : * by allocation functions. 198 : * 199 : * \returns \p true if at least one memory block was freed. 200 : */ 201 : static bool purge_memory () { /* no-op for std::allocator<> - already freed. */ return false; } 202 : }; 203 : 204 : 205 : 206 : /** 207 : * An allocator which can be used in standard containers. 208 : * A wrapper for \p std::allocator<> when Boost is not available. 209 : * 210 : * \author Benjamin S. Kirk 211 : * \date 2011 212 : * \brief FastPoolAllocator is std::allocator when Boost is not available. 213 : */ 214 : template <typename T> 215 : class FastPoolAllocator : public std::allocator<T> 216 : { 217 : public: 218 : 219 : /** 220 : * Methods required for copy construction of containers using this allocator. 221 : */ 222 : template<typename U> 223 : struct rebind { 224 : typedef FastPoolAllocator<U> other; 225 : }; 226 : 227 528 : FastPoolAllocator() : 228 528 : std::allocator<T>() 229 528 : {} 230 : 231 : template <typename U> 232 : FastPoolAllocator(const FastPoolAllocator<U> & o) : 233 : std::allocator<T>(o) 234 : {} 235 : 236 : /** 237 : * Frees every memory block that doesn't have any allocated chunks. 238 : * \returns \p true if at least one memory block was freed. 239 : */ 240 : static bool release_memory () { /* no-op for std::allocator<> - already freed. */ return false; } 241 : 242 : /** 243 : * Frees every memory block. This function invalidates any pointers previously returned 244 : * by allocation functions. 245 : * 246 : * \returns \p true if at least one memory block was freed. 247 : */ 248 : static bool purge_memory () { /* no-op for std::allocator<> - already freed. */ return false; } 249 : }; 250 : 251 : #endif 252 : 253 : } // end namespace libMesh 254 : 255 : 256 : #endif // LIBMESH_POOL_ALLOCATOR_H