$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r54178 - in sandbox/monotonic: boost/monotonic libs/monotonic/test
From: christian.schladetsch_at_[hidden]
Date: 2009-06-22 01:27:32
Author: cschladetsch
Date: 2009-06-22 01:27:31 EDT (Mon, 22 Jun 2009)
New Revision: 54178
URL: http://svn.boost.org/trac/boost/changeset/54178
Log:
added "mini-heap" functionality for storage
Text files modified: 
   sandbox/monotonic/boost/monotonic/storage.hpp                 |    45 ++++++++++++++                          
   sandbox/monotonic/libs/monotonic/test/AllocatorTypes.h        |     1                                         
   sandbox/monotonic/libs/monotonic/test/compare_memory_pool.cpp |   123 ++++++++++++++++++++++++++++++++++++++++
   3 files changed, 168 insertions(+), 1 deletions(-)
Modified: sandbox/monotonic/boost/monotonic/storage.hpp
==============================================================================
--- sandbox/monotonic/boost/monotonic/storage.hpp	(original)
+++ sandbox/monotonic/boost/monotonic/storage.hpp	2009-06-22 01:27:31 EDT (Mon, 22 Jun 2009)
@@ -88,7 +88,7 @@
                                 chain.clear();
                         }
 
-			void *allocate(size_t num_bytes, size_t alignment)
+			void *allocate(size_t num_bytes, size_t alignment = 1)
                         {
                                 if (void *ptr = from_pool(num_bytes, alignment))
                                         return ptr;
@@ -159,6 +159,49 @@
                                 return chain.size();
                         }
 
+			// ------------------------------------------------------------------------
+
+			template <class Ty>
+			Ty *initialised_create()
+			{
+				return reinterpret_cast<Ty *>(allocate_bytes<sizeof(Ty)>());
+			}
+
+			template <class Ty>
+			Ty *create()
+			{
+				Ty *ptr = initialised_create<Ty>();
+				new (ptr) Ty();
+				return ptr;
+			}
+
+			template <class Ty>
+			Ty *create(Ty const &X)
+			{
+				Ty *ptr = initialised_create<Ty>();
+				new (ptr) Ty(X);
+				return ptr;
+			}
+
+			template <class Ty>
+			void destroy(Ty *ptr)
+			{
+				if (!ptr)
+					return;
+				ptr->~Ty();
+			}
+
+			template <size_t N>
+			char *allocate_bytes()
+			{
+				return allocate_bytes(N, boost::aligned_storage<N>::alignment);
+			}
+
+			char *allocate_bytes(size_t num_bytes, size_t alignment = 1)
+			{
+				return reinterpret_cast<char *>(allocate(num_bytes, alignment));
+			}
+
                 private:
                         void AddLink(size_t size)
                         {
Modified: sandbox/monotonic/libs/monotonic/test/AllocatorTypes.h
==============================================================================
--- sandbox/monotonic/libs/monotonic/test/AllocatorTypes.h	(original)
+++ sandbox/monotonic/libs/monotonic/test/AllocatorTypes.h	2009-06-22 01:27:31 EDT (Mon, 22 Jun 2009)
@@ -10,6 +10,7 @@
 #pragma once
 
 #include <memory>
+#include <boost/pool/object_pool.hpp>
 #include <boost/pool/pool_alloc.hpp>
 #undef max
 #undef min
Modified: sandbox/monotonic/libs/monotonic/test/compare_memory_pool.cpp
==============================================================================
--- sandbox/monotonic/libs/monotonic/test/compare_memory_pool.cpp	(original)
+++ sandbox/monotonic/libs/monotonic/test/compare_memory_pool.cpp	2009-06-22 01:27:31 EDT (Mon, 22 Jun 2009)
@@ -198,6 +198,59 @@
         }
 };
 
+
+template <class Al>
+void *allocate_bytes(boost::pool<Al> &pool, size_t len)
+{
+	return pool.malloc(len);
+}
+
+template <size_t N, size_t M, class Al>
+void *allocate_bytes(boost::monotonic::storage<N,M,Al> &storage, size_t len)
+{
+	return storage.allocate(len, 1);
+}
+
+
+template <class Ty, class Al>
+Ty *allocate_object(boost::pool<Al> &pool)
+{
+	return pool.malloc(1);
+}
+
+template <class Ty>
+Ty *allocate_object(boost::monotonic::allocator<Ty> &alloc)
+{
+	return alloc.allocate(1);
+}
+
+struct test_pool_bytes_alloc
+{
+	template <class Storage>
+	int test(Storage &storage, size_t length)
+	{
+		for (size_t n = 0; n < length; ++n)
+		{
+			::allocate_bytes(storage, length*rand()/RAND_MAX);
+		}
+		return 0;
+	}
+};
+
+template <class Ty>
+struct test_pool_object_alloc
+{
+	template <class Storage>
+	int test(Storage &storage, size_t length)
+	{
+		for (size_t n = 0; n < length; ++n)
+		{
+			::allocate_object(storage);
+		}
+		return n;
+	}
+};
+
 struct PoolResult 
 {
         double pool_elapsed;
@@ -351,6 +404,74 @@
         cout << "===================================================" << endl;
 }
 
+#ifdef WIN32
+//warning C4996: 'std::fill_n': Function call with parameters that may be unsafe
+#pragma warning(disable:4996)
+#endif
+
+void test_pools()
+{
+	size_t length = 1;
+
+	{
+		boost::pool<> storage(sizeof(int));
+		for (size_t n = 0; n < length; ++n)
+		{
+			int *p = reinterpret_cast<int *>(storage.malloc());
+		}
+	}
+	{
+		boost::object_pool<int> storage;
+		for (size_t n = 0; n < length; ++n)
+		{
+			int *p = storage.malloc();
+		}
+	}
+
+	if (0)
+	{
+		boost::object_pool<string> storage;
+		for (size_t n = 0; n < length; ++n)
+		{
+			string *p = storage.malloc();
+		}
+		// crashes when storage is released?
+	}
+
+	{
+		// storage starts on the stack, then merges into the heap as needed
+		monotonic::storage<> storage;
+		for (size_t n = 0; n < length; ++n)
+		{
+			// create a new int from storage
+			int *n0 = storage.create<int>();
+
+			// pass a ctor argument
+			int *n1 = storage.create<int>(42);
+
+			// create a new string (uses correct alignment)
+			string *s1 = storage.create<string>("foo");
+			BOOST_ASSERT(*s1 == "foo");
+
+			// allocate 37 bytes with alignment 1
+			char *array0 = storage.allocate_bytes(37);
+			fill_n(array0, 37, 42);
+
+			// allocate 2537 bytes with 64-byte alignment
+			char *array1 = storage.allocate_bytes(2537, 64);
+			fill_n(array1, 2537, 123);
+
+			// allocate 1283 bytes with machine alignment
+			char *array2 = storage.allocate_bytes<1283>();
+			fill_n(array2, 1283, 42);
+
+			// destroy objects. this only calls the destructors; it does not release memory
+			storage.destroy(s1);
+		}
+		// storage is released. if this was only ever on the stack, no work is done
+	}
+}
+
 int main()
 {
         cout << "results of running test at:" << endl;
@@ -364,6 +485,8 @@
         bool run_medium = 1;//true;
         bool run_large = 1;//true;
 
+	test_pools();
+
         // small-size (~100 elements) containers
         if (run_small)
         {