Ticket #2696: boost-pool-maxsize-patch-issue2696.diff
File boost-pool-maxsize-patch-issue2696.diff, 11.9 KB (added by , 12 years ago) |
---|
-
pool.hpp
156 156 const size_type requested_size; 157 157 size_type next_size; 158 158 size_type start_size; 159 size_type max_size; 159 160 160 161 // finds which POD in the list 'chunk' was allocated from 161 162 details::PODptr<size_type> find_POD(void * const chunk) const; … … 194 195 // The second parameter here is an extension! 195 196 // pre: npartition_size != 0 && nnext_size != 0 196 197 explicit pool(const size_type nrequested_size, 197 const size_type nnext_size = 32) 198 :list(0, 0), requested_size(nrequested_size), next_size(nnext_size), start_size(nnext_size) 198 const size_type nnext_size = 32, 199 const size_type nmax_size = 0) 200 :list(0, 0), requested_size(nrequested_size), next_size(nnext_size), start_size(nnext_size),max_size(nmax_size) 199 201 { } 200 202 201 203 ~pool() { purge_memory(); } … … 212 214 // These functions are extensions! 213 215 size_type get_next_size() const { return next_size; } 214 216 void set_next_size(const size_type nnext_size) { next_size = start_size = nnext_size; } 217 size_type get_max_size() const { return max_size; } 218 void set_max_size(const size_type nmax_size) { max_size = nmax_size; } 215 219 size_type get_requested_size() const { return requested_size; } 216 220 217 221 // Both malloc and ordered_malloc do a quick inlined check first for any … … 440 444 if (ptr == 0) 441 445 return 0; 442 446 const details::PODptr<size_type> node(ptr, POD_size); 443 next_size <<= 1; 447 448 BOOST_USING_STD_MIN(); 449 if(!max_size) 450 next_size <<= 1; 451 else if( next_size*partition_size/requested_size < max_size) 452 next_size = min BOOST_PREVENT_MACRO_SUBSTITUTION(next_size << 1, max_size*requested_size/ partition_size); 444 453 445 454 // initialize it, 446 455 store().add_block(node.begin(), node.element_size(), partition_size); … … 464 473 if (ptr == 0) 465 474 return 0; 466 475 const details::PODptr<size_type> node(ptr, POD_size); 467 next_size <<= 1;468 476 477 BOOST_USING_STD_MIN(); 478 if(!max_size) 479 next_size <<= 1; 480 else if( next_size*partition_size/requested_size < max_size) 481 next_size = min BOOST_PREVENT_MACRO_SUBSTITUTION(next_size << 1, max_size*requested_size/ partition_size); 482 469 483 // initialize it, 470 484 // (we can use "add_block" here because we know that 471 485 // the free list is empty, so we don't have to use 472 486 // the slower ordered version) 473 store().add_ block(node.begin(), node.element_size(), partition_size);487 store().add_ordered_block(node.begin(), node.element_size(), partition_size); 474 488 475 489 // insert it into the list, 476 490 // handle border case … … 530 544 // the free list is empty, so we don't have to use 531 545 // the slower ordered version) 532 546 if (next_size > num_chunks) 533 store().add_ block(node.begin() + num_chunks * partition_size,547 store().add_ordered_block(node.begin() + num_chunks * partition_size, 534 548 node.element_size() - num_chunks * partition_size, partition_size); 535 549 536 next_size <<= 1; 550 BOOST_USING_STD_MIN(); 551 if(!max_size) 552 next_size <<= 1; 553 else if( next_size*partition_size/requested_size < max_size) 554 next_size = min BOOST_PREVENT_MACRO_SUBSTITUTION(next_size << 1, max_size*requested_size/ partition_size); 537 555 538 556 // insert it into the list, 539 557 // handle border case -
poolfwd.hpp
46 46 template <typename Tag, unsigned RequestedSize, 47 47 typename UserAllocator = default_user_allocator_new_delete, 48 48 typename Mutex = details::pool::default_mutex, 49 unsigned NextSize = 32> 49 unsigned NextSize = 32, 50 unsigned MaxSize = 0> 50 51 struct singleton_pool; 51 52 52 53 // … … 57 58 template <typename T, 58 59 typename UserAllocator = default_user_allocator_new_delete, 59 60 typename Mutex = details::pool::default_mutex, 60 unsigned NextSize = 32> 61 unsigned NextSize = 32, 62 unsigned MaxSize = 0> 61 63 class pool_allocator; 62 64 63 65 struct fast_pool_allocator_tag; … … 65 67 template <typename T, 66 68 typename UserAllocator = default_user_allocator_new_delete, 67 69 typename Mutex = details::pool::default_mutex, 68 unsigned NextSize = 32> 70 unsigned NextSize = 32, 71 unsigned MaxSize = 0> 69 72 class fast_pool_allocator; 70 73 71 74 } // namespace boost -
singleton_pool.hpp
27 27 template <typename Tag, unsigned RequestedSize, 28 28 typename UserAllocator, 29 29 typename Mutex, 30 unsigned NextSize> 30 unsigned NextSize, 31 unsigned MaxSize> 31 32 struct singleton_pool 32 33 { 33 34 public: -
object_pool.hpp
53 53 54 54 public: 55 55 // This constructor parameter is an extension! 56 explicit object_pool(const size_type next_size = 32 )57 :pool<UserAllocator>(sizeof(T), next_size ) { }56 explicit object_pool(const size_type next_size = 32, const size_type max_size = 0) 57 :pool<UserAllocator>(sizeof(T), next_size, max_size) { } 58 58 59 59 ~object_pool(); 60 60 -
pool_alloc.hpp
35 35 template <typename T, 36 36 typename UserAllocator, 37 37 typename Mutex, 38 unsigned NextSize> 38 unsigned NextSize, 39 unsigned MaxSize> 39 40 class pool_allocator 40 41 { 41 42 public: … … 54 55 template <typename U> 55 56 struct rebind 56 57 { 57 typedef pool_allocator<U, UserAllocator, Mutex, NextSize > other;58 typedef pool_allocator<U, UserAllocator, Mutex, NextSize,MaxSize> other; 58 59 }; 59 60 60 61 public: … … 65 66 // initialization. See ticket #2359 for a complete explaination 66 67 // ( http://svn.boost.org/trac/boost/ticket/2359 ) 67 68 singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex, 68 NextSize >::is_from(0);69 NextSize, MaxSize>::is_from(0); 69 70 } 70 71 71 72 // default copy constructor … … 74 75 75 76 // not explicit, mimicking std::allocator [20.4.1] 76 77 template <typename U> 77 pool_allocator(const pool_allocator<U, UserAllocator, Mutex, NextSize > &)78 pool_allocator(const pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> &) 78 79 { 79 80 // Required to ensure construction of singleton_pool IFF an 80 81 // instace of this allocator is constructed during global 81 82 // initialization. See ticket #2359 for a complete explaination 82 83 // ( http://svn.boost.org/trac/boost/ticket/2359 ) 83 84 singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex, 84 NextSize >::is_from(0);85 NextSize, MaxSize>::is_from(0); 85 86 } 86 87 87 88 // default destructor … … 109 110 { 110 111 const pointer ret = static_cast<pointer>( 111 112 singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex, 112 NextSize >::ordered_malloc(n) );113 NextSize, MaxSize>::ordered_malloc(n) ); 113 114 if (ret == 0) 114 115 boost::throw_exception(std::bad_alloc()); 115 116 return ret; … … 123 124 return; 124 125 #endif 125 126 singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex, 126 NextSize >::ordered_free(ptr, n);127 NextSize, MaxSize>::ordered_free(ptr, n); 127 128 } 128 129 }; 129 130 130 131 template< 131 132 typename UserAllocator, 132 133 typename Mutex, 133 unsigned NextSize> 134 class pool_allocator<void, UserAllocator, Mutex, NextSize> 134 unsigned NextSize, 135 unsigned MaxSize> 136 class pool_allocator<void, UserAllocator, Mutex, NextSize, MaxSize> 135 137 { 136 138 public: 137 139 typedef void* pointer; 138 140 typedef const void* const_pointer; 139 141 typedef void value_type; 140 142 template <class U> struct rebind { 141 typedef pool_allocator<U, UserAllocator, Mutex, NextSize > other;143 typedef pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other; 142 144 }; 143 145 }; 144 146 … … 147 149 template <typename T, 148 150 typename UserAllocator, 149 151 typename Mutex, 150 unsigned NextSize> 152 unsigned NextSize, 153 unsigned MaxSize> 151 154 class fast_pool_allocator 152 155 { 153 156 public: … … 166 169 template <typename U> 167 170 struct rebind 168 171 { 169 typedef fast_pool_allocator<U, UserAllocator, Mutex, NextSize > other;172 typedef fast_pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other; 170 173 }; 171 174 172 175 public: … … 177 180 // initialization. See ticket #2359 for a complete explaination 178 181 // ( http://svn.boost.org/trac/boost/ticket/2359 ) 179 182 singleton_pool<fast_pool_allocator_tag, sizeof(T), 180 UserAllocator, Mutex, NextSize >::is_from(0);183 UserAllocator, Mutex, NextSize, MaxSize>::is_from(0); 181 184 } 182 185 183 186 // default copy constructor … … 187 190 // not explicit, mimicking std::allocator [20.4.1] 188 191 template <typename U> 189 192 fast_pool_allocator( 190 const fast_pool_allocator<U, UserAllocator, Mutex, NextSize > &)193 const fast_pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> &) 191 194 { 192 195 // Required to ensure construction of singleton_pool IFF an 193 196 // instace of this allocator is constructed during global 194 197 // initialization. See ticket #2359 for a complete explaination 195 198 // ( http://svn.boost.org/trac/boost/ticket/2359 ) 196 199 singleton_pool<fast_pool_allocator_tag, sizeof(T), 197 UserAllocator, Mutex, NextSize >::is_from(0);200 UserAllocator, Mutex, NextSize, MaxSize>::is_from(0); 198 201 } 199 202 200 203 // default destructor … … 223 226 const pointer ret = (n == 1) ? 224 227 static_cast<pointer>( 225 228 (singleton_pool<fast_pool_allocator_tag, sizeof(T), 226 UserAllocator, Mutex, NextSize >::malloc)() ) :229 UserAllocator, Mutex, NextSize, MaxSize>::malloc)() ) : 227 230 static_cast<pointer>( 228 231 singleton_pool<fast_pool_allocator_tag, sizeof(T), 229 UserAllocator, Mutex, NextSize >::ordered_malloc(n) );232 UserAllocator, Mutex, NextSize, MaxSize>::ordered_malloc(n) ); 230 233 if (ret == 0) 231 234 boost::throw_exception(std::bad_alloc()); 232 235 return ret; … … 237 240 { 238 241 const pointer ret = static_cast<pointer>( 239 242 (singleton_pool<fast_pool_allocator_tag, sizeof(T), 240 UserAllocator, Mutex, NextSize >::malloc)() );243 UserAllocator, Mutex, NextSize, MaxSize>::malloc)() ); 241 244 if (ret == 0) 242 245 boost::throw_exception(std::bad_alloc()); 243 246 return ret; … … 250 253 #endif 251 254 if (n == 1) 252 255 (singleton_pool<fast_pool_allocator_tag, sizeof(T), 253 UserAllocator, Mutex, NextSize >::free)(ptr);256 UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr); 254 257 else 255 258 (singleton_pool<fast_pool_allocator_tag, sizeof(T), 256 UserAllocator, Mutex, NextSize >::free)(ptr, n);259 UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr, n); 257 260 } 258 261 static void deallocate(const pointer ptr) 259 262 { 260 263 (singleton_pool<fast_pool_allocator_tag, sizeof(T), 261 UserAllocator, Mutex, NextSize >::free)(ptr);264 UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr); 262 265 } 263 266 }; 264 267 265 268 template< 266 269 typename UserAllocator, 267 270 typename Mutex, 268 unsigned NextSize> 269 class fast_pool_allocator<void, UserAllocator, Mutex, NextSize> 271 unsigned NextSize, 272 unsigned MaxSize> 273 class fast_pool_allocator<void, UserAllocator, Mutex, NextSize, MaxSize> 270 274 { 271 275 public: 272 276 typedef void* pointer; 273 277 typedef const void* const_pointer; 274 278 typedef void value_type; 275 279 template <class U> struct rebind { 276 typedef fast_pool_allocator<U, UserAllocator, Mutex, NextSize > other;280 typedef fast_pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other; 277 281 }; 278 282 }; 279 283