Daniele Bartolini 12 лет назад
Родитель
Сommit
8fe94232ec
4 измененных файлов с 191 добавлено и 0 удалено
  1. 2 0
      src/CMakeLists.txt
  2. 1 0
      src/Crown.h
  3. 114 0
      src/core/mem/StackAllocator.cpp
  4. 74 0
      src/core/mem/StackAllocator.h

+ 2 - 0
src/CMakeLists.txt

@@ -153,6 +153,7 @@ set (MEM_SRC
 	core/mem/Allocator.cpp
 	core/mem/Allocator.cpp
 	core/mem/MallocAllocator.cpp
 	core/mem/MallocAllocator.cpp
 	core/mem/LinearAllocator.cpp
 	core/mem/LinearAllocator.cpp
+	core/mem/StackAllocator.cpp
 	core/mem/ProxyAllocator.cpp
 	core/mem/ProxyAllocator.cpp
 )
 )
 
 
@@ -162,6 +163,7 @@ set (MEM_HEADERS
 	core/mem/Allocator.h
 	core/mem/Allocator.h
 	core/mem/MallocAllocator.h
 	core/mem/MallocAllocator.h
 	core/mem/LinearAllocator.h
 	core/mem/LinearAllocator.h
+	core/mem/StackAllocator.h
 	core/mem/ProxyAllocator.h
 	core/mem/ProxyAllocator.h
 )
 )
 
 

+ 1 - 0
src/Crown.h

@@ -75,6 +75,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Allocator.h"
 #include "Allocator.h"
 #include "MallocAllocator.h"
 #include "MallocAllocator.h"
 #include "LinearAllocator.h"
 #include "LinearAllocator.h"
+#include "StackAllocator.h"
 #include "ProxyAllocator.h"
 #include "ProxyAllocator.h"
 
 
 // Core/Filesystem
 // Core/Filesystem

+ 114 - 0
src/core/mem/StackAllocator.cpp

@@ -0,0 +1,114 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "StackAllocator.h"
+#include "OS.h"
+
+namespace crown
+{
+
+//-----------------------------------------------------------------------------
+StackAllocator::StackAllocator(void* start, size_t size) :
+	m_physical_start(start),
+	m_total_size(size),
+	m_top(start),
+	m_allocation_count(0)
+{
+}
+
+//-----------------------------------------------------------------------------
+StackAllocator::~StackAllocator()
+{
+	CE_ASSERT(m_allocation_count == 0 && allocated_size() == 0,
+		"Missing %d deallocations causing a leak of %d bytes", m_allocation_count, allocated_size());
+}
+
+//-----------------------------------------------------------------------------
+void* StackAllocator::allocate(size_t size, size_t align)
+{
+	const size_t actual_size = sizeof(Header) + size + align;
+
+	// Memory exhausted
+	if ((char*) m_top + actual_size > (char*) m_physical_start + m_total_size)
+	{
+		return NULL;
+	}
+
+	// The offset from TOS to the start of the buffer
+	uint32_t offset = (char*) m_top - (char*) m_physical_start;
+
+	// Align user data only, ignore header alignment
+	m_top = (char*) memory::align_top((char*) m_top + sizeof(Header), align) - sizeof(Header);
+
+	Header* header = (Header*) m_top;
+	header->offset = offset;
+	header->alloc_id = m_allocation_count;
+
+	void* user_ptr = (char*) m_top + sizeof(Header);
+	m_top = (char*) m_top + actual_size;
+
+	m_allocation_count++;
+
+	return user_ptr;
+}
+
+//-----------------------------------------------------------------------------
+void StackAllocator::deallocate(void* data)
+{
+	Header* data_header = (Header*) ((char*)data - sizeof(Header));
+
+	CE_ASSERT(data_header->alloc_id == m_allocation_count - 1,
+		"Deallocations must occur in LIFO order");
+
+	m_top = (char*) m_physical_start + data_header->offset;
+
+	m_allocation_count--;
+}
+
+//-----------------------------------------------------------------------------
+size_t StackAllocator::allocated_size()
+{
+	return (char*) m_top - (char*) m_physical_start;
+}
+
+//-----------------------------------------------------------------------------
+void StackAllocator::dump()
+{
+	uint8_t* mem = (uint8_t*)m_physical_start;
+	for (size_t i = 0; i < allocated_size(); i++)
+	{
+		if ((i % sizeof(void*)) == 0)
+		{
+			os::printf("\n");
+			os::printf("%.2X = ", (size_t)(&mem[i]) & 0xFF);
+		}
+		os::printf("%.2X ", mem[i]);
+	}
+
+	os::printf("\n");
+}
+
+} // namespace crown

+ 74 - 0
src/core/mem/StackAllocator.h

@@ -0,0 +1,74 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#pragma once
+
+#include "Allocator.h"
+
+namespace crown
+{
+
+/// Allocates memory linearly in a stack-like fashion from a
+/// predefined chunk. All deallocations must occur in LIFO
+/// order.
+class StackAllocator : public Allocator
+{
+public:
+
+				StackAllocator(void* start, size_t size);
+				~StackAllocator();
+
+	/// @copydoc Allocator::allocate()
+	void*		allocate(size_t size, size_t align = memory::DEFAULT_ALIGN);
+
+	/// @copydoc Allocator::deallocate()
+	/// @note
+	/// Deallocations must occur in LIFO order i.e. the
+	/// last allocation must be freed for first.
+	void		deallocate(void* data);
+
+	/// @copydoc Allocator::allocated_size()
+	size_t		allocated_size();
+
+	void		dump();
+
+private:
+
+	struct Header
+	{
+		uint32_t offset;
+		uint32_t alloc_id;
+	};
+
+	void*		m_physical_start;
+	size_t		m_total_size;
+
+	void*		m_top;
+
+	uint32_t	m_allocation_count;
+};
+
+} // namespace crown