MemPool.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #include "MemPool.h"
  2. #include <algorithm>
  3. NAMESPACE_MAS_BEGIN
  4. tzc::Mutex MemPool::_mutex;
  5. MemPool * MemPool::_instance = nullptr;
  6. MemPool::MemPool()
  7. {
  8. }
  9. MemPool::~MemPool()
  10. {
  11. this->Dispose();
  12. }
  13. MemPool * MemPool::Instance()
  14. {
  15. if (!_instance)
  16. {
  17. _mutex.Lock();
  18. if (!_instance)
  19. {
  20. _instance = new MemPool();
  21. }
  22. _mutex.Unlock();
  23. }
  24. return _instance;
  25. }
  26. void MemPool::DestroyInstance()
  27. {
  28. _mutex.Lock();
  29. TZ_delete(_instance);
  30. _mutex.Unlock();
  31. }
  32. TZ_INT MemPool::Initialize()
  33. {
  34. for (TZ_INT idx = 1; idx <= BLOCK_LIST_COUNT; ++idx)
  35. {
  36. TZ_Uint32 blockSize = (MIN_BLOCK_SIZE << (idx - 1));
  37. TZ_Uint32 blockCount =
  38. (idx < BLOCK_LIST_COUNT ? (1 << (BLOCK_LIST_COUNT - 1 - idx)) : 1);
  39. std::list<void *> blockList;
  40. for (TZ_INT cnt = 1; cnt <= blockCount; ++cnt)
  41. {
  42. void * memBlock = std::malloc(blockSize);
  43. if (nullptr == memBlock)
  44. {
  45. TZLogWarn("malloc memory for size %u failed, "
  46. "error is %d!!!", blockSize, errno);
  47. return MEC_FAILED;
  48. }
  49. blockList.push_back(memBlock);
  50. }
  51. m_memDepot.push_back(blockList);
  52. }
  53. TZLogInfo("initialize memory pool succeed~~~");
  54. return MEC_OK;
  55. }
  56. TZ_INT MemPool::Dispose()
  57. {
  58. tzc::ScopedLock lock(m_lock);
  59. for (TZ_INT idx = 0; idx < m_memDepot.size(); ++idx)
  60. {
  61. std::list<void *>::iterator iter;
  62. for (iter = m_memDepot[idx].begin(); iter != m_memDepot[idx].end(); ++iter)
  63. {
  64. void * memBlock = * iter;
  65. TZ_free(memBlock);
  66. }
  67. m_memDepot[idx].clear();
  68. }
  69. m_memDepot.clear();
  70. TZLogInfo("memory pool dispose succeed~~~~");
  71. return MEC_OK;
  72. }
  73. void * MemPool::AllocAvailMem(TZ_Uint32 expect)
  74. {
  75. tzc::ScopedLock lock(m_lock);
  76. for (TZ_INT idx = 0; idx < BLOCK_LIST_COUNT; ++idx)
  77. {
  78. if (expect <= (MIN_BLOCK_SIZE << idx))
  79. {
  80. if (m_memDepot[idx].empty())
  81. {
  82. TZLogDebug(2, "the memory list %d is empty!!!", idx);
  83. continue;
  84. }
  85. void * rst = m_memDepot[idx].front();
  86. m_memDepot[idx].pop_front();
  87. TZLogInfo("tang: expect %u, idx %d, rst %p, size %d~~~~",
  88. expect, idx, rst, m_memDepot[idx].size());
  89. TZLogDebug(2, "get memblock 0x%x, expect %d~~~, size %d",
  90. rst, expect, (MIN_BLOCK_SIZE << idx));
  91. return rst;
  92. }
  93. }
  94. TZLogWarn("get memory block for size %u failed!!!", expect);
  95. return nullptr;
  96. }
  97. TZ_INT MemPool::ReturnFreeMem(void * memBlock, TZ_Uint32 memSize)
  98. {
  99. tzc::ScopedLock lock(m_lock);
  100. for (TZ_INT idx = 0; idx < BLOCK_LIST_COUNT; ++idx)
  101. {
  102. if (memSize <= (MIN_BLOCK_SIZE << idx))
  103. {
  104. std::list<void *>::iterator iter =
  105. std::find(m_memDepot[idx].begin(),
  106. m_memDepot[idx].end(),
  107. memBlock);
  108. if (iter != m_memDepot[idx].end())
  109. {
  110. TZLogWarn("return repeat memBlock 0x%x!!!", memBlock);
  111. return MEC_DUPLICATED;
  112. }
  113. m_memDepot[idx].push_back(memBlock);
  114. TZLogDebug(10, "return memBlock 0x%x, size %d~~~",
  115. memBlock, (MIN_BLOCK_SIZE << idx));
  116. return MEC_OK;
  117. }
  118. }
  119. TZLogWarn("illegal memory block 0x%x!!!", memBlock);
  120. return MEC_NULL_OBJ;
  121. }
  122. TZ_Uint32 MemPool::GetAvailCount(TZ_Uint32 expect)
  123. {
  124. tzc::ScopedLock lock(m_lock);
  125. if (expect <= MIN_BLOCK_SIZE)
  126. {
  127. return m_memDepot[0].size();
  128. }
  129. for (TZ_INT idx = BLOCK_LIST_COUNT; idx != 0; --idx)
  130. {
  131. if (expect > (MIN_BLOCK_SIZE << (idx - 1)))
  132. {
  133. return m_memDepot[idx].size();
  134. }
  135. }
  136. return 0;
  137. }
  138. NAMESPACE_MAS_END