Index: pool.hpp =================================================================== --- pool.hpp (revision 66834) +++ pool.hpp (working copy) @@ -156,6 +156,7 @@ const size_type requested_size; size_type next_size; size_type start_size; + size_type max_size; // finds which POD in the list 'chunk' was allocated from details::PODptr find_POD(void * const chunk) const; @@ -194,8 +195,9 @@ // The second parameter here is an extension! // pre: npartition_size != 0 && nnext_size != 0 explicit pool(const size_type nrequested_size, - const size_type nnext_size = 32) - :list(0, 0), requested_size(nrequested_size), next_size(nnext_size), start_size(nnext_size) + const size_type nnext_size = 32, + const size_type nmax_size = 0) + :list(0, 0), requested_size(nrequested_size), next_size(nnext_size), start_size(nnext_size),max_size(nmax_size) { } ~pool() { purge_memory(); } @@ -212,6 +214,8 @@ // These functions are extensions! size_type get_next_size() const { return next_size; } void set_next_size(const size_type nnext_size) { next_size = start_size = nnext_size; } + size_type get_max_size() const { return max_size; } + void set_max_size(const size_type nmax_size) { max_size = nmax_size; } size_type get_requested_size() const { return requested_size; } // Both malloc and ordered_malloc do a quick inlined check first for any @@ -440,7 +444,12 @@ if (ptr == 0) return 0; const details::PODptr node(ptr, POD_size); - next_size <<= 1; + + BOOST_USING_STD_MIN(); + if(!max_size) + next_size <<= 1; + else if( next_size*partition_size/requested_size < max_size) + next_size = min BOOST_PREVENT_MACRO_SUBSTITUTION(next_size << 1, max_size*requested_size/ partition_size); // initialize it, store().add_block(node.begin(), node.element_size(), partition_size); @@ -464,13 +473,18 @@ if (ptr == 0) return 0; const details::PODptr node(ptr, POD_size); - next_size <<= 1; + BOOST_USING_STD_MIN(); + if(!max_size) + next_size <<= 1; + else if( next_size*partition_size/requested_size < max_size) + next_size = min BOOST_PREVENT_MACRO_SUBSTITUTION(next_size << 1, max_size*requested_size/ partition_size); + // initialize it, // (we can use "add_block" here because we know that // the free list is empty, so we don't have to use // the slower ordered version) - store().add_block(node.begin(), node.element_size(), partition_size); + store().add_ordered_block(node.begin(), node.element_size(), partition_size); // insert it into the list, // handle border case @@ -530,10 +544,14 @@ // the free list is empty, so we don't have to use // the slower ordered version) if (next_size > num_chunks) - store().add_block(node.begin() + num_chunks * partition_size, + store().add_ordered_block(node.begin() + num_chunks * partition_size, node.element_size() - num_chunks * partition_size, partition_size); - next_size <<= 1; + BOOST_USING_STD_MIN(); + if(!max_size) + next_size <<= 1; + else if( next_size*partition_size/requested_size < max_size) + next_size = min BOOST_PREVENT_MACRO_SUBSTITUTION(next_size << 1, max_size*requested_size/ partition_size); // insert it into the list, // handle border case Index: poolfwd.hpp =================================================================== --- poolfwd.hpp (revision 66834) +++ poolfwd.hpp (working copy) @@ -46,7 +46,8 @@ template + unsigned NextSize = 32, + unsigned MaxSize = 0> struct singleton_pool; // @@ -57,7 +58,8 @@ template + unsigned NextSize = 32, + unsigned MaxSize = 0> class pool_allocator; struct fast_pool_allocator_tag; @@ -65,7 +67,8 @@ template + unsigned NextSize = 32, + unsigned MaxSize = 0> class fast_pool_allocator; } // namespace boost Index: singleton_pool.hpp =================================================================== --- singleton_pool.hpp (revision 66834) +++ singleton_pool.hpp (working copy) @@ -27,7 +27,8 @@ template + unsigned NextSize, + unsigned MaxSize> struct singleton_pool { public: Index: object_pool.hpp =================================================================== --- object_pool.hpp (revision 66834) +++ object_pool.hpp (working copy) @@ -53,8 +53,8 @@ public: // This constructor parameter is an extension! - explicit object_pool(const size_type next_size = 32) - :pool(sizeof(T), next_size) { } + explicit object_pool(const size_type next_size = 32, const size_type max_size = 0) + :pool(sizeof(T), next_size, max_size) { } ~object_pool(); Index: pool_alloc.hpp =================================================================== --- pool_alloc.hpp (revision 66834) +++ pool_alloc.hpp (working copy) @@ -35,7 +35,8 @@ template + unsigned NextSize, + unsigned MaxSize> class pool_allocator { public: @@ -54,7 +55,7 @@ template struct rebind { - typedef pool_allocator other; + typedef pool_allocator other; }; public: @@ -65,7 +66,7 @@ // initialization. See ticket #2359 for a complete explaination // ( http://svn.boost.org/trac/boost/ticket/2359 ) singleton_pool::is_from(0); + NextSize, MaxSize>::is_from(0); } // default copy constructor @@ -74,14 +75,14 @@ // not explicit, mimicking std::allocator [20.4.1] template - pool_allocator(const pool_allocator &) + pool_allocator(const pool_allocator &) { // Required to ensure construction of singleton_pool IFF an // instace of this allocator is constructed during global // initialization. See ticket #2359 for a complete explaination // ( http://svn.boost.org/trac/boost/ticket/2359 ) singleton_pool::is_from(0); + NextSize, MaxSize>::is_from(0); } // default destructor @@ -109,7 +110,7 @@ { const pointer ret = static_cast( singleton_pool::ordered_malloc(n) ); + NextSize, MaxSize>::ordered_malloc(n) ); if (ret == 0) boost::throw_exception(std::bad_alloc()); return ret; @@ -123,22 +124,23 @@ return; #endif singleton_pool::ordered_free(ptr, n); + NextSize, MaxSize>::ordered_free(ptr, n); } }; template< typename UserAllocator, typename Mutex, - unsigned NextSize> -class pool_allocator + unsigned NextSize, + unsigned MaxSize> +class pool_allocator { public: typedef void* pointer; typedef const void* const_pointer; typedef void value_type; template struct rebind { - typedef pool_allocator other; + typedef pool_allocator other; }; }; @@ -147,7 +149,8 @@ template + unsigned NextSize, + unsigned MaxSize> class fast_pool_allocator { public: @@ -166,7 +169,7 @@ template struct rebind { - typedef fast_pool_allocator other; + typedef fast_pool_allocator other; }; public: @@ -177,7 +180,7 @@ // initialization. See ticket #2359 for a complete explaination // ( http://svn.boost.org/trac/boost/ticket/2359 ) singleton_pool::is_from(0); + UserAllocator, Mutex, NextSize, MaxSize>::is_from(0); } // default copy constructor @@ -187,14 +190,14 @@ // not explicit, mimicking std::allocator [20.4.1] template fast_pool_allocator( - const fast_pool_allocator &) + const fast_pool_allocator &) { // Required to ensure construction of singleton_pool IFF an // instace of this allocator is constructed during global // initialization. See ticket #2359 for a complete explaination // ( http://svn.boost.org/trac/boost/ticket/2359 ) singleton_pool::is_from(0); + UserAllocator, Mutex, NextSize, MaxSize>::is_from(0); } // default destructor @@ -223,10 +226,10 @@ const pointer ret = (n == 1) ? static_cast( (singleton_pool::malloc)() ) : + UserAllocator, Mutex, NextSize, MaxSize>::malloc)() ) : static_cast( singleton_pool::ordered_malloc(n) ); + UserAllocator, Mutex, NextSize, MaxSize>::ordered_malloc(n) ); if (ret == 0) boost::throw_exception(std::bad_alloc()); return ret; @@ -237,7 +240,7 @@ { const pointer ret = static_cast( (singleton_pool::malloc)() ); + UserAllocator, Mutex, NextSize, MaxSize>::malloc)() ); if (ret == 0) boost::throw_exception(std::bad_alloc()); return ret; @@ -250,30 +253,31 @@ #endif if (n == 1) (singleton_pool::free)(ptr); + UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr); else (singleton_pool::free)(ptr, n); + UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr, n); } static void deallocate(const pointer ptr) { (singleton_pool::free)(ptr); + UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr); } }; template< typename UserAllocator, typename Mutex, - unsigned NextSize> -class fast_pool_allocator + unsigned NextSize, + unsigned MaxSize> +class fast_pool_allocator { public: typedef void* pointer; typedef const void* const_pointer; typedef void value_type; template struct rebind { - typedef fast_pool_allocator other; + typedef fast_pool_allocator other; }; };