Kaynağa Gözat

Allocator unit tests

Panagiotis Christopoulos Charitos 13 yıl önce
ebeveyn
işleme
84fdbce3ec

+ 14 - 0
include/anki/scene/Common.h

@@ -0,0 +1,14 @@
+#ifndef ANKI_SCENE_COMMON_H
+#define ANKI_SCENE_COMMON_H
+
+#include "anki/util/Allocator.h"
+
+namespace anki {
+
+/// The type of the scene's allocator
+template<typename T>
+using SceneAllocator = StackAllocator<T, false>;
+
+} // end namespace anki
+
+#endif

+ 1 - 5
include/anki/scene/SceneNode.h

@@ -2,7 +2,7 @@
 #define ANKI_SCENE_SCENE_NODE_H
 #define ANKI_SCENE_SCENE_NODE_H
 
 
 #include "anki/scene/Property.h"
 #include "anki/scene/Property.h"
-#include "anki/util/Allocator.h"
+#include "anki/scene/Common.h"
 #include <string>
 #include <string>
 
 
 namespace anki {
 namespace anki {
@@ -20,10 +20,6 @@ class RigidBody;
 /// @addtogroup Scene
 /// @addtogroup Scene
 /// @{
 /// @{
 
 
-/// XXX
-template<typename T>
-using SceneAllocator = StackAllocator<T, false>;
-
 /// Interface class backbone of scene
 /// Interface class backbone of scene
 class SceneNode: public PropertyMap
 class SceneNode: public PropertyMap
 {
 {

+ 20 - 8
include/anki/util/Allocator.h

@@ -28,7 +28,7 @@ public:
 	static void dump();
 	static void dump();
 
 
 protected:
 protected:
-	/// Keep track of the allocated size. Relevant only when we debugging
+	/// Keep track of the allocated size. Relevant only when debugging
 	static PtrSize allocatedSize;
 	static PtrSize allocatedSize;
 
 
 	/// Allocate memory
 	/// Allocate memory
@@ -225,8 +225,9 @@ public:
 	typedef const T& const_reference;
 	typedef const T& const_reference;
 	typedef T value_type;
 	typedef T value_type;
 
 
-	/// Default constructor deleted
-	StackAllocator() = delete;
+	/// Default constructor
+	StackAllocator() throw()
+	{}
 	/// Copy constructor
 	/// Copy constructor
 	StackAllocator(const StackAllocator& b) throw()
 	StackAllocator(const StackAllocator& b) throw()
 	{
 	{
@@ -254,9 +255,13 @@ public:
 	/// Copy
 	/// Copy
 	StackAllocator& operator=(const StackAllocator& b)
 	StackAllocator& operator=(const StackAllocator& b)
 	{
 	{
+		deinit();
 		mpool = b.mpool;
 		mpool = b.mpool;
-		// Retain the mpool
-		++mpool->refCounter;
+		if(mpool)
+		{
+			// Retain the mpool
+			++mpool->refCounter;
+		}
 		return *this;
 		return *this;
 	}
 	}
 	/// Copy
 	/// Copy
@@ -264,9 +269,13 @@ public:
 	StackAllocator& operator=(
 	StackAllocator& operator=(
 		const StackAllocator<U, deallocationFlag, alignmentBits>& b)
 		const StackAllocator<U, deallocationFlag, alignmentBits>& b)
 	{
 	{
+		deinit();
 		mpool = b.mpool;
 		mpool = b.mpool;
-		// Retain the mpool
-		++mpool->refCounter;
+		if(mpool)
+		{
+			// Retain the mpool
+			++mpool->refCounter;
+		}
 		return *this;
 		return *this;
 	}
 	}
 
 
@@ -284,6 +293,7 @@ public:
 	/// Allocate memory
 	/// Allocate memory
 	pointer allocate(size_type n, const void* hint = 0)
 	pointer allocate(size_type n, const void* hint = 0)
 	{
 	{
+		ANKI_ASSERT(mpool != nullptr);
 		(void)hint;
 		(void)hint;
 		size_type size = n * sizeof(value_type);
 		size_type size = n * sizeof(value_type);
 		size_type alignedSize = calcAlignSize(size);
 		size_type alignedSize = calcAlignSize(size);
@@ -312,6 +322,7 @@ public:
 	/// Deallocate memory
 	/// Deallocate memory
 	void deallocate(void* p, size_type n)
 	void deallocate(void* p, size_type n)
 	{
 	{
+		ANKI_ASSERT(mpool != nullptr);
 		(void)p;
 		(void)p;
 		(void)n;
 		(void)n;
 
 
@@ -364,6 +375,7 @@ public:
 	/// Get the max allocation size
 	/// Get the max allocation size
 	size_type max_size() const
 	size_type max_size() const
 	{
 	{
+		ANKI_ASSERT(mpool != nullptr);
 		return mpool->size;
 		return mpool->size;
 	}
 	}
 
 
@@ -377,6 +389,7 @@ public:
 	/// Reinit the allocator. All existing allocated memory will be lost
 	/// Reinit the allocator. All existing allocated memory will be lost
 	void reset()
 	void reset()
 	{
 	{
+		ANKI_ASSERT(mpool != nullptr);
 		mpool->ptr = mpool->memory;
 		mpool->ptr = mpool->memory;
 	}
 	}
 
 
@@ -406,7 +419,6 @@ inline bool operator==(
 {
 {
 	return false;
 	return false;
 }
 }
-
 /// @}
 /// @}
 /// @}
 /// @}
 
 

+ 1 - 0
include/anki/util/NonCopyable.h

@@ -6,6 +6,7 @@ namespace anki {
 /// @addtogroup util
 /// @addtogroup util
 /// @{
 /// @{
 /// @addtogroup patterns
 /// @addtogroup patterns
+/// @{
 
 
 /// Makes a derived class non copyable
 /// Makes a derived class non copyable
 struct NonCopyable
 struct NonCopyable

+ 4 - 1
include/anki/util/Object.h

@@ -10,6 +10,8 @@ namespace anki {
 
 
 /// @addtogroup util
 /// @addtogroup util
 /// @{
 /// @{
+/// @addtogroup patterns
+/// @{
 
 
 /// A hierarchical object
 /// A hierarchical object
 template<typename T>
 template<typename T>
@@ -75,7 +77,7 @@ public:
 		return childs.end();
 		return childs.end();
 	}
 	}
 
 
-	size_t getChildrenSize() const
+	PtrSize getChildrenSize() const
 	{
 	{
 		return childs.size();
 		return childs.size();
 	}
 	}
@@ -112,6 +114,7 @@ private:
 	Container childs;
 	Container childs;
 };
 };
 /// @}
 /// @}
+/// @}
 
 
 } // end namespace anki
 } // end namespace anki
 
 

+ 20 - 23
src/util/Allocator.cpp

@@ -71,6 +71,7 @@ namespace detail {
 //==============================================================================
 //==============================================================================
 void StackAllocatorInternal::init(const PtrSize size)
 void StackAllocatorInternal::init(const PtrSize size)
 {
 {
+	ANKI_ASSERT(mpool == nullptr);
 	mpool = new detail::MemoryPool;
 	mpool = new detail::MemoryPool;
 
 
 	if(mpool != nullptr)
 	if(mpool != nullptr)
@@ -83,24 +84,16 @@ void StackAllocatorInternal::init(const PtrSize size)
 			mpool->ptr = mpool->memory;
 			mpool->ptr = mpool->memory;
 			// Memory pool's refcounter is 1
 			// Memory pool's refcounter is 1
 #if ANKI_PRINT_ALLOCATOR_MESSAGES
 #if ANKI_PRINT_ALLOCATOR_MESSAGES
-		std::cout << "New MemoryPool created: Address: " << mpool
-			<< ", size: " << size
-			<< ", pool address: " << mpool->memory << std::endl;
+			std::cout << "New MemoryPool created: Address: " << mpool
+				<< ", size: " << size
+				<< ", pool address: " << mpool->memory << std::endl;
 #endif
 #endif
 			return;
 			return;
 		}
 		}
-	}
-
-	// Errors happened
-
-	if(mpool->memory)
-	{
-		::free(mpool->memory);
-	}
-
-	if(mpool)
-	{
-		delete mpool;
+		else
+		{
+			delete mpool;
+		}
 	}
 	}
 
 
 	std::cerr << "Stack allocator constuctor failed. I will cannot "
 	std::cerr << "Stack allocator constuctor failed. I will cannot "
@@ -111,18 +104,22 @@ void StackAllocatorInternal::init(const PtrSize size)
 //==============================================================================
 //==============================================================================
 void StackAllocatorInternal::deinit()
 void StackAllocatorInternal::deinit()
 {
 {
-	int refCounter = mpool->refCounter.fetch_sub(1);
-
-	if(mpool && (refCounter - 1) == 0)
+	if (mpool)
 	{
 	{
+		I32 refCounter = mpool->refCounter.fetch_sub(1);
+
+		if(refCounter == 1)
+		{
 #if ANKI_PRINT_ALLOCATOR_MESSAGES
 #if ANKI_PRINT_ALLOCATOR_MESSAGES
-		std::cout << "Deleting MemoryPool " << mpool << std::endl;
+			std::cout << "Deleting MemoryPool " << mpool << std::endl;
 #endif
 #endif
-		// It is safe to delete the memory pool
-		ANKI_ASSERT(mpool->refCounter == 0);
+			// It is safe to delete the memory pool
+			ANKI_ASSERT(mpool->refCounter == 0);
 
 
-		::free(mpool->memory);
-		delete mpool;
+			::free(mpool->memory);
+			delete mpool;
+			mpool = nullptr;
+		}
 	}
 	}
 }
 }
 
 

+ 18 - 0
tests/util/Allocator.cpp

@@ -0,0 +1,18 @@
+#include "tests/framework/Framework.h"
+#include "tests/util/Foo.h"
+#include "anki/util/Allocator.h"
+#include <string>
+
+ANKI_TEST(Allocator, StackAllocator)
+{
+	StackAllocator<char> alloc(12);
+	typedef std::basic_string<char, std::char_traits<char>, 
+		StackAllocator<char>> Str;
+
+	{
+		Str str(alloc);
+
+		str = "lalala";
+	}
+}
+

+ 4 - 0
tests/util/Foo.cpp

@@ -0,0 +1,4 @@
+#include "tests/util/Foo.h"
+
+int Foo::constructorCallCount = 0;
+int Foo::destructorCallCount = 0;

+ 17 - 3
tests/util/Foo.h

@@ -5,22 +5,36 @@
 struct Foo
 struct Foo
 {
 {
 	int x = 666;
 	int x = 666;
+	static int constructorCallCount;
+	static int destructorCallCount;
 
 
 	Foo()
 	Foo()
-	{}
+	{
+		++constructorCallCount;
+	}
 
 
 	Foo(int x_)
 	Foo(int x_)
 		: x(x_)
 		: x(x_)
-	{}
+	{
+		++constructorCallCount;
+	}
 
 
 	Foo(const Foo& b)
 	Foo(const Foo& b)
 		: x(b.x)
 		: x(b.x)
-	{}
+	{
+		++constructorCallCount;
+	}
 
 
 	Foo(Foo&& b)
 	Foo(Foo&& b)
 		: x(b.x)
 		: x(b.x)
 	{
 	{
 		b.x = 0;
 		b.x = 0;
+		++constructorCallCount;
+	}
+
+	~Foo()
+	{
+		++destructorCallCount;
 	}
 	}
 
 
 	Foo& operator=(const Foo& b)
 	Foo& operator=(const Foo& b)