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

📄 xmemory.h

📁 HTTP 搜索代码
💻 H
字号:
/*********************************************************************************************
*	凤凰网络.dragon
*
*	xMemory.h( xLib+ 虚拟内存页内存分配器 )
*
*	(2006-06-21) 创建,增加内存对齐的const
*	(2006-06-22) 增加构造和析构函数调用的两个inline
*					
*
**********************************************************************************************/
#pragma once
#include <new>
#define PAGE_SIZE	4096

const DWORD MEMORY_ALIGN = 4;

#define ALIGNMEM( osize ) ((osize)+(MEMORY_ALIGN-((osize)&(MEMORY_ALIGN-1))))


template <class T>
inline T * CALL_CON( T * ptMem )
{
	//if( pMem & 3 )
	//{
	//	pMem += (4-(pMem&3));
	//}
	T * pt = new(ptMem)T;
	return pt;
}

template <class T>
inline void CALL_DEC( T * pt )
{
	pt->~T();
}


class xMemory
{
public:
	xMemory( DWORD dwReservedSize = 0, DWORD dwInitlizeSize = 0 )
	{
		m_dwMaxSize = 0;
		m_dwCurSize = 0;
		m_pBaseAddr = 0;
		if( dwReservedSize > 0 )
		{
			Create( dwReservedSize, dwInitlizeSize );
		}
	}

	~xMemory()
	{
		Release();
	}

	BOOL Valid()
	{
		return (m_pBaseAddr != NULL);
	}

	//	重新申请内存,仅当保留内存不够用时,使用该函数
	BOOL ReCreate( DWORD dwMaxSize, DWORD dwReserveSize = 0 )
	{
		dwMaxSize = ((dwMaxSize+PAGE_SIZE-1)/PAGE_SIZE)*PAGE_SIZE;
		if( dwMaxSize < PAGE_SIZE )return FALSE;
		BYTE * p = (BYTE*)VirtualAlloc( NULL, dwMaxSize, MEM_RESERVE, PAGE_NOACCESS );
		if( p == NULL )return FALSE;
		if( dwReserveSize > dwMaxSize )
			dwReserveSize = dwMaxSize;
		if( dwReserveSize > m_dwCurSize )
			dwReserveSize = m_dwCurSize;
		if( dwReserveSize > PAGE_SIZE )
		{
			BYTE * pReserve = (BYTE*)VirtualAlloc( p, dwReserveSize, MEM_COMMIT, PAGE_READWRITE );
			if( pReserve == NULL )
			{
				VirtualFree( p, dwMaxSize, MEM_RELEASE );
				return FALSE;
			}
			memcpy( pReserve, m_pBaseAddr, dwReserveSize );
		}
		Release();
		m_pBaseAddr = p;
		m_dwCurSize = dwReserveSize;
		m_dwMaxSize = dwMaxSize;
		return TRUE;
	}

	BOOL Create( DWORD dwMaxSize, DWORD dwInitSize = 0 )
	{
		dwMaxSize = ((dwMaxSize+PAGE_SIZE-1)/PAGE_SIZE)*PAGE_SIZE;
		m_pBaseAddr = (BYTE*)VirtualAlloc( NULL, dwMaxSize, MEM_RESERVE, PAGE_NOACCESS );
		if( m_pBaseAddr == NULL )return FALSE;
		m_dwMaxSize = dwMaxSize;
		if( dwInitSize > 0 )
		{
			Resize( dwInitSize );
		}
		return TRUE;
	}

	VOID Release()
	{
		if( Valid() )
		{
			VirtualFree( m_pBaseAddr, 0, MEM_RELEASE );
			m_pBaseAddr = NULL;
			m_dwMaxSize = 0;
			m_dwCurSize = 0;
		}
	}

	BOOL Resize( DWORD dwNewSize )
	{
		dwNewSize = ((dwNewSize+PAGE_SIZE-1)/PAGE_SIZE)*PAGE_SIZE;
		if( dwNewSize > m_dwMaxSize )return FALSE;
		if( dwNewSize == m_dwCurSize )return TRUE;
		if( dwNewSize > m_dwCurSize )
		{
			VirtualAlloc( m_pBaseAddr + m_dwCurSize, dwNewSize - m_dwCurSize, MEM_COMMIT, PAGE_READWRITE );
		}
		else
		{
			VirtualAlloc( m_pBaseAddr + dwNewSize, m_dwCurSize - dwNewSize, MEM_DECOMMIT, PAGE_NOACCESS );
		}
		m_dwCurSize = dwNewSize;
		return TRUE;
	}

	BYTE * GetBase(){ return m_pBaseAddr;}
	DWORD  GetCurSize(){ return m_dwCurSize;}
	DWORD  GetMaxSize(){ return m_dwMaxSize;}
protected:
	BYTE *	m_pBaseAddr;
	DWORD	m_dwCurSize;
	DWORD	m_dwMaxSize;
};





class xFixedMemPool
{
	struct SELEHEADER
	{
		DWORD	dwMagic;
		DWORD	dwAllocID;
		xFixedMemPool * pPool;
		SELEHEADER * pNext;
		SELEHEADER * pPrev;
	};
public:
	xFixedMemPool( DWORD dwEleSize, DWORD dwEleCount, DWORD dwMagic = 'MEP1' ) : m_dwMagic( dwMagic ), BLOCKSIZE( ALIGNMEM(dwEleSize + sizeof( SELEHEADER )) )
	{
		if( !m_vMemory.Create( BLOCKSIZE * dwEleCount ) )
			throw "CMemElePool初始化虚拟内存失败!";
		m_pFreeList = NULL;
		m_pUsedList = NULL;
		m_dwAllocedSize = 0;
		m_dwAllocCounter = 0;
	}
	~xFixedMemPool()
	{
	}
	BYTE * newElement()
	{
		if( m_pFreeList == NULL )
		{
			if( !CommitMemory() || m_pFreeList == NULL )return NULL;
		}
		SELEHEADER * ph = m_pFreeList;
		RemoveFromList( &m_pFreeList, ph );
		AddToList( &m_pUsedList, ph );
		return (((BYTE*)ph) + sizeof( SELEHEADER ) );
	}
	VOID delElement( BYTE * pEle )
	{
		if( !isElement( pEle ) )return;
		SELEHEADER * pHeader = ((SELEHEADER*)(pEle-sizeof( SELEHEADER ) ));
		RemoveFromList( &m_pUsedList, pHeader );
		if( pHeader->dwAllocID == this->m_dwAllocCounter )
		{
			this->m_dwAllocCounter--;
			this->m_dwAllocedSize -= BLOCKSIZE;
			CheckToDecommit();
		}
		else
		{
			AddToList( &m_pFreeList, pHeader );
			RefreshFreeList();
		}
	}
	BOOL isElement( BYTE * pEle )
	{
		BYTE * pHead = pEle - sizeof( SELEHEADER );
		if( IsBadReadPtr( pHead, sizeof( SELEHEADER ) ) ||
			((SELEHEADER*)pHead)->dwMagic != m_dwMagic || 
			((SELEHEADER*)pHead)->pPool != this )
			return FALSE;
		return TRUE;
	}

	BOOL full()
	{
		if( m_vMemory.GetCurSize() + BLOCKSIZE > m_vMemory.GetMaxSize() &&
			this->m_pFreeList == NULL )
			return TRUE;
		return FALSE;
	}
protected:

	VOID RemoveFromList( SELEHEADER ** ppList, SELEHEADER * pNode )
	{
		if( *ppList == NULL )return;
		if( pNode == *ppList )
			*ppList = pNode->pNext;
		if( pNode->pNext )
			pNode->pNext->pPrev = pNode->pPrev;
		if( pNode->pPrev )
			pNode->pPrev->pNext = pNode->pNext;
		pNode->pNext = NULL;
		pNode->pPrev = NULL;
	}

	VOID AddToList( SELEHEADER ** ppList, SELEHEADER * pNode )
	{
		pNode->pNext = *ppList;
		pNode->pPrev = NULL;
		if( *ppList )(*ppList)->pPrev = pNode;
		*ppList = pNode;
	}

	VOID RefreshFreeList()	//	刷新freelist,将连续的内存退回去,当退回去的内存大于一个页面的时候,decommit一下
	{
		SELEHEADER * p = m_pFreeList;
		SELEHEADER * pNext = NULL;

		while( p )
		{
			pNext = p->pNext;
			if( p->dwAllocID == this->m_dwAllocCounter )
			{
				this->m_dwAllocCounter --;
				this->m_dwAllocedSize-= BLOCKSIZE;
				RemoveFromList( &m_pFreeList, p );
			}
			p = pNext;
		}
		
		CheckToDecommit();
	}

	VOID CheckToDecommit()
	{
		if( m_vMemory.GetCurSize() - m_dwAllocedSize >= ((DWORD)(PAGE_SIZE * 1.5f)) )
		{
			m_vMemory.Resize( m_vMemory.GetCurSize() - ((DWORD)(PAGE_SIZE * 1.5f)) );
		}
	}

	BOOL CommitMemory()
	{
//		DWORD dwAllocedSize = m_vMemory.GetCurSize();
		if( m_vMemory.GetCurSize() - m_dwAllocedSize < BLOCKSIZE )
		{
			if( !m_vMemory.Resize( m_vMemory.GetCurSize() + BLOCKSIZE ) )
				return FALSE;
		}
		SELEHEADER * ph = (SELEHEADER*)(m_vMemory.GetBase() + m_dwAllocedSize);
		m_dwAllocedSize += BLOCKSIZE;
		ph->dwAllocID = ++this->m_dwAllocCounter;
		ph->dwMagic = m_dwMagic;
		ph->pPool = this;
		AddToList( &m_pFreeList, ph );
		//ph->pNext = m_pFreeList;
		//m_pFreeList = ph;
		return TRUE;
	}

	const DWORD m_dwMagic;
	const DWORD BLOCKSIZE;
	xMemory m_vMemory;
	SELEHEADER * m_pFreeList;
	SELEHEADER * m_pUsedList;
	DWORD		m_dwAllocCounter;
	DWORD		m_dwAllocedSize;
};

⌨️ 快捷键说明

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