Ticket #2696: boost-pool-maxsize-patch-issue2696.diff

File boost-pool-maxsize-patch-issue2696.diff, 11.9 KB (added by Dean Michael Berris, 12 years ago)

Update to original patch to apply to r66834 -- tested locally without failures, GCC 4.4 Linux.

  • pool.hpp

     
    156156    const size_type requested_size;
    157157    size_type next_size;
    158158    size_type start_size;
     159    size_type max_size;
    159160
    160161    // finds which POD in the list 'chunk' was allocated from
    161162    details::PODptr<size_type> find_POD(void * const chunk) const;
     
    194195    // The second parameter here is an extension!
    195196    // pre: npartition_size != 0 && nnext_size != 0
    196197    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)
    199201    { }
    200202
    201203    ~pool() { purge_memory(); }
     
    212214    // These functions are extensions!
    213215    size_type get_next_size() const { return next_size; }
    214216    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; }
    215219    size_type get_requested_size() const { return requested_size; }
    216220
    217221    // Both malloc and ordered_malloc do a quick inlined check first for any
     
    440444  if (ptr == 0)
    441445    return 0;
    442446  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);
    444453
    445454  //  initialize it,
    446455  store().add_block(node.begin(), node.element_size(), partition_size);
     
    464473  if (ptr == 0)
    465474    return 0;
    466475  const details::PODptr<size_type> node(ptr, POD_size);
    467   next_size <<= 1;
    468476
     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
    469483  //  initialize it,
    470484  //  (we can use "add_block" here because we know that
    471485  //  the free list is empty, so we don't have to use
    472486  //  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);
    474488
    475489  //  insert it into the list,
    476490  //   handle border case
     
    530544  //  the free list is empty, so we don't have to use
    531545  //  the slower ordered version)
    532546  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,
    534548        node.element_size() - num_chunks * partition_size, partition_size);
    535549
    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);
    537555
    538556  //  insert it into the list,
    539557  //   handle border case
  • poolfwd.hpp

     
    4646template <typename Tag, unsigned RequestedSize,
    4747    typename UserAllocator = default_user_allocator_new_delete,
    4848    typename Mutex = details::pool::default_mutex,
    49     unsigned NextSize = 32>
     49    unsigned NextSize = 32,
     50    unsigned MaxSize = 0>
    5051struct singleton_pool;
    5152
    5253//
     
    5758template <typename T,
    5859    typename UserAllocator = default_user_allocator_new_delete,
    5960    typename Mutex = details::pool::default_mutex,
    60     unsigned NextSize = 32>
     61    unsigned NextSize = 32,
     62    unsigned MaxSize = 0>
    6163class pool_allocator;
    6264
    6365struct fast_pool_allocator_tag;
     
    6567template <typename T,
    6668    typename UserAllocator = default_user_allocator_new_delete,
    6769    typename Mutex = details::pool::default_mutex,
    68     unsigned NextSize = 32>
     70    unsigned NextSize = 32,
     71    unsigned MaxSize = 0>
    6972class fast_pool_allocator;
    7073
    7174} // namespace boost
  • singleton_pool.hpp

     
    2727template <typename Tag, unsigned RequestedSize,
    2828    typename UserAllocator,
    2929    typename Mutex,
    30     unsigned NextSize>
     30    unsigned NextSize,
     31    unsigned MaxSize>
    3132struct singleton_pool
    3233{
    3334  public:
  • object_pool.hpp

     
    5353
    5454  public:
    5555    // 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) { }
    5858
    5959    ~object_pool();
    6060
  • pool_alloc.hpp

     
    3535template <typename T,
    3636    typename UserAllocator,
    3737    typename Mutex,
    38     unsigned NextSize>
     38    unsigned NextSize,
     39    unsigned MaxSize>
    3940class pool_allocator
    4041{
    4142  public:
     
    5455    template <typename U>
    5556    struct rebind
    5657    {
    57       typedef pool_allocator<U, UserAllocator, Mutex, NextSize> other;
     58      typedef pool_allocator<U, UserAllocator, Mutex, NextSize,MaxSize> other;
    5859    };
    5960
    6061  public:
     
    6566      // initialization. See ticket #2359 for a complete explaination
    6667      // ( http://svn.boost.org/trac/boost/ticket/2359 )
    6768      singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
    68                      NextSize>::is_from(0);
     69                     NextSize, MaxSize>::is_from(0);
    6970    }
    7071
    7172    // default copy constructor
     
    7475
    7576    // not explicit, mimicking std::allocator [20.4.1]
    7677    template <typename U>
    77     pool_allocator(const pool_allocator<U, UserAllocator, Mutex, NextSize> &)
     78    pool_allocator(const pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> &)
    7879    {
    7980      // Required to ensure construction of singleton_pool IFF an
    8081      // instace of this allocator is constructed during global
    8182      // initialization. See ticket #2359 for a complete explaination
    8283      // ( http://svn.boost.org/trac/boost/ticket/2359 )
    8384      singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
    84                      NextSize>::is_from(0);
     85                     NextSize, MaxSize>::is_from(0);
    8586    }
    8687
    8788    // default destructor
     
    109110    {
    110111      const pointer ret = static_cast<pointer>(
    111112          singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
    112               NextSize>::ordered_malloc(n) );
     113              NextSize, MaxSize>::ordered_malloc(n) );
    113114      if (ret == 0)
    114115        boost::throw_exception(std::bad_alloc());
    115116      return ret;
     
    123124        return;
    124125#endif
    125126      singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
    126           NextSize>::ordered_free(ptr, n);
     127          NextSize, MaxSize>::ordered_free(ptr, n);
    127128    }
    128129};
    129130
    130131template<
    131132    typename UserAllocator,
    132133    typename Mutex,
    133     unsigned NextSize>
    134 class pool_allocator<void, UserAllocator, Mutex, NextSize>
     134    unsigned NextSize,
     135    unsigned MaxSize>
     136class pool_allocator<void, UserAllocator, Mutex, NextSize, MaxSize>
    135137{
    136138public:
    137139    typedef void*       pointer;
    138140    typedef const void* const_pointer;
    139141    typedef void        value_type;
    140142    template <class U> struct rebind {
    141         typedef pool_allocator<U, UserAllocator, Mutex, NextSize> other;
     143        typedef pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
    142144    };
    143145};
    144146
     
    147149template <typename T,
    148150    typename UserAllocator,
    149151    typename Mutex,
    150     unsigned NextSize>
     152    unsigned NextSize,
     153    unsigned MaxSize>
    151154class fast_pool_allocator
    152155{
    153156  public:
     
    166169    template <typename U>
    167170    struct rebind
    168171    {
    169       typedef fast_pool_allocator<U, UserAllocator, Mutex, NextSize> other;
     172      typedef fast_pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
    170173    };
    171174
    172175  public:
     
    177180      // initialization. See ticket #2359 for a complete explaination
    178181      // ( http://svn.boost.org/trac/boost/ticket/2359 )
    179182      singleton_pool<fast_pool_allocator_tag, sizeof(T),
    180                      UserAllocator, Mutex, NextSize>::is_from(0);
     183                     UserAllocator, Mutex, NextSize, MaxSize>::is_from(0);
    181184    }
    182185   
    183186    // default copy constructor
     
    187190    // not explicit, mimicking std::allocator [20.4.1]
    188191    template <typename U>
    189192    fast_pool_allocator(
    190         const fast_pool_allocator<U, UserAllocator, Mutex, NextSize> &)
     193        const fast_pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> &)
    191194    {
    192195      // Required to ensure construction of singleton_pool IFF an
    193196      // instace of this allocator is constructed during global
    194197      // initialization. See ticket #2359 for a complete explaination
    195198      // ( http://svn.boost.org/trac/boost/ticket/2359 )
    196199      singleton_pool<fast_pool_allocator_tag, sizeof(T),
    197                      UserAllocator, Mutex, NextSize>::is_from(0);
     200                     UserAllocator, Mutex, NextSize, MaxSize>::is_from(0);
    198201    }
    199202
    200203    // default destructor
     
    223226      const pointer ret = (n == 1) ?
    224227          static_cast<pointer>(
    225228              (singleton_pool<fast_pool_allocator_tag, sizeof(T),
    226                   UserAllocator, Mutex, NextSize>::malloc)() ) :
     229                  UserAllocator, Mutex, NextSize, MaxSize>::malloc)() ) :
    227230          static_cast<pointer>(
    228231              singleton_pool<fast_pool_allocator_tag, sizeof(T),
    229                   UserAllocator, Mutex, NextSize>::ordered_malloc(n) );
     232                  UserAllocator, Mutex, NextSize, MaxSize>::ordered_malloc(n) );
    230233      if (ret == 0)
    231234        boost::throw_exception(std::bad_alloc());
    232235      return ret;
     
    237240    {
    238241      const pointer ret = static_cast<pointer>(
    239242          (singleton_pool<fast_pool_allocator_tag, sizeof(T),
    240               UserAllocator, Mutex, NextSize>::malloc)() );
     243              UserAllocator, Mutex, NextSize, MaxSize>::malloc)() );
    241244      if (ret == 0)
    242245        boost::throw_exception(std::bad_alloc());
    243246      return ret;
     
    250253#endif
    251254      if (n == 1)
    252255        (singleton_pool<fast_pool_allocator_tag, sizeof(T),
    253             UserAllocator, Mutex, NextSize>::free)(ptr);
     256            UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr);
    254257      else
    255258        (singleton_pool<fast_pool_allocator_tag, sizeof(T),
    256             UserAllocator, Mutex, NextSize>::free)(ptr, n);
     259            UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr, n);
    257260    }
    258261    static void deallocate(const pointer ptr)
    259262    {
    260263      (singleton_pool<fast_pool_allocator_tag, sizeof(T),
    261           UserAllocator, Mutex, NextSize>::free)(ptr);
     264          UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr);
    262265    }
    263266};
    264267
    265268template<
    266269    typename UserAllocator,
    267270    typename Mutex,
    268     unsigned NextSize>
    269 class fast_pool_allocator<void, UserAllocator, Mutex, NextSize>
     271    unsigned NextSize,
     272    unsigned MaxSize>
     273class fast_pool_allocator<void, UserAllocator, Mutex, NextSize, MaxSize>
    270274{
    271275public:
    272276    typedef void*       pointer;
    273277    typedef const void* const_pointer;
    274278    typedef void        value_type;
    275279    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;
    277281    };
    278282};
    279283