BufferAlloc.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:8k
源码类别:

模拟服务器

开发平台:

C/C++

  1. //////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. //  FileName    :   BufferAlloc.cpp
  4. //  Version     :   1.0
  5. //  Creater     :   Freeway Chen
  6. //  Date        :   2003-6-26 15:04:15
  7. //  Comment     :   
  8. //
  9. //////////////////////////////////////////////////////////////////////////////////////
  10. #include "stdafx.h"
  11. #include <windows.h>
  12. #include <crtdbg.h>
  13. #include "BufferAlloc.h"
  14. #include <vector>
  15. using namespace std;
  16. #define defMAX_BUFFER_ALLOC_ITEM_NUM    64
  17. long g_lBufferAllocInitCount = 0;
  18. CRITICAL_SECTION g_BufferAllocCrit;
  19. int g_BufferAllocCritInitFlag = false;
  20. HANDLE g_hBufferAllocHeap = NULL;
  21. // 用来存放最大释放节点的数目
  22. long g_lMaxFreeNodeCount = 1024 * 64;
  23. long g_lFreeNodeCount    = 0;
  24. // 定义 第 n 个数据指针的一个动态数组 
  25. typedef vector<unsigned char *> BufferAllocFreeItemType;
  26. // 用来存放一个所有数据的数组,数组的每一项表示,指向 第n K的一个动态数组
  27. // 为什么不用静态分配数组,而是使用动态分配,主要是担心有些全局的类已经使用该数组,但是数组还没有初始化
  28. BufferAllocFreeItemType *g_pBufferAllocFreeArray = NULL;
  29. int _BufferAlloc_Init_Internal()
  30. {
  31.     int nResult = false;
  32.     
  33.     InitializeCriticalSection(&g_BufferAllocCrit);
  34.     g_BufferAllocCritInitFlag = true;
  35.     EnterCriticalSection(&g_BufferAllocCrit);
  36.     g_hBufferAllocHeap = HeapCreate(HEAP_NO_SERIALIZE, 1024 * 1024 * 4, 0);
  37.     if (!g_hBufferAllocHeap)
  38.         goto Exit0;
  39.     try
  40.     {
  41.         g_pBufferAllocFreeArray = new BufferAllocFreeItemType[defMAX_BUFFER_ALLOC_ITEM_NUM];
  42.     }
  43.     catch (...) 
  44.     {
  45.         goto Exit0;
  46.     }
  47.     nResult = true;
  48. Exit0:
  49.     if (!nResult)
  50.     {
  51.         if (g_hBufferAllocHeap)
  52.         {
  53.             HeapDestroy(g_hBufferAllocHeap);
  54.             g_hBufferAllocHeap = NULL;
  55.         }
  56.     }
  57.     LeaveCriticalSection(&g_BufferAllocCrit);
  58.     if (!nResult)
  59.     {
  60.         if (g_BufferAllocCritInitFlag)
  61.         {
  62.             DeleteCriticalSection(&g_BufferAllocCrit);
  63.             g_BufferAllocCritInitFlag = false;
  64.         }
  65.     }
  66.     return nResult;
  67. }
  68. int _BufferAlloc_UnInit_Internal()
  69. {
  70.     if (!g_BufferAllocCritInitFlag)
  71.         return true;
  72.     EnterCriticalSection(&g_BufferAllocCrit);
  73.     if (g_pBufferAllocFreeArray)
  74.     {
  75.         for (int i = 0; i < defMAX_BUFFER_ALLOC_ITEM_NUM; i++)
  76.         {
  77.             BufferAllocFreeItemType::iterator pPos;
  78.             for (pPos = g_pBufferAllocFreeArray[i].begin(); pPos != g_pBufferAllocFreeArray[i].end(); pPos++)
  79.             {
  80.                 HeapFree(g_hBufferAllocHeap, HEAP_NO_SERIALIZE, *pPos);
  81.                 *pPos = NULL;
  82.             }
  83.             
  84.             g_pBufferAllocFreeArray[i].clear();
  85.         }
  86.         delete []g_pBufferAllocFreeArray;
  87.         g_pBufferAllocFreeArray = NULL;
  88.     }
  89.     LeaveCriticalSection(&g_BufferAllocCrit);
  90.     if (g_hBufferAllocHeap)
  91.     {
  92.         HeapDestroy(g_hBufferAllocHeap);
  93.         g_hBufferAllocHeap = NULL;
  94.     }
  95.     DeleteCriticalSection(&g_BufferAllocCrit);
  96.     g_BufferAllocCritInitFlag = false;
  97.     return false;
  98. }
  99. int BufferAlloc_IncMaxFreeNodeCount(long lCount)
  100. {
  101.     EnterCriticalSection(&g_BufferAllocCrit);
  102.     
  103.     g_lMaxFreeNodeCount += lCount;
  104.     
  105.     LeaveCriticalSection(&g_BufferAllocCrit);
  106.     return true;
  107. }
  108. int BufferAlloc_DecMaxFreeNodeCount(long lCount)
  109. {
  110.     EnterCriticalSection(&g_BufferAllocCrit);
  111.     
  112.     g_lMaxFreeNodeCount -= lCount;
  113.     
  114.     LeaveCriticalSection(&g_BufferAllocCrit);
  115.     return true;
  116. }
  117. void *BufferAlloc_Alloc(size_t uSize)
  118. {
  119.     _ASSERT(uSize > 0);
  120.     if (uSize == 0)
  121.         return NULL;
  122.     // 将分配的字节转换为以 K 为单位
  123.     size_t uAllocKSize = (uSize + (1024 - 1)) / 1024;
  124.     void *pvResult = NULL;
  125.     
  126.     // 由于空闲数组的下标从 0 开始,因此需要 - 1
  127.     size_t uAllocFreeIndex = uAllocKSize - 1;
  128.     EnterCriticalSection(&g_BufferAllocCrit);
  129.     if (uAllocKSize > defMAX_BUFFER_ALLOC_ITEM_NUM)
  130.     {
  131.         // 如果分配的数据大小超过  defMAX_BUFFER_ALLOC_ITEM_NUM(64) K,直接向系统分配
  132.         pvResult = HeapAlloc(g_hBufferAllocHeap, HEAP_NO_SERIALIZE, uAllocKSize * 1024);
  133.         goto Exit1;
  134.     }
  135.     if (g_lFreeNodeCount == 0)
  136.     {
  137.         // 如果空闲列表中没有多余的节点,就直接向系统申请内存
  138.         pvResult = HeapAlloc(g_hBufferAllocHeap, HEAP_NO_SERIALIZE, uAllocKSize * 1024);
  139.         goto Exit1;
  140.     }
  141.     if (g_pBufferAllocFreeArray[uAllocFreeIndex].empty())
  142.     {
  143.         // 如果找不到合适的空间,就直接申请分配
  144.         pvResult = HeapAlloc(g_hBufferAllocHeap, HEAP_NO_SERIALIZE, uAllocKSize * 1024);
  145.         goto Exit1;
  146.     }
  147.     // 如果有空闲的缓冲区
  148.     g_lFreeNodeCount--; // 减少空闲缓冲区的计数
  149.     //InterlockedDecrement(&g_lFreeNodeCount);
  150.     
  151.     pvResult = g_pBufferAllocFreeArray[uAllocFreeIndex].back();
  152.     g_pBufferAllocFreeArray[uAllocFreeIndex].pop_back();
  153. Exit1:
  154.     LeaveCriticalSection(&g_BufferAllocCrit);
  155.     return pvResult;
  156. }
  157. // 释放 uSize 大小的缓冲区
  158. int BufferAlloc_Free(void *pvBuffer, size_t uSize)
  159. {
  160.     _ASSERT(pvBuffer);
  161.     if (!pvBuffer)
  162.         return true;
  163.     _ASSERT(uSize > 0);
  164.     if (uSize == 0)
  165.         return true;
  166.     // 将分配的字节转换为以 K 为单位
  167.     size_t uAllocKSize = (uSize + (1024 - 1)) / 1024;
  168.     int nResult = false;
  169.     // 由于空闲数组的下标从 0 开始,因此需要 - 1
  170.     size_t uAllocFreeIndex = uAllocKSize - 1;
  171.     EnterCriticalSection(&g_BufferAllocCrit);
  172.     if (uAllocKSize > defMAX_BUFFER_ALLOC_ITEM_NUM)
  173.     {
  174.         // 如果分配的数据大小超过  defMAX_BUFFER_ALLOC_ITEM_NUM(64) K,直接释放内存
  175.         HeapFree(g_hBufferAllocHeap, HEAP_NO_SERIALIZE, pvBuffer);
  176.         goto Exit1;
  177.     }
  178.     if (g_lFreeNodeCount >= g_lMaxFreeNodeCount)
  179.     {
  180.         // 如果空闲列表中已经达到最大值,直接释放内存
  181.         HeapFree(g_hBufferAllocHeap, HEAP_NO_SERIALIZE, pvBuffer);
  182.         goto Exit1;
  183.     }
  184.     try
  185.     {
  186.         g_pBufferAllocFreeArray[uAllocFreeIndex].push_back((unsigned char *)pvBuffer);
  187.     }
  188.     catch (...)
  189.     {
  190.         goto Exit0;
  191.     }
  192.                     
  193.     g_lFreeNodeCount++; // 增加空闲缓冲区的计数
  194.     //InterlockedIncrement(&g_lFreeNodeCount);
  195. Exit1:
  196.     nResult = true;
  197. Exit0:
  198.     
  199.     if (!nResult)
  200.     {
  201.         // 空闲缓冲区放置不成功,就直接释放内存
  202.         HeapFree(g_hBufferAllocHeap, HEAP_NO_SERIALIZE, pvBuffer);
  203.         nResult = true;
  204.     }
  205.     LeaveCriticalSection(&g_BufferAllocCrit);
  206.     return nResult;
  207. }
  208. class KHeap 
  209. {
  210. private:
  211.     HANDLE m_hHeap;
  212.     #ifdef _DEBUG
  213.     long   m_lAllocCount;
  214.     long   m_lFreeCount;
  215.     #endif
  216. public:
  217.     KHeap(size_t uInitialSize = 0); 
  218.     ~KHeap();
  219.     
  220.     void *Alloc(size_t uSize);
  221.     void Free(void *pvBuffer, size_t uSize);
  222. };
  223. inline KHeap::KHeap(size_t uInitialSize)
  224. {
  225.     #ifdef _DEBUG
  226.     m_lAllocCount = 0;
  227.     m_lFreeCount  = 0;
  228.     #endif
  229.     m_hHeap = HeapCreate(0, uInitialSize, 0);
  230.     _ASSERT(m_hHeap);
  231. }
  232. inline KHeap::~KHeap()
  233. {
  234.     #ifdef _DEBUG
  235.     _ASSERT(m_lAllocCount == m_lFreeCount);
  236.     #endif
  237.     if (m_hHeap)
  238.     {
  239.         HeapDestroy(m_hHeap);
  240.         m_hHeap = NULL;
  241.     }
  242. }
  243. inline void *KHeap::Alloc(size_t uSize)
  244. {
  245.     if (!m_hHeap)
  246.         return NULL;
  247.         
  248.     #ifdef _DEBUG
  249.     InterlockedIncrement(&m_lAllocCount);
  250.     #endif
  251.     return HeapAlloc(m_hHeap, 0, uSize);
  252. }
  253. inline void KHeap::Free(void *pvBuffer, size_t uSize)
  254. {
  255.     if (!m_hHeap)
  256.     {
  257.         _ASSERT(false);
  258.         return;
  259.     }
  260.     uSize = uSize;      // make compiler no warning
  261.     
  262.     HeapFree(m_hHeap, 0, pvBuffer);
  263.     #ifdef _DEBUG
  264.     InterlockedIncrement(&m_lFreeCount);
  265.     #endif
  266. }