#include "MemPool.h" #include NAMESPACE_MAS_BEGIN tzc::Mutex MemPool::_mutex; MemPool * MemPool::_instance = nullptr; MemPool::MemPool() { } MemPool::~MemPool() { this->Dispose(); } MemPool * MemPool::Instance() { if (!_instance) { _mutex.Lock(); if (!_instance) { _instance = new MemPool(); } _mutex.Unlock(); } return _instance; } void MemPool::DestroyInstance() { _mutex.Lock(); TZ_delete(_instance); _mutex.Unlock(); } TZ_INT MemPool::Initialize() { for (TZ_INT idx = 1; idx <= BLOCK_LIST_COUNT; ++idx) { TZ_Uint32 blockSize = (MIN_BLOCK_SIZE << (idx - 1)); TZ_Uint32 blockCount = (idx < BLOCK_LIST_COUNT ? (1 << (BLOCK_LIST_COUNT - 1 - idx)) : 1); std::list blockList; for (TZ_INT cnt = 1; cnt <= blockCount; ++cnt) { void * memBlock = std::malloc(blockSize); if (nullptr == memBlock) { TZLogWarn("malloc memory for size %u failed, " "error is %d!!!", blockSize, errno); return MEC_FAILED; } blockList.push_back(memBlock); } m_memDepot.push_back(blockList); } TZLogInfo("initialize memory pool succeed~~~"); return MEC_OK; } TZ_INT MemPool::Dispose() { tzc::ScopedLock lock(m_lock); for (TZ_INT idx = 0; idx < m_memDepot.size(); ++idx) { std::list::iterator iter; for (iter = m_memDepot[idx].begin(); iter != m_memDepot[idx].end(); ++iter) { void * memBlock = * iter; TZ_free(memBlock); } m_memDepot[idx].clear(); } m_memDepot.clear(); TZLogInfo("memory pool dispose succeed~~~~"); return MEC_OK; } void * MemPool::AllocAvailMem(TZ_Uint32 expect) { tzc::ScopedLock lock(m_lock); for (TZ_INT idx = 0; idx < BLOCK_LIST_COUNT; ++idx) { if (expect <= (MIN_BLOCK_SIZE << idx)) { if (m_memDepot[idx].empty()) { TZLogDebug(2, "the memory list %d is empty!!!", idx); continue; } void * rst = m_memDepot[idx].front(); m_memDepot[idx].pop_front(); TZLogInfo("tang: expect %u, idx %d, rst %p, size %d~~~~", expect, idx, rst, m_memDepot[idx].size()); TZLogDebug(2, "get memblock 0x%x, expect %d~~~, size %d", rst, expect, (MIN_BLOCK_SIZE << idx)); return rst; } } TZLogWarn("get memory block for size %u failed!!!", expect); return nullptr; } TZ_INT MemPool::ReturnFreeMem(void * memBlock, TZ_Uint32 memSize) { tzc::ScopedLock lock(m_lock); for (TZ_INT idx = 0; idx < BLOCK_LIST_COUNT; ++idx) { if (memSize <= (MIN_BLOCK_SIZE << idx)) { std::list::iterator iter = std::find(m_memDepot[idx].begin(), m_memDepot[idx].end(), memBlock); if (iter != m_memDepot[idx].end()) { TZLogWarn("return repeat memBlock 0x%x!!!", memBlock); return MEC_DUPLICATED; } m_memDepot[idx].push_back(memBlock); TZLogDebug(10, "return memBlock 0x%x, size %d~~~", memBlock, (MIN_BLOCK_SIZE << idx)); return MEC_OK; } } TZLogWarn("illegal memory block 0x%x!!!", memBlock); return MEC_NULL_OBJ; } TZ_Uint32 MemPool::GetAvailCount(TZ_Uint32 expect) { tzc::ScopedLock lock(m_lock); if (expect <= MIN_BLOCK_SIZE) { return m_memDepot[0].size(); } for (TZ_INT idx = BLOCK_LIST_COUNT; idx != 0; --idx) { if (expect > (MIN_BLOCK_SIZE << (idx - 1))) { return m_memDepot[idx].size(); } } return 0; } NAMESPACE_MAS_END