#include "UtilityCommon.h" #include "MemoryPoolFactory.h" //#include "MemoryPoolFactoryV.h" //#include "MemoryPoolFactoryV2.h" #if 0 //================================================================================================== //================================================================================================== //================================================================================================== #elif MEMORY_POOL_FACTORY_VERSION >= 0x0300 //================================================================================================== //================================================================================================== //================================================================================================== //重构(改为虚拟内存池路由器和增强的异常处理) //版本2.1-由Waverix编写 //2011年05月14日:3.0版,重构,改变内部数据结构 //在客户端应用程序之后使用共享内存架构。 //这个实现是基于WxFramework::MemoryPoolSizeBased的剥离版本 //以及WxFramework::MemoryPool。 util::IVMemoryPool::~IVMemoryPool() { } namespace util { namespace internal { ; struct MemoryPoolSizeBased::Token : public util::__LList { void* ptr_; }; struct MemoryPoolSizeBased::TokenBlock : public util::__LList { #pragma warning(push) #pragma warning(disable:4200) MemoryPoolSizeBased::Token stream_[0]; #pragma warning(pop) }; // NOTE: f110525.6L // specification // ------------------------------------------------------------------------------------------------- // | SharedMemoryHeaderSection | NodeHdrPtr | Node... | // | alloc/free & leak check | pool node mark | result of new, deletion ptr | struct NodeHdrPtr { void* parent_; }; }}; //end of namespace //================================================================================================== //================================================================================================== //================================================================================================== util::internal::MemoryPoolSizeBased::MemoryPoolSizeBased( size_t type_size, func_object_lifetime instance_func, func_object_lifetime delete_func) : type_size_(type_size + sizeof(util::internal::NodeHdrPtr)) , init_count_(0) , growth_count_(0) , type_name_("") , instance_func_(instance_func) , delete_func_(delete_func) { util::LList::Init(&free_list_); util::LList::Init(&alloc_list_); util::LList::Init(&total_list_); ZeroMemory(&statistics_, sizeof(statistics_)); } void util::internal::MemoryPoolSizeBased::Initialize( size_t init_size, size_t chunk_size, const char* type_name) { init_count_ = init_size; growth_count_ = chunk_size; if (growth_count_ == 0) { chunk_size = (init_count_ >> 1); growth_count_ = (chunk_size == 0) ? 1 : chunk_size; }; type_name_ = type_name ? type_name : ""; if (init_count_) { AddBlock(init_count_); }; } util::internal::MemoryPoolSizeBased::~MemoryPoolSizeBased() { FreeAllElements(); } void* util::internal::MemoryPoolSizeBased::Allocate() { if (util::LList::IsEmpty(&free_list_)) { AddBlock(growth_count_); }; Token* token = free_list_.next; util::LList::Delete(token); --statistics_.number_of_free_nodes; // 'util::internal::NodeHdrPtr*' == 'token->ptr_' util::internal::NodeHdrPtr* hdr = ((util::internal::NodeHdrPtr*)token->ptr_); hdr->parent_ = token; // CHANGES: f110708.1L // util::LList::AddPrev(token, &alloc_list_); ++statistics_.number_of_alloc_nodes; // void* ptr = hdr + 1; return ptr; } void util::internal::MemoryPoolSizeBased::Deallocate(void* element) { // sync缠绕可能会发生问题。再验证一下. if (FlowControl::FCAssert(util::LList::IsEmpty(&alloc_list_) == false)) { #ifdef _SERVER return; #endif //_SERVER // '(util::internal::NodeHdrPtr*) + 1' == user control pointer util::internal::NodeHdrPtr* hdr = ((util::internal::NodeHdrPtr*)(element)) - 1; // #if USING_SUN_SHARED_POOL // CHANGES: f110811.3L, 修复了客户端(用户发布版本)内存泄漏 if (FlowControl::FCAssert(SharedMemoryPool::CheckValidAllocatedMemory(hdr)) == false) { return; // 内存损坏,发生泄漏 }; // #endif if (hdr == NULL || hdr->parent_ == NULL) { return; } Token* token = reinterpret_cast(hdr->parent_); if (FlowControl::FCAssert(token->ptr_ == hdr) == false) { return; // 泄漏发生 }; hdr->parent_ = NULL; // util::LList::Delete(token); --statistics_.number_of_alloc_nodes; util::LList::AddPrev(token, &free_list_); ++statistics_.number_of_free_nodes; } } void util::internal::MemoryPoolSizeBased::AddBlock(size_t element_count) { const int token_node_size = int(sizeof(Token) * element_count); const int elements_size = int(element_count * type_size_); __TOUCHED(elements_size); // #ifdef USING_SUN_SHARED_POOL_EXCEPT_MALLOC TokenBlock* block = (TokenBlock*)SharedMemoryPool::MemoryAllocate((sizeof(TokenBlock) + token_node_size), NULL, 0); #else TokenBlock* block = (TokenBlock*)TAllocMalloc(sizeof(TokenBlock) + token_node_size); #endif //USING_SUN_SHARED_POOL_EXCEPT_MALLOC ZeroMemory(block, sizeof(TokenBlock) + token_node_size); util::LList::Init(block); util::LList::AddPrev(block, &total_list_); ++statistics_.number_of_total_blocks; Token* const tokens = block->stream_; Token* token = tokens; for (size_t i = 0; i < element_count; ++i, ++token) { // init tokens util::LList::Init(token); #ifdef USING_SUN_SHARED_POOL_EXCEPT_MALLOC token->ptr_ = SharedMemoryPool::MemoryAllocate(type_size_, NULL, 0); #else token->ptr_ = TAllocMalloc(type_size_); #endif //USING_SUN_SHARED_POOL_EXCEPT_MALLOC // 'util::internal::NodeHdrPtr*' == 'token->ptr_' util::internal::NodeHdrPtr* hdr = ((util::internal::NodeHdrPtr*)token->ptr_); hdr->parent_ = token; if (instance_func_) { instance_func_(hdr + 1); }; util::LList::AddPrev(token, &free_list_); ++statistics_.number_of_free_nodes; }; } #if _BUILD_FLAG_SHARED_MEMORY_NEWDEL_SYNC_CHECK_ void util::internal::MemoryPoolSizeBased::DeadBeef(Element* element) { int* it = &element->deadBeef; int* itend = (int*)((byte*)element + elementSize_); while(it < itend) *it++ = 0xDEADBEEF; } #endif //------------------------------------------------------------------------------ // () // name: // usage: void util::internal::MemoryPoolSizeBased::FreeAllElements() { ;{ size_t counter = 0; Token* root = static_cast(&free_list_); Token* token = root->next; while (token != root) { Token* next_token = util::LList::Delete(token); util::internal::NodeHdrPtr* hdr = reinterpret_cast(token->ptr_); void* ptr = hdr + 1; if (delete_func_) { delete_func_(ptr); }; #ifdef USING_SUN_SHARED_POOL_EXCEPT_MALLOC SharedMemoryPool::MemoryDeAllocate(hdr); #else TAllocFree(hdr); #endif //USING_SUN_SHARED_POOL_EXCEPT_MALLOC token = next_token; ++counter; }; if (FlowControl::FCAssert(statistics_.number_of_free_nodes == counter) == false) { SUNLOG(eCRITICAL_LOG, _T("|信息=“%s”工厂中不匹配的可用节点(%u:%u)"), statistics_.number_of_free_nodes, counter, type_name_); }; statistics_.number_of_free_nodes = 0; }; ;{ size_t counter = 0; Token* root = static_cast(&alloc_list_); Token* token = root->next; while (token != root) { Token* next_token = util::LList::Delete(token); util::internal::NodeHdrPtr* hdr = reinterpret_cast(token->ptr_); void* ptr = hdr + 1; if (delete_func_) { delete_func_(ptr); }; #ifdef USING_SUN_SHARED_POOL_EXCEPT_MALLOC SharedMemoryPool::MemoryDeAllocate(hdr); #else TAllocFree(hdr); #endif //USING_SUN_SHARED_POOL_EXCEPT_MALLOC token = next_token; ++counter; } if (FlowControl::FCAssert(statistics_.number_of_alloc_nodes == counter) == false) { SUNLOG(eCRITICAL_LOG, _T("|信息=“%s”工厂中分配的节点(%u:%u)不匹配"), statistics_.number_of_alloc_nodes, counter, type_name_); }; statistics_.number_of_alloc_nodes = 0; }; ;{ size_t counter = 0; TokenBlock* root = static_cast(&total_list_); TokenBlock* token = root->next; while (token != root) { TokenBlock* next_token = util::LList::Delete(token); #ifdef USING_SUN_SHARED_POOL_EXCEPT_MALLOC SharedMemoryPool::MemoryDeAllocate(token); #else TAllocFree(hdr); #endif //USING_SUN_SHARED_POOL_EXCEPT_MALLOC token = next_token; ++counter; } if (FlowControl::FCAssert(statistics_.number_of_total_blocks == counter) == false) { SUNLOG(eCRITICAL_LOG, _T("|信息=“%s”工厂中不匹配的令牌块节点(%u:%u)"), statistics_.number_of_total_blocks, counter, type_name_); }; statistics_.number_of_total_blocks = 0; }; } //================================================================================================== //================================================================================================== //================================================================================================== #elif MEMORY_POOL_FACTORY_VERSION >= 0x0210 //================================================================================================== //================================================================================================== //================================================================================================== namespace util { VOID AssertionLogger4Pool_Default( DWORD errTYPE, ePOOL_ERROR* IN pINFO ) { TCHAR* pErrTypeMsg = ePOOL_ERROR::INVALID_REFERENCE == errTYPE ? _T("Freeing Address is Can't Accessable") : ePOOL_ERROR::CANT_ALLOCATABLE == errTYPE ? _T("Can't Allocatable") : ePOOL_ERROR::CANT_DEALLOCATABLE == errTYPE ? _T("Can't DeAllocatable, STAT(Already Freed | Invalid Reference | Overrun)") : ePOOL_ERROR::NOT_MATCHED_ALLOCnDEALLOC == errTYPE ? _T("Free Count is not matched AllocCount") : NULL; //MessageOut( 3, _T("[POOL ASSERTION][TYPE:%s] \"%s\""), pINFO->m_pszTYPENAME, pErrTypeMsg ); printf( _T("[POOL ASSERTION][TYPE:%s] \"%s\"\n"), pINFO->m_pszTYPENAME, pErrTypeMsg ); # ifdef _DEBUG __debugbreak(); # endif // } } // //================================================================================================== //================================================================================================== //================================================================================================== #endif //MEMORY_POOL_FACTORY_VERSION >= 0x0210 //================================================================================================== //================================================================================================== //==================================================================================================