AWE泛型内存池

//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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值