(hryEngine)引擎基础组成——高效内存池(lookaside list)

转自 http://blogold.chinaunix.net/u3/102180/showart_2065839.html


//  工程名称:网络游戏服务器端引擎《hryEngine》 
//  参考项目:ReactOS、Apache、ACE
【路过的朋友请留下您宝贵的意见,谢谢!】

#ifndef _LOOKASIDELIST_
#define _LOOKASIDELIST_
/******************************************************************************
* LookasideList Functions *
******************************************************************************/

#include "..\Define.h"

#define LAL_MEMORY_BLOCK_SIZE    (8)
typedef struct _LAL_MEMORY_BLOCK
{    
    _LAL_MEMORY_BLOCK*    sNext;                    // 0

    DWORD                dwMemSize;                // 4

    CHAR                pMemory[1];                // 8

    
    _LAL_MEMORY_BLOCK()
    {
        memset(this,0,sizeof(_LAL_MEMORY_BLOCK));
    }
} LAL_MEMORY_BLOCK, *PLAL_MEMORY_BLOCK;

typedef struct _LAL_BLOCK_HEADER
{
    PLAL_MEMORY_BLOCK    pEntry;        // 0

    WORD                wLen;        // 4


    _LAL_BLOCK_HEADER()
    {
        memset(this,0,sizeof(_LAL_BLOCK_HEADER));
    }
} LAL_BLOCK_HEADER, *PLAL_BLOCK_HEADER;

#define LAL_MEMORY_OBJECT_SIZE    (14)
typedef struct _LAL_MEMORY_OBJECT
{
    _LAL_MEMORY_OBJECT*    pPrev;            // 0    for allocated list free

    _LAL_MEMORY_OBJECT*    pNext;            // 4

    PVOID                pParent;        // 8            

    USHORT                usIndex:15;        // 12

    USHORT                usStatus:1;        //            0: free 1: allocated

    CHAR                pMemory[1];        // 14


    _LAL_MEMORY_OBJECT()
    {
        memset(this,0,sizeof(_LAL_MEMORY_OBJECT));
    }    
} LAL_MEMORY_OBJECT, *PLAL_MEMORY_OBJECT;

typedef struct _LAL_OBJECT_HEADER
{
    PLAL_MEMORY_OBJECT    pEntry;        // 0

    DWORD                wLen;        // 4


    _LAL_OBJECT_HEADER()
    {
        memset(this,0,sizeof(_LAL_OBJECT_HEADER));
    }
} LAL_OBJECT_HEADER, *PLAL_OBJECT_HEADER;


class LOOKASIDE_LIST 
{
private:
    LAL_BLOCK_HEADER    m_sMemoryBlockList;
    DWORD                m_dwObjectSize;
    WORD                m_wMaxObjectNum;
    WORD                m_wDefaultObjectNum;
    WORD                m_wIncreaseObjectNum;

    BOOL
    AddBlock(
        IN OUT PLAL_BLOCK_HEADER pBlockHeader,
        IN OUT PLAL_OBJECT_HEADER pObjectHeader,
        IN CONST DWORD dwObjSize,
        IN CONST WORD wObjNum);
public:
    enum
    {
        PER_BLOCK_OBJ_MAX_NUM = 512,
        MEM_STATUS_FREE = 0,
        MEM_STATUS_ALLOCATED = 1,
    };
    LAL_OBJECT_HEADER    m_sFreeObjectList;
    LAL_OBJECT_HEADER    m_sAllocatedObjectList;
    DWORD                m_dwRealObjectSize;
public:
    LOOKASIDE_LIST();
    ~LOOKASIDE_LIST();
    BOOL 
    InitializeLookasideList(
        IN CONST DWORD dwObjectSize,
        IN CONST WORD wMaxObjNum,
        IN CONST WORD wDefaultObjNum,
        IN CONST WORD wIncreaseObjectNum);
    BOOL
    IncreaseBlock(VOID);
};

static 
inline 
PLAL_MEMORY_OBJECT
BodyToHeader ( 
             IN PVOID addr );

PVOID
LalAlloc(
         IN LOOKASIDE_LIST* pLookaside);

VOID
LalFree(
         IN LOOKASIDE_LIST* pLookaside,
         IN PVOID pMemory);


#endif


/*
* PROJECT: hryEngine.LookasideList
* PURPOSE: memory pool by lookaside list
* PROGRAMMERS: Liao Huaifu([email protected],[email protected])
                 Shanghai
                 09/9-26~09/10-8
*/


#include <windows.h>
#include <malloc.h>
#include "LookasideList.h"

LOOKASIDE_LIST::LOOKASIDE_LIST()
{
    memset(this,0,sizeof(LOOKASIDE_LIST));
}

LOOKASIDE_LIST::~LOOKASIDE_LIST()
{
    if (m_sMemoryBlockList.pEntry && m_sMemoryBlockList.wLen)
    {
        PLAL_MEMORY_BLOCK pBlock = m_sMemoryBlockList.pEntry;
        while(pBlock)
        {
            PLAL_MEMORY_BLOCK tmpBlock = pBlock->sNext;
            delete[] (char*)pBlock;
            pBlock = NULL;
            pBlock = tmpBlock;
        }
    }
}

BOOL 
LOOKASIDE_LIST::InitializeLookasideList(
                        IN CONST DWORD dwObjectSize,
                        IN CONST WORD wMaxObjNum,
                        IN CONST WORD wDefaultObjNum,
                        IN CONST WORD wIncreaseObjectNum)
{
    m_dwObjectSize = dwObjectSize;
    m_wMaxObjectNum = wMaxObjNum;
    m_wDefaultObjectNum = wDefaultObjNum;
    m_wIncreaseObjectNum = wIncreaseObjectNum;

    WORD num = 0;
    (wDefaultObjNum%PER_BLOCK_OBJ_MAX_NUM == 0)? 
        num = wDefaultObjNum/PER_BLOCK_OBJ_MAX_NUM : 
        num = wDefaultObjNum/PER_BLOCK_OBJ_MAX_NUM + 1;
    for(int i=0;i<num;i++)
    {
        AddBlock(&m_sMemoryBlockList,&m_sFreeObjectList,m_dwObjectSize,PER_BLOCK_OBJ_MAX_NUM);
    }
    return TRUE;
}

BOOL
LOOKASIDE_LIST::AddBlock(
         IN OUT PLAL_BLOCK_HEADER pBlockHeader,
         IN OUT PLAL_OBJECT_HEADER pObjectHeader,
         IN CONST DWORD dwObjSize,
         IN CONST WORD wObjNum)
{
    if (!pBlockHeader || !pObjectHeader || !dwObjSize || !dwObjSize)
    {
        return FALSE;
    }

    m_dwRealObjectSize = dwObjSize + LAL_MEMORY_OBJECT_SIZE;
    DWORD dwBlockSize = wObjNum * m_dwRealObjectSize + LAL_MEMORY_BLOCK_SIZE;
    char *pMemory = new char[dwBlockSize];
    if (!pMemory)
    {
        return FALSE;
    }

    PLAL_MEMORY_BLOCK pBlock = (PLAL_MEMORY_BLOCK)pMemory;
    pBlock->sNext = pBlockHeader->pEntry;
    pBlock->dwMemSize = dwBlockSize;
    //pBlock->pMemory = pMemory + LAL_MEMORY_BLOCK_SIZE;


    pBlockHeader->pEntry = pBlock;
    pBlockHeader->wLen++;

    // init object memory chain table

    DWORD dwOffset = 0;     
    for(int i=0;i<wObjNum;i++)
    {
        dwOffset = LAL_MEMORY_BLOCK_SIZE + (i*m_dwRealObjectSize);
        PLAL_MEMORY_OBJECT pObject = (PLAL_MEMORY_OBJECT)(pMemory + dwOffset);
        pObject->pNext = pObjectHeader->pEntry;
        pObject->pPrev = NULL;
        pObjectHeader->pEntry = pObject;
        pObjectHeader->wLen++;
        pObject->pParent = pMemory;
        pObject->usIndex = i+1;
        pObject->usStatus = MEM_STATUS_FREE;
        //pObject->pMemory = pMemory + dwOffset + LAL_MEMORY_OBJECT_SIZE;

    }
    return TRUE;
}

BOOL
LOOKASIDE_LIST::IncreaseBlock(VOID)
{
    if (m_wMaxObjectNum && m_sAllocatedObjectList.wLen>=m_wMaxObjectNum)
    {
        return FALSE;
    }
    return AddBlock(&m_sMemoryBlockList,&m_sFreeObjectList,m_dwObjectSize,m_wIncreaseObjectNum);
}

PVOID
LalAlloc(
         IN LOOKASIDE_LIST* pLookaside)
{
    if (!pLookaside)    return    NULL;
    if (!pLookaside->m_sFreeObjectList.pEntry)
    {
        if (!pLookaside->IncreaseBlock())
            return NULL;
    }

    PLAL_MEMORY_OBJECT pVel = pLookaside->m_sFreeObjectList.pEntry;
    pLookaside->m_sFreeObjectList.wLen--;
    pLookaside->m_sFreeObjectList.pEntry = pVel->pNext;
    pVel->usStatus = LOOKASIDE_LIST::MEM_STATUS_ALLOCATED;
    pVel->pNext = pVel->pPrev = NULL;
#ifdef DEBUG_VER
    if (pLookaside->m_sAllocatedObjectList.pEntry)
    {
        pVel->pNext = pLookaside->m_sAllocatedObjectList.pEntry;
        pLookaside->m_sAllocatedObjectList.pEntry->pPrev = pVel;    
        pLookaside->m_sAllocatedObjectList.pEntry = pVel;
    }
    pLookaside->m_sAllocatedObjectList.pEntry = pVel;
    pLookaside->m_sAllocatedObjectList.wLen++;
#endif
    return pVel->pMemory;
}

VOID
LalFree(
         IN LOOKASIDE_LIST* pLookaside,
         IN PVOID pMemory)
{
    if (!pLookaside || !pMemory) return;
    
    PLAL_MEMORY_OBJECT pVel = BodyToHeader(pMemory);
    PCHAR pUnit = (PCHAR)pVel;
    PCHAR pL = ((PCHAR)pVel->pParent) + (pVel->usIndex-1)*(pLookaside->m_dwRealObjectSize);
    PCHAR pH = ((PCHAR)pVel->pParent) + (pVel->usIndex+1)*(pLookaside->m_dwRealObjectSize);
    if (pUnit > pL && pUnit < pH)
    {
        if (pVel->usStatus)
        {
#ifdef DEBUG_VER
            PLAL_MEMORY_OBJECT pPrev = pVel->pPrev;
            PLAL_MEMORY_OBJECT pNext = pVel->pNext;
            if (pPrev)    
                pPrev->pNext = pNext;
            if (pNext)    
                pNext->pPrev = pPrev;
            else // pPrev = pNext = null

                pLookaside->m_sAllocatedObjectList.pEntry = NULL;    
            pLookaside->m_sAllocatedObjectList.wLen--;
#endif
            pVel->usStatus = LOOKASIDE_LIST::MEM_STATUS_FREE;    
            pVel->pPrev = NULL;
            pVel->pNext = pLookaside->m_sFreeObjectList.pEntry;     
            pLookaside->m_sFreeObjectList.pEntry = pVel;
            pLookaside->m_sFreeObjectList.wLen++;
        }
        else
        {
            // memory had been destroy

        }
    }
}

static 
inline 
PLAL_MEMORY_OBJECT
BodyToHeader ( 
             IN PVOID addr )
{
    return (PLAL_MEMORY_OBJECT)(((char*)addr) - LAL_MEMORY_OBJECT_SIZE);
}


你可能感兴趣的:((hryEngine)引擎基础组成——高效内存池(lookaside list))