⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memorypool.cpp

📁 这个是symbian下的一个蛮庞大的3D游戏源代码!对于学习3D开发的人有很大的帮助!
💻 CPP
字号:
#include <lang/MemoryPool.h>
#include <lang/String.h>
#include <lang/algorithm/quicksort.h>
#include <lang/Globals.h>
#include "dprintf.h"
#include <string.h>
#ifdef WIN32
#include "dprintf.h"
#endif
#include <config.h>


namespace lang
{

	
static const int BLOCK_ALIGNMENT = 4;


MemoryPool::MemoryPool( int size, int maxsize, const char* name ) :
	m_maxSize( maxsize ),
	m_next( 0 ),
	m_maxgctime( 0 )
{
	resize( size );

	if ( 0 == m_maxSize )
		m_maxSize = 0x7FFFFFFF;

	String::cpy( m_name, sizeof(m_name), name );
}

MemoryPool::~MemoryPool()
{
	//Debug::printf( "lang: Destroying MemoryPool \"%s\". Max time spend in compact() was %d ms.\n", m_name, m_maxgctime );

	for ( int i = 0 ; i < m_blocks.size() ; ++i )
	{
		//if ( 0 != m_blocks[i] )
		//	Debug::printf( "ERROR: lang.~MemoryPool: Memory still in use: \"%s\"\n", m_blocks[i] );
		assert( 0 == m_blocks[i] );
	}
}

void MemoryPool::dump() const
{
#ifdef WIN32
	dprintf( "Dumping memory pool \"%s\":\n", m_name );
	dprintf( "(%d blocks, %d bytes, %d byte pool size)\n", m_blocks.size(), m_next, m_mem.size() );
	for ( int i = 0 ; i < m_blocks.size() ; ++i )
	{
		char* p = m_blocks[i];
		if ( p != 0 )
		{
			BlockHeader* header = reinterpret_cast<BlockHeader*>(p)-1;
			dprintf( "  block[%d]: ptr=%x, size=%d, refs=%d, data='%s'\n", i, (int)header, header->size, header->refs, m_blocks[i] );
		}
		else
			dprintf( "  block[%d]: null\n", i );
	}
	dprintf( "\n" );
#endif
}

int MemoryPool::allocate( int bytes )
{
	// make sure there is enough space
	int spaceneeded = bytes+BLOCK_ALIGNMENT+(int)sizeof(BlockHeader);
	if ( m_next+spaceneeded > size() )
	{
		compact();
		if ( m_next+spaceneeded > size() && m_next+spaceneeded <= m_maxSize )
		{
			resize( m_mem.size() + spaceneeded );

			if ( m_next+spaceneeded > size() )
			{
				INTERNAL_ERROR();
				//throwError( OutOfMemoryException() );
			}
		}
	}

	// get release memory block index
	int index;
	if ( m_freed.size() > 0 )
	{
		index = m_freed.last();
		m_freed.resize( m_freed.size()-1 );
	}
	else
	{
		index = m_blocks.size();
		m_blocks.add( 0 );
	}
	assert( index >= 0 && index < m_blocks.size() );
	
	// align next block pointer
	m_next = (m_next+BLOCK_ALIGNMENT-1) & ~(BLOCK_ALIGNMENT-1);
	
	// allocate block
	bytes += sizeof(BlockHeader);
	char* mem = m_mem.begin() + m_next;
	BlockHeader* header = reinterpret_cast<BlockHeader*>(mem);
	header->size = bytes;
	header->refs = 1;
	m_blocks[index] = mem + sizeof(BlockHeader);
	m_next += bytes;
	
	return index;
}

void MemoryPool::unalloc( int handle )
{
	assert( m_blocks[handle] );
	assert( (reinterpret_cast<BlockHeader*>(m_blocks[handle])-1)->refs == 0 );
	
	m_freed.add( handle );
	m_blocks[handle] = 0;
}

void MemoryPool::compact()
{
#ifdef WIN32
	//dprintf( "lang: MemoryPool::compact(), before:\n" );
	//dump();
#endif

	// sort to ascending memory addresses
	TRACEF(1);
	dprintf( "m_gcbuf.resize( %d )\n", m_blocks.size() );
	m_gcbuf.resize( m_blocks.size() );
	TRACEF(1);
	for ( int i = 0 ; i < m_blocks.size() ; ++i )
		m_gcbuf[i] = i;
	TRACEF(1);
	LANG_SORT( m_gcbuf.begin(), m_gcbuf.end(), HandleSorter(this) );
	TRACEF(1);
	
	// remove gaps
	TRACEF(1);
	m_next = 0;
	for ( int i = 0 ; i < m_gcbuf.size() ; ++i )
	{
		int index = m_gcbuf[i];
		char* src =  m_blocks[index];
		if ( src != 0 )
		{
			BlockHeader* header = reinterpret_cast<BlockHeader*>(src)-1;
			int size = header->size;
			
			// align next block pointer
			m_next = (m_next+BLOCK_ALIGNMENT-1) & ~(BLOCK_ALIGNMENT-1);
			
			char* dst = m_mem.begin() + m_next;
			assert( m_next+size <= m_mem.size() );
			memmove( dst, header, size );
			m_next += size;
			
			m_blocks[index] = dst + sizeof(BlockHeader);
		}
	}

	TRACEF(1);

#ifdef WIN32
	//dprintf( "lang: MemoryPool::compact(), after:\n" );
	//dump();
#endif
}

int MemoryPool::blocksAllocated() const
{
	assert( m_blocks.size() >= m_freed.size() );
	return m_blocks.size() - m_freed.size();
}

void MemoryPool::resize( int newsize )
{
	assert( newsize > m_mem.size() );

	// make sure the memory size grows at least 50%
	int minsize = m_mem.size() * 3 >> 1;
	minsize = (minsize+15) & ~15;
	if ( newsize < minsize )
		newsize = minsize;

	m_gcbuf.resize( m_blocks.size() );
	for ( int i = 0 ; i < m_blocks.size() ; ++i )
		m_gcbuf[i] = m_blocks[i] != 0 ? m_blocks[i] - m_mem.begin() : -1;
	
	m_mem.resize( newsize );
	
	m_blocks.clear();
	for ( int i = 0 ; i < m_gcbuf.size() ; ++i )
		m_blocks.add( m_gcbuf[i] != -1 ? m_gcbuf[i] + m_mem.begin() : 0 );
}


} // lang


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -