Browse Source

Allocator. WIP

Panagiotis Christopoulos Charitos 13 years ago
parent
commit
0abb8b4319
4 changed files with 228 additions and 5 deletions
  1. 10 5
      CMakeLists.txt
  2. 156 0
      include/anki/util/Allocator.h
  3. 1 0
      src/renderer/Is.cpp
  4. 61 0
      src/util/Allocator.cpp

+ 10 - 5
CMakeLists.txt

@@ -27,7 +27,12 @@ MESSAGE("++ AnKi SIMD: ${ANKI_MATH_SIMD}")
 
 # Arch
 SET(ANKI_ARCH "0" CACHE STRING "The CPU architecture (0 or 32 or 64). If zero go native")
-MESSAGE("++ AnKi arch: ${ANKI_ARCH}")
+
+IF(ANKI_ARCH STREQUAL "0")
+	MESSAGE("++ AnKi arch: 0 (Native)")
+ELSE()
+	MESSAGE("++ AnKi arch: ${ANKI_ARCH}")
+ENDIF()
 
 IF(NOT ANKI_ARCH STREQUAL "0")
 	SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m${ANKI_ARCH} ")
@@ -84,14 +89,14 @@ ENDIF()
 # Strip
 OPTION(ANKI_STRIP "Srip the symbols from the executables" OFF)
 IF(ANKI_STRIP)
-	MESSAGE("++ Stipping: true")
+	MESSAGE("++ Stipping symbols: true")
 	SET(FLAGS " -s ")
 
 	SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS}")
 	SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}")
 	SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAGS}")
 ELSE()
-	MESSAGE("++ Stipping: false")
+	MESSAGE("++ Stipping symbols: false")
 ENDIF()
 
 # gperftools
@@ -99,10 +104,10 @@ OPTION(ANKI_WITH_GPERFTOOLS_PROF "Link with gperftools profiler" OFF)
 IF(ANKI_WITH_GPERFTOOLS_PROF)
 	LINK_DIRECTORIES("/home/godlike/src/more/gperftools/install/lib")
 	SET(ANKI_GPERFTOOLS_LIBS "profiler")
-	MESSAGE("++ gperftools profiler: true")
+	MESSAGE("++ With gperftools profiler: true")
 ELSE()
 	SET(ANKI_GPERFTOOLS_LIBS "")
-	MESSAGE("++ gperftools profiler: false")
+	MESSAGE("++ With gperftools profiler: false")
 ENDIF()
 
 #

+ 156 - 0
include/anki/util/Allocator.h

@@ -0,0 +1,156 @@
+#ifndef ANKI_UTIL_ALLOCATOR_H
+#define ANKI_UTIL_ALLOCATOR_H
+
+#include "anki/util/Exception.h"
+#include "anki/util/Assert.h"
+#include <cstddef> // For ptrdiff_t
+#include <cstring> // For memset
+#include <atomic>
+
+#define ANKI_DEBUG_ALLOCATORS ANKI_DEBUG
+
+namespace anki {
+
+namespace detail {
+
+/// Static methods for the #Allocator class
+struct AllocatorStatic
+{
+	static PtrSize allocatedSize;
+
+	/// Print a few debugging messages
+	static void dump();
+
+	/// Allocate memory
+	static void* malloc(PtrSize size);
+
+	/// Free memory
+	static void free(void* p, PtrSize size);
+};
+
+} // end namespace detail
+
+/// The default allocator. It uses malloc and free for 
+/// allocations/deallocations. It's STL compatible
+template<typename T>
+class Allocator
+{
+public:
+	// Typedefs
+	typedef size_t size_type;
+	typedef ptrdiff_t difference_type;
+	typedef T* pointer;
+	typedef const T* const_pointer;
+	typedef T& reference;
+	typedef const T& const_reference;
+	typedef T value_type;
+
+	/// Default constructor
+	Allocator() throw()
+	{}
+	/// Copy constructor
+	Allocator(const Allocator&) throw()
+	{}
+	/// Copy constructor with another type
+	template<typename U>
+	Allocator(const Allocator<U>&) throw()
+	{}
+
+	/// Destructor
+	~Allocator()
+	{}
+
+	/// Copy
+	Allocator<T>& operator=(const Allocator&)
+	{
+		return *this;
+	}
+	/// Copy with another type
+	template<typename U>
+	Allocator& operator=(const Allocator<U>&) 
+	{
+		return *this;
+	}
+
+	/// Get address of reference
+	pointer address(reference x) const 
+	{
+		return &x; 
+	}
+	/// Get const address of const reference
+	const_pointer address(const_reference x) const 
+	{
+		return &x;
+	}
+
+	/// Allocate memory
+	pointer allocate(size_type n, const void* = 0)
+	{
+		size_type size = n * sizeof(value_type);
+		return (pointer)AllocatorStatic::malloc(size);
+	}
+
+	/// Deallocate memory
+	void deallocate(void* p, size_type n)
+	{
+		size_type size = n * sizeof(T);
+		AllocatorStatic::free(p, size);
+	}
+
+	/// Call constructor
+	void construct(pointer p, const T& val)
+	{
+		// Placement new
+		new ((T*)p) T(val); 
+	}
+	/// Call constructor with more arguments
+	template<typename U, typename... Args>
+	void construct(U* p, Args&&... args)
+	{
+		// Placement new
+		::new((void*)p) U(std::forward<Args>(args)...);
+	}
+
+	/// Call the destructor of p
+	void destroy(pointer p) 
+	{
+		p->~T();
+	}
+	/// Call the destructor of p of type U
+	template<typename U>
+	void destroy(U* p)
+	{
+		p->~U();
+	}
+
+	/// Get the max allocation size
+	size_type max_size() const 
+	{
+		return size_type(-1); 
+	}
+
+	/// A struct to rebind the allocator to another allocator of type U
+	template<typename U>
+	struct rebind
+	{ 
+		typedef Allocator<U> other; 
+	};
+};
+
+/// Another allocator of the same type can deallocate from this one
+template<typename T1, typename T2>
+inline bool operator==(const Allocator<T1>&, const Allocator<T2>&)
+{
+	return true;
+}
+
+/// Another allocator of the another type cannot deallocate from this one
+template<typename T1, typename AnotherAllocator>
+inline bool operator==(const Allocator<T1>&, const AnotherAllocator&)
+{
+	return false;
+}
+
+} // end namespace anki
+
+#endif

+ 1 - 0
src/renderer/Is.cpp

@@ -154,6 +154,7 @@ struct WriteSpotLightsUbo: ThreadJob
 				0.0, 0.5, 0.0, 0.5, 
 				0.0, 0.0, 0.5, 0.5, 
 				0.0, 0.0, 0.0, 1.0);
+			// bias * proj_l * view_l * world_c
 			slight.texProjectionMat = biasMat4 * light.getProjectionMatrix() *
 				Mat4::combineTransformations(light.getViewMatrix(),
 				Mat4(cam->getWorldTransform()));

+ 61 - 0
src/util/Allocator.cpp

@@ -0,0 +1,61 @@
+#include "anki/util/Allocator.h"
+#include <iostream>
+
+namespace anki {
+
+namespace detail {
+
+//==============================================================================
+PtrSize AllocatorStatic::allocatedSize = 0;
+
+//==============================================================================
+void AllocatorStatic::dump()
+{
+#if ANKI_DEBUG_ALLOCATORS
+	if(allocatedSize > 0)
+	{
+		std::cerr << "You have memory leak of " << allocatedSize 
+			<< " bytes" << std::endl;
+	}
+#endif
+}
+
+//==============================================================================
+void* AllocatorStatic::malloc(PtrSize size)
+{
+	void out = std::malloc(size);
+
+	if(out != nullptr)
+	{
+		// Zero the buffer
+		memset(out, 0, size);
+#if ANKI_DEBUG_ALLOCATORS
+		allocatedSize += size;
+#endif
+	}
+	else
+	{
+		throw ANKI_EXCEPTION("malloc() failed");
+	}
+	
+	return out;
+}
+
+//==============================================================================
+void AllocatorStatic::free(void* p, PtrSize size)
+{
+	std::free(p);
+
+	if(p)
+	{
+#if ANKI_DEBUG_ALLOCATORS
+		allocatedSize -= size;
+#else
+		(void)size; // Make static the analyzer happy
+#endif
+	}
+}
+
+} // end namespace detail
+
+} // end namespace anki