Chinaunix首页 | 论坛 | 博客
  • 博客访问: 37712
  • 博文数量: 20
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 250
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-29 17:42
文章分类

全部博文(20)

文章存档

2011年(1)

2010年(3)

2009年(16)

我的朋友

分类: 系统运维

2009-09-20 22:26:04

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


文件名:MemoryPool.h
类名: CMemoryPool
描述: 本内存池(静态)实现了固定大小内存块分配与释放,其中实现了O(1)时间复杂度Alloc与Free操作,不产生任何内存碎片和缝隙。
***************************************************************************************/
#ifndef _LHF_MEMORY_POOL_H_
#define _LHF_MEMORY_POOL_H_
#include <Windows.h>
namespace LHF_MEMORY_POOL
{
    enum
    {
        MEMORY_DESC_SIZE = 8,
        MEMORY_BLOCK_HEADER_SIZE = 4,
    };

    // 内存块信息结构

    struct MEMORY_DESC
    {
        void* m_pMemoryAddr;
        MEMORY_DESC* m_pNext;


        MEMORY_DESC()
        {
            memset(this,0,sizeof(MEMORY_DESC));
        }


    };

    // 内存块结构

    struct MEMORY_BLOCK
    {
        MEMORY_DESC* m_pMemoryDesc;
        char m_pMemory[1];


        MEMORY_BLOCK()
        {
            memset(this,0,sizeof(MEMORY_BLOCK));
        }
    };

    // 内存池类

    class CMemoryPool
    {
    private:
        // 链表访问控制

        CRITICAL_SECTION m_csMemoryPool;
        // 内存块信息结构链表头

        MEMORY_DESC* m_pBaseDesc;
        // 单位内存块空间大小

        DWORD m_dwUnitBlockSize;
        // 内存块数量

        DWORD m_dwBlockNum;
        // 内存块链表

        void* m_pLinearMemoryPool;
        // 内存块信息链表

        void* m_pLinearDescPool;


        bool InitializeMemoryBlockPool();
        bool InitializeMemoryDescPool();
    public:
        CMemoryPool();
        ~CMemoryPool();
        bool InitializeMemoryPool(DWORD dwUnitBlockSize,DWORD dwBlockNum);


        void* Alloc();
        void Free(void* pMemory);
    };
}
#endif

#include "MemoryPool.h"
namespace LHF_MEMORY_POOL
{
    CMemoryPool::CMemoryPool()
    {
        memset(this,0,sizeof(this));
        InitializeCriticalSection(&m_csMemoryPool);
    }

    CMemoryPool::~CMemoryPool()
    {
        DeleteCriticalSection(&m_csMemoryPool);


        if (m_pLinearDescPool)
        {
            delete [] m_pLinearDescPool;
            m_pLinearDescPool = NULL;
        }


        if (m_pLinearMemoryPool)
        {
            delete [] m_pLinearMemoryPool;
            m_pLinearMemoryPool = NULL;
        }


        if (m_pBaseDesc)
        {
            m_pBaseDesc = NULL;
        }


    }


    bool CMemoryPool::InitializeMemoryPool(DWORD dwUnitBlockSize,DWORD dwBlockNum)
    {
        bool bResult = FALSE;


        if (!dwBlockNum || !dwUnitBlockSize)
        {
            return bResult;
        }


        this->m_dwUnitBlockSize = dwUnitBlockSize;
        this->m_dwBlockNum = dwBlockNum;


        EnterCriticalSection(&m_csMemoryPool);
        this->m_pLinearDescPool = new char[dwBlockNum * MEMORY_DESC_SIZE];
        if (!this->m_pLinearDescPool)
        {
            return bResult;
        }
        memset(this->m_pLinearDescPool,0,sizeof(char)*(dwBlockNum * MEMORY_DESC_SIZE));


        this->m_pLinearMemoryPool = new char[dwBlockNum * (MEMORY_BLOCK_HEADER_SIZE+dwUnitBlockSize)];
        if (!this->m_pLinearMemoryPool)
        {
            return bResult;
        }
        memset(this->m_pLinearMemoryPool,0,
            sizeof(char)*(dwBlockNum * (MEMORY_BLOCK_HEADER_SIZE+dwUnitBlockSize)));


        bResult = this->InitializeMemoryDescPool();
        if (!bResult)
        {
            return bResult;
        }


        bResult = this->InitializeMemoryBlockPool();
        LeaveCriticalSection(&m_csMemoryPool);
        return bResult;
    }


    // 形成链表

    bool CMemoryPool::InitializeMemoryDescPool()
    {
        MEMORY_DESC *pDescList = (MEMORY_DESC *)this->m_pLinearDescPool;


        if (!pDescList)
        {
            return FALSE;
        }


        EnterCriticalSection(&m_csMemoryPool);
        for (DWORD i=0 ;i<this->m_dwBlockNum;i++)
        {
            // 如果是最后一个,就指向空

            pDescList[i].m_pMemoryAddr = NULL;


            if (i == m_dwBlockNum-1)
            {
                pDescList[i].m_pNext = NULL;
            }
            else
            {
                pDescList[i].m_pNext = &pDescList[i+1];
            }
        }


        this->m_pBaseDesc = &pDescList[0];
        this->m_pBaseDesc->m_pNext = pDescList[0].m_pNext;
        LeaveCriticalSection(&m_csMemoryPool);
        return TRUE;
    }

    // 将内存块与分配链表挂钩

    bool CMemoryPool::InitializeMemoryBlockPool()
    {
        char *pBlockList = (char *)this->m_pLinearMemoryPool;
        MEMORY_DESC *pDescList = (MEMORY_DESC *)this->m_pLinearDescPool;


        if (!pDescList || !pBlockList)
        {
            return FALSE;
        }

        EnterCriticalSection(&m_csMemoryPool);
        for (DWORD i=0; i<this->m_dwBlockNum; i++)
        {
            char *pTmp = pBlockList + (i*(m_dwUnitBlockSize + MEMORY_BLOCK_HEADER_SIZE));
            ((MEMORY_BLOCK *)pTmp)->m_pMemoryDesc = &pDescList[i];
            pDescList[i].m_pMemoryAddr = ((MEMORY_BLOCK *)pTmp)->m_pMemory;
        }
        LeaveCriticalSection(&m_csMemoryPool);
        return TRUE;
    }


    void* CMemoryPool::Alloc()
    {
        void *pResult = NULL;
        EnterCriticalSection(&m_csMemoryPool);
        if(m_pBaseDesc)
        {
            // 备份出结果

            pResult = m_pBaseDesc->m_pMemoryAddr;
            // 重新修改m_pBaseDesc的指向

            if (m_pBaseDesc->m_pNext)
            {
                m_pBaseDesc = m_pBaseDesc->m_pNext;
            }
            else
            {
                m_pBaseDesc = NULL;
            }
        }
        LeaveCriticalSection(&m_csMemoryPool);
        return pResult;
    }

    void CMemoryPool::Free(void* pMemory)
    {
        if (!pMemory)
        {
            return;
        }

        memset(pMemory,0,sizeof(char)*m_dwUnitBlockSize);
        char *pFree = (char*)pMemory;
        char *pDesc = pFree-4 ;

        MEMORY_BLOCK *pMemoryBlock = (MEMORY_BLOCK *)pDesc;
        pMemoryBlock->m_pMemoryDesc->m_pNext = m_pBaseDesc;
        m_pBaseDesc = pMemoryBlock->m_pMemoryDesc;
    }
}


阅读(983) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-09-23 15:49:28

1、内存分块申请 2、添加一些debug下的调试信息 3、采用链表管理Node