My Site
  • Home
  • Games
  • Code Samples
    • StringPool
    • Multithreaded File Processor
    • Swept Separation Axis Collision Detection
    • SmallBlockAllocator
    • MemoryManager
  • Contact
  • Resume
My implementation of a Memory Manager
MemoryManager.h
#ifndef _MEMORY_MANAGER_H
#define _MEMORY_MANAGER_H

#include 
#include 

#include "SmallBlockAllocator.h"

#define MemoryManagerHeap 1024 * 1024

class MemoryManager
{
public:
	static void CreateMemoryManager();
	static void DestroyMemoryManager();

	static void *alloc(size_t i_size);
	static void dealloc(void* i_pBasePointer);
private:
	static void CoalesceFreeBlocks(void* i_pBasePointer);

	std::map m_SmallBlockAllocators;
	std::map m_FreeBlocks;
	std::map m_OutStandingBlocks;
	void * m_pMemoryHeap;
	size_t m_AllocatedSize;
	MemoryManager();
	~MemoryManager();
	static MemoryManager *m_pInstance;
};

typedef std::map SmallBlockAllocatorMap;
typedef std::map FreeBlockMap;
typedef std::map OutStandingBlockMap;

#endif // End of MemoryManager.h
MemoryManager.cpp
#include "MemoryManager.h"

MemoryManager* MemoryManager::m_pInstance = NULL;
MemoryManager::MemoryManager()
{
	// Allocate a single block of memory of size 1MB
	m_pMemoryHeap = _aligned_malloc(MemoryManagerHeap, 4);
	m_AllocatedSize = 0;
	m_SmallBlockAllocators.insert(std::make_pair(4, SmallBlockAllocator::Create(4, 100)));
	m_SmallBlockAllocators.insert(std::make_pair(8, SmallBlockAllocator::Create(8, 100)));
	m_SmallBlockAllocators.insert(std::make_pair(16, SmallBlockAllocator::Create(16, 100)));
}

MemoryManager::~MemoryManager()
{
	_aligned_free(m_pMemoryHeap);
	SmallBlockAllocatorMap::iterator SBAIterator = m_SmallBlockAllocators.begin();
	for (size_t iterator = 0; iterator < m_SmallBlockAllocators.size(); iterator++)
	{
		SmallBlockAllocator::Destroy(m_SmallBlockAllocators[iterator]);
	}
}

void MemoryManager::CreateMemoryManager()
{
	if (m_pInstance == NULL)
	{
		m_pInstance = new MemoryManager();
	}
}

void MemoryManager::DestroyMemoryManager()
{
	assert(m_pInstance);
	delete m_pInstance;
	m_pInstance = NULL;
}

void* MemoryManager::alloc(size_t i_size)
{
	assert(m_pInstance);

	// Check if we can use the Small Block Allocators to allocate memory.
	SmallBlockAllocatorMap::iterator itSBA = m_pInstance->m_SmallBlockAllocators.find(i_size);
	if (itSBA != m_pInstance->m_SmallBlockAllocators.end())
	{
		return itSBA->second->alloc(i_size);
	}

	// Size is bigger for Small Block Allocators to handle
	// Memory Manager will allocate the memory
	if (m_pInstance->m_FreeBlocks.size() == 0)
	{
		m_pInstance->m_AllocatedSize += i_size;
		m_pInstance->m_OutStandingBlocks.insert(std::make_pair(m_pInstance->m_pMemoryHeap, i_size));
		void *pNextFreePointer = static_cast(m_pInstance->m_pMemoryHeap) + i_size;
		if (static_cast(pNextFreePointer) < static_cast(m_pInstance->m_pMemoryHeap) + MemoryManagerHeap)
		{
			m_pInstance->m_FreeBlocks.insert(std::make_pair(pNextFreePointer, MemoryManagerHeap - m_pInstance->m_AllocatedSize));
		}
		return m_pInstance->m_pMemoryHeap;
	}
	else if (i_size <= MemoryManagerHeap - m_pInstance->m_AllocatedSize)
	{
		FreeBlockMap::iterator itFreeBlocks = m_pInstance->m_FreeBlocks.begin();
		for (; itFreeBlocks != m_pInstance->m_FreeBlocks.end(); itFreeBlocks++)
		{
			if (itFreeBlocks->second >= i_size)
			{
				m_pInstance->m_AllocatedSize += i_size;
				m_pInstance->m_OutStandingBlocks.insert(std::make_pair(itFreeBlocks->first, i_size));
				void *pNextFreePointer = static_cast(itFreeBlocks->first) + i_size;
				if (itFreeBlocks->second - i_size != 0)
					m_pInstance->m_FreeBlocks.insert(std::make_pair(pNextFreePointer, itFreeBlocks->second - i_size));
				void *pMemoryPointer = itFreeBlocks->first;
				m_pInstance->m_FreeBlocks.erase(itFreeBlocks);
				return pMemoryPointer;
			}
		}

		return NULL;
	}
	else
		return NULL;
}

void MemoryManager::dealloc(void* i_pBasePointer)
{
	assert(m_pInstance);
	OutStandingBlockMap::iterator itOutStandingBlock = m_pInstance->m_OutStandingBlocks.find(i_pBasePointer);
	if (itOutStandingBlock != m_pInstance->m_OutStandingBlocks.end())
	{
		m_pInstance->m_FreeBlocks.insert(std::make_pair(i_pBasePointer, itOutStandingBlock->second));
		m_pInstance->m_OutStandingBlocks.erase(itOutStandingBlock);
		if (m_pInstance->m_FreeBlocks.size() >= 2)
			CoalesceFreeBlocks(i_pBasePointer);
	}
}

void MemoryManager::CoalesceFreeBlocks(void* i_pBasePointer)
{
	assert(m_pInstance);
	FreeBlockMap::iterator itFreeBlock = m_pInstance->m_FreeBlocks.find(i_pBasePointer);
	void *pAdjacentPointer = static_cast(i_pBasePointer)+itFreeBlock->second;
	FreeBlockMap::iterator itAdjacentFreeBlock = m_pInstance->m_FreeBlocks.find(pAdjacentPointer);
	
	while (itAdjacentFreeBlock != m_pInstance->m_FreeBlocks.end())
	{
		itFreeBlock->second += itAdjacentFreeBlock->second;
		m_pInstance->m_FreeBlocks.erase(itAdjacentFreeBlock);
		pAdjacentPointer = static_cast(i_pBasePointer)+itFreeBlock->second;
		itAdjacentFreeBlock = m_pInstance->m_FreeBlocks.find(pAdjacentPointer);
	}

	if (m_pInstance->m_FreeBlocks.size() >= 2)
	{
		FreeBlockMap::iterator itFreeBlockIterator = m_pInstance->m_FreeBlocks.begin();
		for (; itFreeBlockIterator != m_pInstance->m_FreeBlocks.end(); itFreeBlockIterator++)
		{
			pAdjacentPointer = static_cast(itFreeBlockIterator->first)+itFreeBlockIterator->second;
			if (pAdjacentPointer == i_pBasePointer)
			{
				itFreeBlockIterator->second += itFreeBlock->second;
				m_pInstance->m_FreeBlocks.erase(itFreeBlock);
			}
		}
	}
}
Powered by Create your own unique website with customizable templates.
  • Home
  • Games
  • Code Samples
    • StringPool
    • Multithreaded File Processor
    • Swept Separation Axis Collision Detection
    • SmallBlockAllocator
    • MemoryManager
  • Contact
  • Resume