//AweMemory.h
/************************************************************************/
/* 内存池源码 */
/*作者:双刃剑 */
/*时间:2010-10-21 */
/************************************************************************/
#pragma once
void SetPageSize(DWORD dwSize);
BOOL MemCreate(DWORD dwMemSize);
void MemDestroy(void);
/* 结构定义 */
typedef struct _MemList
{
void* _data;
struct _MemList* _pNext;
}MemList,PMemList;
extern MemList* pMemlistHead ;
//AweMemory.cpp
/************************************************************************/
/* 内存池源码 */
/*作者:双刃剑 */
/*时间:2010-10-21 */
/************************************************************************/
#pragma once
#include "stdafx.h"
#include <Windows.h>
#include "AweMemory.h"
/************************************************************************/
/* 变量声明 */
DWORD dwMemPageSize = 0; //默认内存页的大小
DWORD dwStartingBytes = 0; //操作系统64K内存区以后的向量值,具体参考virtualalloc
DWORD dwNeedPages = 0; //所需的页数
DWORD dwRealPageSize = 256; //在一页中分成小页的大小
DWORD dwRealPages = 0; //小页实际所需的页数
DWORD dwTotalBytes = 0; //通过换算得出实际的内存大小
ULONG_PTR* pUlPfnArray = NULL; //页框号数组
void* pAddrHead = NULL; //内存的首地址
void* pAddrTail = NULL; //内存的尾地址
BOOL bIsActive = FALSE;//标识内存存活
/************************************************************************/
/************************************************************************/
MemList* pMemlistHead = NULL ;
/************************************************************************/
BOOL SetPrivileges(BOOL bActive)
{
BOOL result = FALSE;
HANDLE hToken;
//打开进程,取得令牌hToken
if ( !OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken) )
{
return result;
}
TOKEN_PRIVILEGES tp={0};
// 获得锁定内存权限的ID
if( !LookupPrivilegeValue(NULL,SE_LOCK_MEMORY_NAME,&tp.Privileges[0].Luid ) )
{
CloseHandle(hToken);
return result;
}
// 设置权限信息
tp.PrivilegeCount = 1 ;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED * ((DWORD)bActive) ;
// 调整权限
AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),NULL,NULL);
result = ( ERROR_SUCCESS == GetLastError() );
CloseHandle( hToken );
return result;
}
BOOL MemCreate(DWORD dwMemSize)
{
if (bIsActive)
return FALSE;
MEMORYSTATUSEX ms;
SYSTEM_INFO si;
MemList* pMemTemp = NULL ;
GetSystemInfo(&si);
ms.dwLength = sizeof(MEMORYSTATUSEX);
GlobalMemoryStatusEx(&ms);
if ( ms.ullTotalPhys-ms.ullAvailPhys<dwMemSize )
{
return FALSE;
}
//计算计算机的页大小
dwMemPageSize = si.dwPageSize;
//计算向量(分配粒度)
dwStartingBytes = ( dwMemSize/si.dwAllocationGranularity+( (DWORD)(dwMemSize%si.dwAllocationGranularity > 0 ? 1 : 0) ) )
*si.dwAllocationGranularity;
//计算页数
dwNeedPages = dwStartingBytes/dwMemPageSize + (DWORD)(dwStartingBytes%dwMemPageSize > 0 ? 1 : 0);
//申请页框号数组
pUlPfnArray = new ULONG_PTR[dwNeedPages];
pAddrHead = VirtualAlloc(NULL,dwStartingBytes,MEM_RESERVE|MEM_PHYSICAL , PAGE_READWRITE );
if (!pAddrHead)
{
return FALSE;
}
pAddrTail = (char*)pAddrHead+dwMemSize;
//正式开始预订内存页
BOOL bRet = FALSE;
SetPrivileges(TRUE);
bRet = AllocateUserPhysicalPages(GetCurrentProcess(),(PULONG_PTR)&dwNeedPages,pUlPfnArray);
SetPrivileges(FALSE);
if (FALSE == bRet)
{
VirtualFree(pAddrHead,0,MEM_RELEASE);
delete[] pUlPfnArray;
return FALSE;
}
if (!MapUserPhysicalPages(pAddrHead,dwNeedPages,pUlPfnArray))
{
VirtualFree(pAddrHead,0,MEM_RELEASE);
FreeUserPhysicalPages(GetCurrentProcess(),(PULONG_PTR)&dwNeedPages,pUlPfnArray );
delete[] pUlPfnArray;
return FALSE;
}
分成实际大小的页
dwRealPages = dwMemSize / dwRealPageSize;
dwTotalBytes = dwRealPages * dwRealPageSize;
for (DWORD i = 0 ; i<dwRealPages ; i++)
{
pMemTemp = new MemList;
if (!pMemlistHead)
{
pMemlistHead = pMemTemp;
pMemlistHead->_pNext = NULL;
pMemlistHead->_data = pAddrHead;
continue;
}
pMemTemp->_pNext = pMemlistHead ;
pMemlistHead = pMemTemp;
pMemlistHead->_data = ((char*)pAddrHead) + ( i*dwRealPageSize );
}
bIsActive = TRUE;
return TRUE;
}
void MemDestroy(void)
{
if (!pAddrHead)
{
return;
}
bIsActive = FALSE;
MapUserPhysicalPages(pAddrHead,dwNeedPages,NULL);
FreeUserPhysicalPages(GetCurrentProcess(),(PULONG_PTR)&dwNeedPages,pUlPfnArray );
VirtualFree(pAddrHead,0,MEM_RELEASE);
MemList* pTemp;
while(pMemlistHead)
{
pTemp = pMemlistHead;
pMemlistHead = pMemlistHead->_pNext;
delete pTemp;
}
pAddrHead = NULL;
pAddrTail = NULL;
delete[] pUlPfnArray;
pUlPfnArray = NULL;
}
void SetPageSize(DWORD dwSize)
{
dwRealPageSize = dwSize;
}
/************************************************************************/
/* 内存池源码 */
/*作者:双刃剑 */
/*时间:2010-10-21 */
/************************************************************************/
#pragma once
#include <Windows.h>
#include "AweMemory.h"
template <class T>
class OBJPool
{
public:
OBJPool(unsigned int unNum);
virtual ~OBJPool();
T** Allocate();
void Free(T** pData);
__inline void Lock()
{
EnterCriticalSection(&m_cs_memlist);
}
__inline void UnLock()
{
LeaveCriticalSection(&m_cs_memlist);
}
protected:
private:
BOOL m_bInit;
MemList* m_pMemListHead;//头永远指向可用,当 == null时表示无节点可用
CRITICAL_SECTION m_cs_memlist;
};
template <class T >
OBJPool<T>::OBJPool(unsigned int unNum)
{
unsigned int unMemSize = unNum*sizeof(T);
SetPageSize(sizeof(T));
MemCreate(unMemSize);
InitializeCriticalSection(&m_cs_memlist);
m_pMemListHead = pMemlistHead ;
m_bInit = TRUE;
}
template <class T >
OBJPool<T>::~OBJPool()
{
DeleteCriticalSection(&m_cs_memlist);
MemDestroy();
}
template <class T >
T** OBJPool<T>::Allocate()
{
T** pRet = NULL;
if (!m_bInit)
{
return pRet;
}
Lock();
if (m_pMemListHead)
{
pRet = (T**)( &m_pMemListHead->_data );
m_pMemListHead = m_pMemListHead->_pNext;
}
UnLock();
return pRet;
}
template <class T >
void OBJPool<T>::Free(T** pData)
{
if (!m_bInit)
{
return;
}
Lock();
MemList* pTem = (MemList*)pData ;
pTem->_pNext = m_pMemListHead;
m_pMemListHead = pTem;
UnLock();
}
//demo
// AWE_TEST1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "OBJPoolT.h"
typedef struct _user
{
char username[16];
BYTE byAge;
BYTE bySex;
char szAddress[255];
}USER;
int _tmain(int argc, _TCHAR* argv[])
{
OBJPool<USER> *obt_int = new OBJPool<USER>(2);
USER **p = obt_int->Allocate();
if (p)
{
USER* p1 = *p;
strcpy(p1->username,"jack");
p1->byAge = 18;
p1->bySex = 0;
strcpy(p1->szAddress,"陕西省安康市汉滨区");
obt_int->Free(p);
}
delete obt_int;
return 0;
}
AWE泛型内存池
最新推荐文章于 2016-11-30 19:52:12 发布