📄 xmemory.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 + -