Files
Sun1602/Utility/MemoryPoolFactory.cpp
2022-10-26 12:25:11 +08:00

323 lines
11 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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<Token>
{
void* ptr_;
};
struct MemoryPoolSizeBased::TokenBlock : public util::__LList<TokenBlock>
{
#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<Token*>(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<Token*>(&free_list_);
Token* token = root->next;
while (token != root)
{
Token* next_token = util::LList::Delete(token);
util::internal::NodeHdrPtr* hdr =
reinterpret_cast<util::internal::NodeHdrPtr*>(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<Token*>(&alloc_list_);
Token* token = root->next;
while (token != root)
{
Token* next_token = util::LList::Delete(token);
util::internal::NodeHdrPtr* hdr =
reinterpret_cast<util::internal::NodeHdrPtr*>(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<TokenBlock*>(&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
//==================================================================================================
//==================================================================================================
//==================================================================================================