Archived

This topic is now archived and is closed to further replies.

memory manager problems

This topic is 4983 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi i''ve got some problems here. I have been redesigning my memory/resource manager after reading about different tequniques people where using in thier engines (sliding slot and buddy systems) now as far as I know my resource managers are working as they havn''t really been changed but they now include various memory manager classes as member variables, 1 for ram, 1 for hard disk and 1 for vram if nessessary. I think my mem manager has the right ideas going there is just a few implementation details that are wrong, I am basing some of this off of superpigs enginuity articles and I admit I have hardly any knowledge of STL and so all that stuff may be a bit mixed up, slow or there may just be a better way for me to have done these functions. I also havn''t done any pointer arithmetic for ages and so there''s parts of the code that don''t compile because of this. I also think I may be using the smart pointer and memory managed object classes from the enginuity articles a bit wrong. Anyway here is the source code for the memory manager so far (if anyone has difficulty reading it, just post telling me what parts you don''t understand):
template <class T> 
class E_MemBlock : public E_MMObject
{
public:
	T *m_StartLocation;
	unsigned int m_BlockSize; //amount of memory the block has, e.g. 128k etc

	void SetData(T *ptr, unsigned long size)
	{
		memcpy(m_StartLocation, ptr, size); 	
	}
protected:
	unsigned long Size(){return sizeof(*this);}
};

template <class T> 
	class E_MemoryManager
	{
		//=====================================================================

		//variables

		//=====================================================================

	protected:
		std::list<E_SmartPointer<E_MemBlock<T> > > m_FreeBlocks;
		std::list<E_SmartPointer<E_MemBlock<T> > > m_UsedBlocks;

	public:
		//=====================================================================

		//functions

		//=====================================================================

		//----------------------------------------------------------------------

		//the function takes the data type being pointed to (char, int etc)

		//memory is a ptr to the memory that should be managed, size is the

		//total size of the memory.

		//this function then creates a memory block from this data and then stores

		//it in the free blocks list. it then splits the block into 2. it then 

		//recursively splits the 1st block until a block with the lowest

		//memory size is created.

		//the function returns false if this can''t be done and true on success

		//----------------------------------------------------------------------

		bool Create(T *memory, unsigned int size)
		{

			//create a free block with the parameters passed in

			//this is used as the main memory for this manager

			E_MemBlock<T> block;
			block.m_BlockSize = size;
			block.m_StartLocation = memory;
			
			//store original block in the free list

			m_FreeBlocks.insert(m_FreeBlocks.begin(), &block);
			
			//recursively split the block into smaller sizes

			for(; block.m_BlockSize == size / 5;)
			{
				if(!SplitBlock(block))
					break;
			}

			return true;
		}

		//----------------------------------------------------------------------

		//This takes a ptr to a block to be split, the source block should

		//return as half the size as it''s original self, the remainder of the

		//source block is stored in destBlock.

		//the function returns false if the block could not be split and true on

		//success

		//----------------------------------------------------------------------

		bool SplitBlock(E_MemBlock<T> block)
		{
			//find half size of original block

			unsigned int halfSize = block.m_BlockSize / 2;
			
			//create new block with ptr at half way through originals memory and size

			//as half the original

			E_MemBlock<T> newBlock;
			newBlock.m_BlockSize = halfSize;
			newBlock.m_StartLocation = block.m_StartLocation + halfSize;

			//set the original block to have half the size 

			block.m_BlockSize = halfSize;

			//store the new block on the free list

			m_FreeBlocks.insert(m_FreeBlocks.begin(), &newBlock);

			return true;
		}

		//----------------------------------------------------------------------

		//This function takes the size of the required block and trys to find 2 or

		//more blocks free in contiguous memory that it can merge to create a

		//block of the desired size, if it can''t NULL is returned

		//----------------------------------------------------------------------

		E_MemBlock<T> MergeBlock(unsigned int size)
		{
			//sort free blocks so that the memory is as linear as possible

			m_FreeBlocks.sort();

			//find 2 or more adjacent blocks that are linear in memory and that are 

			//large enough in total to create a block as large as size

			std::list<E_SmartPointer<E_MemBlock<T> > >::iterator it;
			
			//loop through the free list

			for(it = m_FreeBlocks.begin(); it != m_FreeBlocks.end(); it++)
			{
				//store the start block

				E_SmartPointer<E_MemBlock<T> > &startBlock = (*it);

							
				//store the total size of the blocks

				unsigned int totalSize = startBlock->m_BlockSize;
				
				//store the number of blocks that are going to be merged

				unsigned int numOfBlocks = 0;
					
				bool linear = true;

				//loop through all the blocks after the start block until we reach a block

				//that is not contiguous in memory from the other ones

				for(it++; linear == true; it++)
				{
					//get the next block

					E_SmartPointer<E_MemBlock<T> > &nextBlock = (*it);
					
					//check if memory is linear

					if(startBlock->m_StartLocation + totalSize != nextBlock->m_StartLocation)
						linear = false;

					numOfBlocks += 1;
					
					//update the total size of all the contiguous blocks

					totalSize += nextBlock->m_BlockSize;
					
					//merge the blocks if enough memory is found

					if(totalSize >= size)
					{
						startBlock->m_BlockSize = totalSize;
						
						//remove and delete all blocks that were merged

						for(it = *startBlock+1; it < *startBlock + numOfBlocks;) // dont know what i need to do here

						{
							E_MemBlock<T> *block = (*it);
							it++;
							m_FreeBlocks.remove(block);
							block = NULL;
						}

						//return the newley merged block

						return startBlock;
					}
				}
			}
			return NULL;
		}

		//----------------------------------------------------------------------

		//This function returns a free block that matches the size, if one can''t

		//be found it trys merging blocks together and splitting larger blocks,

		//if it still can''t find a block then it returns a block with size null

		//, else it returns the block and puts it on the used list

		//----------------------------------------------------------------------

		E_MemBlock<T> GetFreeBlock(unsigned int size)
		{
			//search the list for a block that matches size

			//if one is found return it

			std::list<E_SmartPointer<E_MemBlock<T> > >::iterator it;
			
			//loop through the free list

			for(it = m_FreeBlocks.begin(); it != m_FreeBlocks.end(); it++)
			{
				E_SmartPointer<E_MemBlock<T> > &block = (*it);
				if(block->m_BlockSize == size)
				{
					m_FreeBlocks.remove(block);
					m_UsedBlocks.insert(m_UsedBlocks.begin(), block);
					return *block;
				}
			}

			//else

			//try merging blocks

			E_MemBlock<T> mergedBlock;
			mergedBlock.m_BlockSize = 0;
			mergedBlock = MergeBlock(size);

			if(mergedBlock.m_BlockSize != 0)
			{
				m_FreeBlocks.remove(&mergedBlock);
				m_UsedBlocks.insert(m_UsedBlocks.begin(), &mergedBlock);
				return mergedBlock;
			}

			//else try spliting larger blocks 

			for(it = m_FreeBlocks.begin(); it != m_FreeBlocks.end(); it++)
			{
				E_SmartPointer<E_MemBlock<T> > &block = (*it);
				if(block->m_BlockSize >= size)
				{
					do
					{
						SplitBlock(*block);
						if(block->m_BlockSize == size)
						{
							//return the free block and put it on the used list

							m_FreeBlocks.remove(block);
							m_UsedBlocks.insert(m_UsedBlocks.begin(), block);
							return *block;
						}
					}while(block->m_BlockSize >= size);
				}
			}
			return mergedBlock; //wanted to return NULL so that memory wasn''t wasted

								//now it looks like the caller will need to delete this

		}

		//----------------------------------------------------------------------

		//this function releses it''s memory and is put on the free blocks list

		//----------------------------------------------------------------------

		bool ReleaseBlock(E_MemBlock<T> block)
		{
			//put the block on the free list

			return true;
		}
If anyone cares to go through the code and point out what''s wrong with it (everythng ;-) ) or give tips on better ways to do some of the code (like speeding it up or makeing it easier to read etc) I''d be greatful. Cheers!

Share this post


Link to post
Share on other sites
Could someone please help? should i have this in another forum?
This effects quite a big part of my engine, and although i could revert back to the older version, this looks like a much better way to handle resources

Share this post


Link to post
Share on other sites
I''m guessing the reason you haven''t gotten any responses is that thats an awful lot of code and a terribly vague request. Plus just looking at the indentation, its not entirely clear that the complete code is there. Maybe if you had more specific questions about smaller sections of the code, you would get more responses.

Share this post


Link to post
Share on other sites