$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r52612 - in sandbox/memory: boost boost/memory libs/memory/examples/pool
From: xushiweizh_at_[hidden]
Date: 2009-04-26 14:49:43
Author: xushiwei
Date: 2009-04-26 14:49:42 EDT (Sun, 26 Apr 2009)
New Revision: 52612
URL: http://svn.boost.org/trac/boost/changeset/52612
Log:
1. class object_pool (boost/memory/object_pool.hpp)
2. example: testObjectPool
Added:
   sandbox/memory/boost/memory/object_pool.hpp   (contents, props changed)
      - copied, changed from r52606, /sandbox/memory/boost/memory/typed_alloc.hpp
Removed:
   sandbox/memory/boost/memory/typed_alloc.hpp
Text files modified: 
   sandbox/memory/boost/memory.hpp                              |     4                                         
   sandbox/memory/boost/memory/fixed_alloc.hpp                  |     8                                         
   sandbox/memory/boost/memory/object_pool.hpp                  |   174 +++++++++++++++++++++++++++++++-------- 
   sandbox/memory/libs/memory/examples/pool/simple_examples.cpp |    38 ++++++++                                
   4 files changed, 181 insertions(+), 43 deletions(-)
Modified: sandbox/memory/boost/memory.hpp
==============================================================================
--- sandbox/memory/boost/memory.hpp	(original)
+++ sandbox/memory/boost/memory.hpp	2009-04-26 14:49:42 EDT (Sun, 26 Apr 2009)
@@ -44,6 +44,10 @@
 #include "memory/pool.hpp"
 #endif
 
+#ifndef BOOST_MEMORY_OBJECT_POOL_HPP
+#include "memory/object_pool.hpp"
+#endif
+
 // -------------------------------------------------------------------------
 // default_alloc
 
Modified: sandbox/memory/boost/memory/fixed_alloc.hpp
==============================================================================
--- sandbox/memory/boost/memory/fixed_alloc.hpp	(original)
+++ sandbox/memory/boost/memory/fixed_alloc.hpp	2009-04-26 14:49:42 EDT (Sun, 26 Apr 2009)
@@ -128,13 +128,13 @@
         void BOOST_MEMORY_CALL clear()
         {
                 MemBlock* nextBlk;
-		for (MemBlock* blk = m_blks.first(); !m_blks.done(blk); blk = nextBlk)
+		for (MemBlock* blk = this->m_blks.first(); !this->m_blks.done(blk); blk = nextBlk)
                 {
                         nextBlk = blk->next();
-			m_alloc.deallocate(blk);
+			this->m_alloc.deallocate(blk);
                 }
-		m_blks.clear();
-		m_freelist.clear();
+		this->m_blks.clear();
+		this->m_freelist.clear();
         }
 
 private:
Copied: sandbox/memory/boost/memory/object_pool.hpp (from r52606, /sandbox/memory/boost/memory/typed_alloc.hpp)
==============================================================================
--- /sandbox/memory/boost/memory/typed_alloc.hpp	(original)
+++ sandbox/memory/boost/memory/object_pool.hpp	2009-04-26 14:49:42 EDT (Sun, 26 Apr 2009)
@@ -1,5 +1,5 @@
 //
-//  boost/memory/typed_alloc.hpp
+//  boost/memory/object_pool.hpp
 //
 //  Copyright (c) 2004 - 2008 xushiwei (xushiweizh_at_[hidden])
 //
@@ -9,19 +9,28 @@
 //
 //  See http://www.boost.org/libs/memory/index.htm for documentation.
 //
-#ifndef BOOST_MEMORY_TYPED_ALLOC_HPP
-#define BOOST_MEMORY_TYPED_ALLOC_HPP
+#ifndef BOOST_MEMORY_OBJECT_POOL_HPP
+#define BOOST_MEMORY_OBJECT_POOL_HPP
+
+#ifndef BOOST_MEMORY_FIXED_ALLOC_HPP
+#include "fixed_alloc.hpp"
+#endif
+
+#ifndef BOOST_MEMORY_BLOCKPOOL_HPP
+#include "block_pool.hpp"
+#endif
 
 NS_BOOST_MEMORY_BEGIN
 
 // -------------------------------------------------------------------------
-// class norm_typed_alloc
+// class norm_object_pool_
 
 template <class Type, class PolicyT>
-class norm_typed_alloc : private fixed_alloc<PolicyT>
+class norm_object_pool_ : private fixed_alloc<PolicyT>
 {
 private:
         typedef fixed_alloc<PolicyT> PoolT;
+	typedef typename PoolT::alloc_type AllocT;
 
 #pragma pack(1)
 protected:
@@ -35,7 +44,7 @@
         };
 #pragma pack()
 
-protected:
+protected:	
         size_t BOOST_MEMORY_CALL is_allocated_(void*p )
         {
                 return 1 & ((ChunkHeader*)p - 1)->tag;
@@ -55,22 +64,23 @@
         
 public:
         typedef PoolT pool_type;
+	typedef AllocT alloc_type;
         
 public:
         using PoolT::get_alloc;
 
 public:
-	norm_typed_alloc() : PoolT(sizeof(Type))
+	norm_object_pool_() : PoolT(sizeof(Type))
         {
                 BOOST_MEMORY_STATIC_ASSERT(sizeof(ChunkHeader) == sizeof(typename PoolT::ChunkHeader));
         }
         
-	explicit norm_typed_alloc(AllocT alloc) : PoolT(alloc, sizeof(Type))
+	explicit norm_object_pool_(AllocT alloc) : PoolT(alloc, sizeof(Type))
         {
                 BOOST_MEMORY_STATIC_ASSERT(sizeof(ChunkHeader) == sizeof(typename PoolT::ChunkHeader));
         }
         
-	~norm_typed_alloc()
+	~norm_object_pool_()
         {
                 clear();
         }
@@ -79,26 +89,51 @@
         {
                 return *this;
         }
-	
+
+private:
+	void BOOST_MEMORY_CALL do_clear_block_(MemBlock* const blk)
+	{
+		size_t nUsed = blk->nUsed;
+		char* p = blk->buffer + ChunkHeaderSize;
+		for (;; p += this->m_cbChunk)
+		{
+			if (is_allocated_(p))
+			{
+				((Type*)p)->~Type();
+				if (--nUsed == 0)
+					break;
+			}
+		}
+	}
+
 public:
-	__forceinline void BOOST_MEMORY_CALL clear()
+	void BOOST_MEMORY_CALL clear()
         {
-		// ...
+		MemBlock* nextBlk;
+		for (MemBlock* blk = m_blks.first(); !m_blks.done(blk); blk = nextBlk)
+		{
+			nextBlk = blk->next();
+			if (blk->nUsed)
+				do_clear_block_(blk);
+			this->m_alloc.deallocate(blk);
+		}
+		this->m_blks.clear();
+		this->m_freelist.clear();
         }
 
 #if defined(BOOST_MEMORY_NO_STRICT_EXCEPTION_SEMANTICS)
         __forceinline void* BOOST_MEMORY_CALL allocate(size_t cb, destructor_t fn)
         {
-		BOOST_MEMORY_ASSERT(fn == BOOST_MEMORY_DESTRUCTOR(Type));
-		void* p = PoolT::allocate(cb);
-		manage(p, fn);
+		BOOST_MEMORY_ASSERT(cb == sizeof(Type) && fn == BOOST_MEMORY_DESTRUCTOR(Type));
+		void* p = PoolT::allocate();
+		mark_allocated_(p);
                 return p;
         }
 #endif
         
         __forceinline void* BOOST_MEMORY_CALL unmanaged_alloc(size_t cb, destructor_t fn) {
-		BOOST_MEMORY_ASSERT(fn == BOOST_MEMORY_DESTRUCTOR(Type));
-		return PoolT::allocate(cb);
+		BOOST_MEMORY_ASSERT(cb == sizeof(Type) && fn == BOOST_MEMORY_DESTRUCTOR(Type));
+		return PoolT::allocate();
         }
 
         __forceinline void BOOST_MEMORY_CALL manage(void* p, destructor_t fn) {
@@ -106,6 +141,12 @@
                 mark_allocated_(p);
         }
 
+	Type* BOOST_MEMORY_CALL construct() {
+		Type* p = new(PoolT::allocate()) Type;
+		mark_allocated_(p);
+		return p;
+	}
+
         void BOOST_MEMORY_CALL destroy(Type* obj) {
                 mark_deallocated_(obj);
                 obj->~Type();
@@ -114,21 +155,76 @@
 };
 
 // -------------------------------------------------------------------------
-// class typed_alloc
+// class pod_object_pool_
+
+template <class Type, class PolicyT>
+class pod_object_pool_ : private fixed_alloc<PolicyT>
+{
+private:
+	typedef fixed_alloc<PolicyT> PoolT;
+	typedef typename PoolT::alloc_type AllocT;
+
+public:
+	typedef PoolT pool_type;
+	typedef AllocT alloc_type;
+
+public:
+	using PoolT::get_alloc;
+	using PoolT::clear;
+
+public:
+	pod_object_pool_() : PoolT(sizeof(Type)) {}
+
+	explicit pod_object_pool_(AllocT alloc)
+		: PoolT(alloc, sizeof(Type)) {
+	}
+
+	pool_type& BOOST_MEMORY_CALL get_pool() {
+		return *this;
+	}
+
+#if defined(BOOST_MEMORY_NO_STRICT_EXCEPTION_SEMANTICS)
+	__forceinline void* BOOST_MEMORY_CALL allocate(size_t cb, int fnZero) {
+		BOOST_MEMORY_ASSERT(cb == sizeof(Type));
+		return PoolT::allocate();
+	}
+#endif
+
+	__forceinline void* BOOST_MEMORY_CALL unmanaged_alloc(size_t cb, int fnZero) {
+		BOOST_MEMORY_ASSERT(cb == sizeof(Type));
+		return PoolT::allocate();
+	}
+
+	__forceinline void BOOST_MEMORY_CALL manage(void* p, int fnZero) {
+	}
+
+	__forceinline Type* BOOST_MEMORY_CALL construct() {
+		return new (PoolT::allocate()) Type;
+	}
+
+	__forceinline void BOOST_MEMORY_CALL destroy(Type* obj) {
+	}
+};
+
+// -------------------------------------------------------------------------
+// class object_pool_traits
 
 #if defined(_MSC_VER) && (_MSC_VER <= 1200) // VC++ 6.0
 
-template <class Type, class PolicyT, int hasDestructor>
-struct typed_alloc_base_traits_
+template <
+	class Type,
+	class PolicyT = NS_BOOST_MEMORY_POLICY::stdlib,
+	int hasDestructor = destructor_traits<Type>::hasDestructor>
+struct object_pool_traits
 {
         template <int hasDestructor>
         struct traits_ {
-		typedef norm_typed_alloc<Type, PolicyT> type;
+		typedef norm_object_pool_<Type, PolicyT> type;
         };
         
         template <>
         struct traits_<0> {
-		typedef pod_typed_alloc<Type, PolicyT> type;
+		typedef pod_object_pool_<Type, PolicyT> type;
         };
         
         typedef typename traits_<hasDestructor>::type type;
@@ -136,36 +232,36 @@
 
 #else
 
-template <class Type, class PolicyT, int hasDestructor>
-struct typed_alloc_base_traits_ {
-	typedef norm_typed_alloc<Type, PolicyT> type;
+template <
+		class Type,
+		class PolicyT = NS_BOOST_MEMORY_POLICY::stdlib,
+		int hasDestructor = destructor_traits<Type>::hasDestructor>
+struct object_pool_traits {
+	typedef norm_object_pool_<Type, PolicyT> type;
 };
 
 template <class Type, class PolicyT>
-struct typed_alloc_base_traits_<Type, PolicyT, 0> {
-	typedef pod_typed_alloc<Type, PolicyT> type;
+struct object_pool_traits<Type, PolicyT, 0> {
+	typedef pod_object_pool_<Type, PolicyT> type;
 };
 
 #endif
 
-//
-// class typed_alloc
-//
+// -------------------------------------------------------------------------
+// class object_pool
 
-template <class Type, class PolicyT>
-class typed_alloc : 
-	public typed_alloc_base_traits_<Type, PolicyT, destructor_traits<Type>::hasDestructor>::type
+template <class Type, class PolicyT = NS_BOOST_MEMORY_POLICY::stdlib>
+class object_pool : public object_pool_traits<Type, PolicyT>::type
 {
 private:
-	typedef typed_alloc_base_traits_<Type, PolicyT, destructor_traits<Type>::hasDestructor>::type Base;
+	typedef typename object_pool_traits<Type, PolicyT>::type Base;
         typedef typename Base::alloc_type AllocT;
         
 public:
-	typed_alloc() :
-		Base(sizeof(Type)) {
+	__forceinline object_pool() {
         }
-	explicit typed_alloc(AllocT alloc) :
-		Base(alloc, sizeof(Type)) {
+	__forceinline explicit object_pool(AllocT alloc) :
+		Base(alloc) {
         }
 };
 
@@ -174,4 +270,4 @@
 
 NS_BOOST_MEMORY_END
 
-#endif /* BOOST_MEMORY_TYPED_ALLOC_HPP */
+#endif /* BOOST_MEMORY_OBJECT_POOL_HPP */
Deleted: sandbox/memory/boost/memory/typed_alloc.hpp
==============================================================================
--- sandbox/memory/boost/memory/typed_alloc.hpp	2009-04-26 14:49:42 EDT (Sun, 26 Apr 2009)
+++ (empty file)
@@ -1,177 +0,0 @@
-//
-//  boost/memory/typed_alloc.hpp
-//
-//  Copyright (c) 2004 - 2008 xushiwei (xushiweizh_at_[hidden])
-//
-// Distributed under the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-//
-//  See http://www.boost.org/libs/memory/index.htm for documentation.
-//
-#ifndef BOOST_MEMORY_TYPED_ALLOC_HPP
-#define BOOST_MEMORY_TYPED_ALLOC_HPP
-
-NS_BOOST_MEMORY_BEGIN
-
-// -------------------------------------------------------------------------
-// class norm_typed_alloc
-
-template <class Type, class PolicyT>
-class norm_typed_alloc : private fixed_alloc<PolicyT>
-{
-private:
-	typedef fixed_alloc<PolicyT> PoolT;
-
-#pragma pack(1)
-protected:
-	struct ChunkHeader
-	{
-		union
-		{
-			MemBlock* pBlock;
-			size_t tag;
-		};
-	};
-#pragma pack()
-
-protected:
-	size_t BOOST_MEMORY_CALL is_allocated_(void*p )
-	{
-		return 1 & ((ChunkHeader*)p - 1)->tag;
-	}
-	
-	void BOOST_MEMORY_CALL mark_allocated_(void* p)
-	{
-		BOOST_MEMORY_ASSERT(!is_allocated_(p));
-		++((ChunkHeader*)p - 1)->tag;
-	}
-
-	void BOOST_MEMORY_CALL mark_deallocated_(void* p)
-	{
-		BOOST_MEMORY_ASSERT(is_allocated_(p));
-		--((ChunkHeader*)p - 1)->tag;
-	}
-	
-public:
-	typedef PoolT pool_type;
-	
-public:
-	using PoolT::get_alloc;
-
-public:
-	norm_typed_alloc() : PoolT(sizeof(Type))
-	{
-		BOOST_MEMORY_STATIC_ASSERT(sizeof(ChunkHeader) == sizeof(typename PoolT::ChunkHeader));
-	}
-	
-	explicit norm_typed_alloc(AllocT alloc) : PoolT(alloc, sizeof(Type))
-	{
-		BOOST_MEMORY_STATIC_ASSERT(sizeof(ChunkHeader) == sizeof(typename PoolT::ChunkHeader));
-	}
-	
-	~norm_typed_alloc()
-	{
-		clear();
-	}
-
-	pool_type& BOOST_MEMORY_CALL get_pool()
-	{
-		return *this;
-	}
-	
-public:
-	__forceinline void BOOST_MEMORY_CALL clear()
-	{
-		// ...
-	}
-
-#if defined(BOOST_MEMORY_NO_STRICT_EXCEPTION_SEMANTICS)
-	__forceinline void* BOOST_MEMORY_CALL allocate(size_t cb, destructor_t fn)
-	{
-		BOOST_MEMORY_ASSERT(fn == BOOST_MEMORY_DESTRUCTOR(Type));
-		void* p = PoolT::allocate(cb);
-		manage(p, fn);
-		return p;
-	}
-#endif
-	
-	__forceinline void* BOOST_MEMORY_CALL unmanaged_alloc(size_t cb, destructor_t fn) {
-		BOOST_MEMORY_ASSERT(fn == BOOST_MEMORY_DESTRUCTOR(Type));
-		return PoolT::allocate(cb);
-	}
-
-	__forceinline void BOOST_MEMORY_CALL manage(void* p, destructor_t fn) {
-		BOOST_MEMORY_ASSERT(fn == BOOST_MEMORY_DESTRUCTOR(Type));
-		mark_allocated_(p);
-	}
-
-	void BOOST_MEMORY_CALL destroy(Type* obj) {
-		mark_deallocated_(obj);
-		obj->~Type();
-		return PoolT::deallocate(obj);
-	}
-};
-
-// -------------------------------------------------------------------------
-// class typed_alloc
-
-#if defined(_MSC_VER) && (_MSC_VER <= 1200) // VC++ 6.0
-
-template <class Type, class PolicyT, int hasDestructor>
-struct typed_alloc_base_traits_
-{
-	template <int hasDestructor>
-	struct traits_ {
-		typedef norm_typed_alloc<Type, PolicyT> type;
-	};
-	
-	template <>
-	struct traits_<0> {
-		typedef pod_typed_alloc<Type, PolicyT> type;
-	};
-	
-	typedef typename traits_<hasDestructor>::type type;
-};
-
-#else
-
-template <class Type, class PolicyT, int hasDestructor>
-struct typed_alloc_base_traits_ {
-	typedef norm_typed_alloc<Type, PolicyT> type;
-};
-
-template <class Type, class PolicyT>
-struct typed_alloc_base_traits_<Type, PolicyT, 0> {
-	typedef pod_typed_alloc<Type, PolicyT> type;
-};
-
-#endif
-
-//
-// class typed_alloc
-//
-
-template <class Type, class PolicyT>
-class typed_alloc : 
-	public typed_alloc_base_traits_<Type, PolicyT, destructor_traits<Type>::hasDestructor>::type
-{
-private:
-	typedef typed_alloc_base_traits_<Type, PolicyT, destructor_traits<Type>::hasDestructor>::type Base;
-	typedef typename Base::alloc_type AllocT;
-	
-public:
-	typed_alloc() :
-		Base(sizeof(Type)) {
-	}
-	explicit typed_alloc(AllocT alloc) :
-		Base(alloc, sizeof(Type)) {
-	}
-};
-
-// -------------------------------------------------------------------------
-// $Log: $
-
-NS_BOOST_MEMORY_END
-
-#endif /* BOOST_MEMORY_TYPED_ALLOC_HPP */
Modified: sandbox/memory/libs/memory/examples/pool/simple_examples.cpp
==============================================================================
--- sandbox/memory/libs/memory/examples/pool/simple_examples.cpp	(original)
+++ sandbox/memory/libs/memory/examples/pool/simple_examples.cpp	2009-04-26 14:49:42 EDT (Sun, 26 Apr 2009)
@@ -72,11 +72,49 @@
                 alloc.allocate();
 }
 
+int g_nConstruct = 0;
+int g_nDestruct = 0;
+
+struct Obj
+{
+	char m_val[100];
+
+	Obj()		 { ++g_nConstruct; }
+	Obj(int val) { ++g_nConstruct; }
+	~Obj()		 { ++g_nDestruct; }
+};
+
+void testObjectPool()
+{
+	boost::memory::object_pool<int> alloc;
+	int* p1 = alloc.construct();
+	int* p2 = alloc.construct();
+	int* p3 = BOOST_NEW(alloc, int)(30);
+	BOOST_MEMORY_ASSERT(*p3 == 30);
+
+	{
+		boost::memory::object_pool<Obj> alloc2;
+		for (int i = 0; i < 3000; ++i)
+		{
+			Obj* o1 = alloc2.construct();
+			Obj* o2 = alloc2.construct();
+			Obj* o3 = BOOST_NEW(alloc2, Obj)(20);
+			Obj* o4 = BOOST_NEW(alloc2, Obj)(25);
+			alloc2.destroy(o2);
+			alloc2.destroy(o3);
+		}
+	}
+	BOOST_MEMORY_ASSERT(g_nConstruct == g_nDestruct);
+	if (g_nConstruct != g_nDestruct)
+		printf("ERROR: memory leaks!\n");
+}
+
 int main()
 {
         NS_BOOST_MEMORY::enableMemoryLeakCheck();
 
         testPool();
         testScopedPool();
+	testObjectPool();
         return 0;
 }