Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r78271 - in sandbox/pool: boost/pool libs/pool/test
From: svart.riddare_at_[hidden]
Date: 2012-04-30 10:20:44


Author: edupuis
Date: 2012-04-30 10:20:43 EDT (Mon, 30 Apr 2012)
New Revision: 78271
URL: http://svn.boost.org/trac/boost/changeset/78271

Log:
Added class 'boost::static_object_pool'. To minimize code duplication and prevent API changes, existing class 'boost::object_pool<T, UserAllocator>' now inherits from 'boost::object_pool_base<T, pool<UserAllocator>>'.

Member functions get_max_size() and set_max_size() where missing from boost::object_pool implementation. I took advantage of the refactoring to add these functions.
Text files modified:
   sandbox/pool/boost/pool/object_pool.hpp | 170 +++++++++++++++++++++++++++++----------
   sandbox/pool/boost/pool/poolfwd.hpp | 3
   sandbox/pool/libs/pool/test/test_poisoned_macros.cpp | 3
   sandbox/pool/libs/pool/test/test_static_pool.cpp | 71 +++++++++++++++-
   4 files changed, 195 insertions(+), 52 deletions(-)

Modified: sandbox/pool/boost/pool/object_pool.hpp
==============================================================================
--- sandbox/pool/boost/pool/object_pool.hpp (original)
+++ sandbox/pool/boost/pool/object_pool.hpp 2012-04-30 10:20:43 EDT (Mon, 30 Apr 2012)
@@ -19,6 +19,8 @@
 
 // boost::pool
 #include <boost/pool/pool.hpp>
+// boost::static_pool
+#include <boost/pool/static_pool.hpp>
 
 // The following code will be put into Boost.Config in a later revision
 #if defined(BOOST_MSVC) || defined(__KCC)
@@ -48,43 +50,31 @@
 <b>T</b> The type of object to allocate/deallocate.
 T must have a non-throwing destructor.
 
-<b>UserAllocator</b>
-Defines the allocator that the underlying Pool will use to allocate memory from the system.
-See User Allocators for details.
-
-Class object_pool is a template class
-that can be used for fast and efficient memory allocation of objects.
-It also provides automatic destruction of non-deallocated objects.
+<b>Pool</b>
+Defines the underlying Pool will use to manage memory from the system.
+This is intended to be either a Pool or a StaticPool.
 
-When the object pool is destroyed, then the destructor for type T
-is called for each allocated T that has not yet been deallocated. O(N).
-
-Whenever an object of type ObjectPool needs memory from the system,
-it will request it from its UserAllocator template parameter.
-The amount requested is determined using a doubling algorithm;
-that is, each time more system memory is allocated,
-the amount of system memory requested is doubled.
-Users may control the doubling algorithm by the parameters passed
-to the object_pool's constructor.
+Class object_pool_base is a template base class which is used
+to define classes object_pool and static_object_pool.
 */
 
-template <typename T, typename UserAllocator>
-class object_pool: protected pool<UserAllocator>
+template <typename T, typename Pool>
+class object_pool_base: protected Pool
 { //!
   public:
     typedef T element_type; //!< ElementType
- typedef UserAllocator user_allocator; //!<
- typedef typename pool<UserAllocator>::size_type size_type; //!< pool<UserAllocator>::size_type
- typedef typename pool<UserAllocator>::difference_type difference_type; //!< pool<UserAllocator>::difference_type
+ typedef typename Pool::user_allocator user_allocator; //!<
+ typedef typename Pool::size_type size_type; //!< pool<UserAllocator>::size_type
+ typedef typename Pool::difference_type difference_type; //!< pool<UserAllocator>::difference_type
 
   protected:
     //! \return The underlying boost:: \ref pool storage used by *this.
- pool<UserAllocator> & store()
+ Pool & store()
     {
       return *this;
     }
     //! \return The underlying boost:: \ref pool storage used by *this.
- const pool<UserAllocator> & store() const
+ const Pool & store() const
     {
       return *this;
     }
@@ -96,17 +86,14 @@
     }
 
   public:
- explicit object_pool(const size_type arg_next_size = 32, const size_type arg_max_size = 0)
+ explicit object_pool_base(const size_type arg_requested_objects)
     :
- pool<UserAllocator>(sizeof(T), arg_next_size, arg_max_size)
- { //! Constructs a new (empty by default) ObjectPool.
- //! \param next_size Number of chunks to request from the system the next time that object needs to allocate system memory (default 32).
- //! \pre next_size != 0.
- //! \param max_size Maximum number of chunks to ever request from the system - this puts a cap on the doubling algorithm
- //! used by the underlying pool.
+ Pool(sizeof(T), arg_requested_objects)
+ { //! Constructs a new (empty by default) ObjectPoolBase.
+ //! \param arg_requested_objects Number of memory chunks to allocate at initialization.
     }
 
- ~object_pool();
+ ~object_pool_base();
 
     // Returns 0 if out-of-memory.
     element_type * malloc BOOST_PREVENT_MACRO_SUBSTITUTION()
@@ -204,20 +191,10 @@
       chunk->~T();
       (free)(chunk);
     }
-
- size_type get_next_size() const
- { //! \returns The number of chunks that will be allocated next time we run out of memory.
- return store().get_next_size();
- }
- void set_next_size(const size_type x)
- { //! Set a new number of chunks to allocate the next time we run out of memory.
- //! \param x wanted next_size (must not be zero).
- store().set_next_size(x);
- }
 };
 
-template <typename T, typename UserAllocator>
-object_pool<T, UserAllocator>::~object_pool()
+template <typename T, typename Pool>
+object_pool_base<T, Pool>::~object_pool_base()
 {
 #ifndef BOOST_POOL_VALGRIND
   // handle trivial case of invalid list.
@@ -258,7 +235,7 @@
     }
 
     // free storage.
- (UserAllocator::free)(iter.begin());
+ (Pool::free)(iter.begin());
 
     // increment iter.
     iter = next;
@@ -277,6 +254,109 @@
 #endif
 }
 
+/*! \brief A template class
+that can be used for fast and efficient memory allocation of objects.
+It also provides automatic destruction of non-deallocated objects.
+
+\details
+
+<b>T</b> The type of object to allocate/deallocate.
+T must have a non-throwing destructor.
+
+<b>UserAllocator</b>
+Defines the allocator that the underlying Pool will use to allocate memory from the system.
+See User Allocators for details.
+
+Class object_pool is a template class
+that can be used for fast and efficient memory allocation of objects.
+It also provides automatic destruction of non-deallocated objects.
+
+When the object pool is destroyed, then the destructor for type T
+is called for each allocated T that has not yet been deallocated. O(N).
+
+Whenever an object of type ObjectPool needs memory from the system,
+it will request it from its UserAllocator template parameter.
+The amount requested is determined using a doubling algorithm;
+that is, each time more system memory is allocated,
+the amount of system memory requested is doubled.
+Users may control the doubling algorithm by the parameters passed
+to the object_pool's constructor.
+*/
+
+template<typename T, typename UserAllocator>
+class object_pool : public object_pool_base<T, pool<UserAllocator> >
+{
+ public:
+ explicit object_pool(const size_type arg_next_size = 32, const size_type arg_max_size = 0)
+ :
+ object_pool_base<T, pool<UserAllocator> >(arg_next_size)
+ { //! Constructs a new (empty by default) ObjectPool.
+ //! \param arg_next_size Number of chunks to request from the system the next time that object needs to allocate system memory (default 32).
+ //! \pre next_size != 0.
+ //! \param arg_max_size Maximum number of chunks to ever request from the system - this puts a cap on the doubling algorithm
+ //! used by the underlying pool.
+ set_max_size(arg_max_size);
+ }
+
+ public:
+ size_type get_next_size() const
+ { //! \returns The number of chunks that will be allocated next time we run out of memory.
+ return pool<UserAllocator>::get_next_size();
+ }
+
+ void set_next_size(const size_type nnext_size)
+ { //! Set a new number of chunks to allocate the next time we run out of memory.
+ //! \param nnext_size wanted next_size (must not be zero).
+ pool<UserAllocator>::set_next_size(nnext_size);
+ }
+
+ size_type get_max_size() const
+ { //! \returns max_size.
+ return pool<UserAllocator>::get_max_size();
+ }
+
+ void set_max_size(const size_type nmax_size)
+ { //! Set max_size.
+ pool<UserAllocator>::set_max_size(nmax_size);
+ }
+};
+
+/*! \brief A template class
+that can be used for fast and efficient memory allocation of objects.
+It also provides automatic destruction of non-deallocated objects.
+
+\details
+
+<b>T</b> The type of object to allocate/deallocate.
+T must have a non-throwing destructor.
+
+<b>UserAllocator</b>
+Defines the allocator that the underlying StaticPool will use to allocate memory from the system.
+See User Allocators for details.
+
+Class static_object_pool is a template class
+that can be used for fast and efficient memory allocation of objects.
+It also provides automatic destruction of non-deallocated objects.
+
+When the object pool is destroyed, then the destructor for type T
+is called for each allocated T that has not yet been deallocated. O(N).
+
+The StaticObjectPool allocates all memory needed at initialization.
+*/
+
+template<typename T, typename UserAllocator>
+class static_object_pool : public object_pool_base<T, static_pool<UserAllocator> >
+{
+ public:
+ explicit static_object_pool(const size_type arg_requested_objects)
+ :
+ object_pool_base<T, static_pool<UserAllocator> >(arg_requested_objects)
+ { //! Constructs a new (empty by default) StaticObjectPool.
+ //! \param arg_requested_objects Number of memory chunks to allocate at initialization.
+ //! It defines the maximum number of objects that can be malloc'ed from this pool.
+ }
+};
+
 } // namespace boost
 
 // The following code might be put into some Boost.Config header in a later revision

Modified: sandbox/pool/boost/pool/poolfwd.hpp
==============================================================================
--- sandbox/pool/boost/pool/poolfwd.hpp (original)
+++ sandbox/pool/boost/pool/poolfwd.hpp 2012-04-30 10:20:43 EDT (Mon, 30 Apr 2012)
@@ -46,6 +46,9 @@
 template <typename T, typename UserAllocator = default_user_allocator_new_delete>
 class object_pool;
 
+template <typename T, typename UserAllocator = default_user_allocator_new_delete>
+class static_object_pool;
+
 //
 // Location: <boost/pool/static_pool.hpp>
 //

Modified: sandbox/pool/libs/pool/test/test_poisoned_macros.cpp
==============================================================================
--- sandbox/pool/libs/pool/test/test_poisoned_macros.cpp (original)
+++ sandbox/pool/libs/pool/test/test_poisoned_macros.cpp 2012-04-30 10:20:43 EDT (Mon, 30 Apr 2012)
@@ -36,6 +36,9 @@
 template class boost::static_pool<boost::default_user_allocator_new_delete>;
 template class boost::static_pool<boost::default_user_allocator_malloc_free>;
 
+template class boost::static_object_pool<int, boost::default_user_allocator_new_delete>;
+template class boost::static_object_pool<int, boost::default_user_allocator_malloc_free>;
+
 template class boost::pool_allocator<int, boost::default_user_allocator_new_delete>;
 template class boost::pool_allocator<int, boost::default_user_allocator_malloc_free>;
 template class boost::fast_pool_allocator<int, boost::default_user_allocator_new_delete>;

Modified: sandbox/pool/libs/pool/test/test_static_pool.cpp
==============================================================================
--- sandbox/pool/libs/pool/test/test_static_pool.cpp (original)
+++ sandbox/pool/libs/pool/test/test_static_pool.cpp 2012-04-30 10:20:43 EDT (Mon, 30 Apr 2012)
@@ -5,7 +5,8 @@
  * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
  */
 
-#include <M:/Boost/Sandbox/pool/boost/pool/static_pool.hpp>
+#include <boost/pool/static_pool.hpp>
+#include <boost/pool/object_pool.hpp>
 
 #include <boost/assert.hpp>
 #include <boost/detail/lightweight_test.hpp>
@@ -35,18 +36,32 @@
 
 bool user_allocator_once::reset = false;
 
-// Main set of test
+// Object that counts the number of calls to constructor / destructor
 
-static void test_static_pool()
+class Count
+{
+ public :
+ static int count;
+ Count() { count += 1; }
+ ~Count() { count -= 1; }
+};
+
+int Count::count = 0;
+
+// Testing static_pool
+
+template<int SIZE>
+void test_static_pool()
 {
         static const int pool_size = 24; // Initial size of pool
- static const int num_iterations = pool_size + 8; // Number of mallocs we will try on pool
+ static const int num_iterations = pool_size + 8; // Number of mallocs we will try on pool in following tests
+ static const int num_random_iterations = 2000; // Number of iterations for test #4 that follows
         static const int consecutive_elements = 5; // Number of consecutive elements we will request
 
         void *p[num_iterations];
 
         user_allocator_once::reset = true;
- boost::static_pool<user_allocator_once> pool(sizeof(int), pool_size);
+ boost::static_pool<user_allocator_once> pool(SIZE, pool_size);
 
         for (int n = 0; n < 2; n++)
         {
@@ -91,7 +106,7 @@
                 for (int k = 0; k < pool_size / 2; k++)
                         p[allocated++] = pool.malloc();
 
- for (int k = 0; k < 100 * num_iterations; k++)
+ for (int k = 0; k < num_random_iterations; k++)
                 {
                         if ((rand() & 8) && (allocated < pool_size))
                         {
@@ -110,10 +125,52 @@
         }
 }
 
+// Testing static_object_pool
+
+template<typename T>
+void test_static_object_pool()
+{
+ static const int pool_size = 24; // Initial size of pool
+ static const int num_random_iterations = 200; // Number of iterations f
+
+ user_allocator_once::reset = true;
+ boost::static_object_pool<T, user_allocator_once> pool(pool_size);
+
+ T *p[pool_size];
+
+ // TEST #1
+
+ srand(NULL);
+
+ int allocated = 0;
+ for (int k = 0; k < pool_size / 2; k++)
+ p[allocated++] = pool.construct();
+
+ for (int k = 0; k < num_random_iterations; k++)
+ {
+ if ((rand() & 8) && (allocated < pool_size))
+ {
+ p[allocated++] = pool.construct();
+ }
+ else if (allocated > 0)
+ {
+ pool.destroy(p[--allocated]);
+ }
+
+ BOOST_TEST(Count::count == allocated);
+ }
+
+ while (allocated < pool_size / 4)
+ p[allocated++] = pool.construct();
+}
+
 // Main
 
 int main()
 {
- test_static_pool();
+ test_static_pool<8>();
+ test_static_object_pool<Count>();
+ BOOST_TEST(Count::count == 0);
+
         return 0;
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk