greenplumn CMemoryPoolManager 源码
greenplumn CMemoryPoolManager 代码
文件路径:/src/backend/gporca/libgpos/src/memory/CMemoryPoolManager.cpp
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (c) 2004-2015 VMware, Inc. or its affiliates.
//
// @filename:
// CWorkerPoolManager.cpp
//
// @doc:
// Central scheduler;
// * maintains global worker-local-storage
// * keeps track of all worker pools
//---------------------------------------------------------------------------
#include "gpos/memory/CMemoryPoolManager.h"
#include "gpos/base.h"
#include "gpos/common/CAutoP.h"
#include "gpos/common/clibwrapper.h"
#include "gpos/error/CAutoTrace.h"
#include "gpos/memory/CMemoryPool.h"
#include "gpos/memory/CMemoryPoolTracker.h"
#include "gpos/memory/CMemoryVisitorPrint.h"
#include "gpos/task/CAutoSuspendAbort.h"
#include "gpos/task/CAutoTraceFlag.h"
using namespace gpos;
using namespace gpos::clib;
// global instance of memory pool manager
CMemoryPoolManager *CMemoryPoolManager::m_memory_pool_mgr = nullptr;
// ctor
CMemoryPoolManager::CMemoryPoolManager(CMemoryPool *internal,
EMemoryPoolType memory_pool_type)
: m_internal_memory_pool(internal),
m_ht_all_pools(nullptr),
m_memory_pool_type(memory_pool_type)
{
GPOS_ASSERT(nullptr != internal);
GPOS_ASSERT(GPOS_OFFSET(CMemoryPool, m_link) ==
GPOS_OFFSET(CMemoryPoolTracker, m_link));
}
// Set up CMemoryPoolManager's internals.
// This must be done here instead of the constructor because CMemoryPoolManager
// uses virtual methods for determining the correct CMemoryPool for
// allocations; and these virtual methods must not be called in the
// constructor, or else it will use the base class allocator instead of the one
// defined in derived-class virtual function.
void
CMemoryPoolManager::Setup()
{
m_ht_all_pools = GPOS_NEW(m_internal_memory_pool)
CSyncHashtable<CMemoryPool, ULONG_PTR>();
m_ht_all_pools->Init(
m_internal_memory_pool, GPOS_MEMORY_POOL_HT_SIZE,
GPOS_OFFSET(CMemoryPool, m_link), GPOS_OFFSET(CMemoryPool, m_hash_key),
&(CMemoryPool::m_invalid), HashULongPtr, EqualULongPtr);
// create pool used in allocations made using global new operator
m_global_memory_pool = CreateMemoryPool();
}
// Initialize global memory pool manager using CMemoryPoolTracker
GPOS_RESULT
CMemoryPoolManager::Init()
{
if (nullptr == CMemoryPoolManager::m_memory_pool_mgr)
{
return SetupGlobalMemoryPoolManager<CMemoryPoolManager,
CMemoryPoolTracker>();
}
return GPOS_OK;
}
CMemoryPool *
CMemoryPoolManager::CreateMemoryPool()
{
CMemoryPool *mp = NewMemoryPool();
// accessor scope
{
// HERE BE DRAGONS
// See comment in CCache::InsertEntry
const ULONG_PTR hashKey = mp->GetHashKey();
MemoryPoolKeyAccessor acc(*m_ht_all_pools, hashKey);
acc.Insert(mp);
}
return mp;
}
// Allocate a new NewMemoryPool
CMemoryPool *
CMemoryPoolManager::NewMemoryPool()
{
return GPOS_NEW(m_internal_memory_pool) CMemoryPoolTracker();
}
// Release given memory pool
void
CMemoryPoolManager::Destroy(CMemoryPool *mp)
{
GPOS_ASSERT(nullptr != mp);
// accessor scope
{
// HERE BE DRAGONS
// See comment in CCache::InsertEntry
const ULONG_PTR hashKey = mp->GetHashKey();
MemoryPoolKeyAccessor acc(*m_ht_all_pools, hashKey);
acc.Remove(mp);
}
mp->TearDown();
GPOS_DELETE(mp);
}
// Return total allocated size in bytes
ULLONG
CMemoryPoolManager::TotalAllocatedSize()
{
ULLONG total_size = 0;
MemoryPoolIter iter(*m_ht_all_pools);
while (iter.Advance())
{
MemoryPoolIterAccessor acc(iter);
CMemoryPool *mp = acc.Value();
if (nullptr != mp)
{
total_size = total_size + mp->TotalAllocatedSize();
}
}
return total_size;
}
// free memory allocation
void
CMemoryPoolManager::DeleteImpl(void *ptr, CMemoryPool::EAllocationType eat)
{
CMemoryPoolTracker::DeleteImpl(ptr, eat);
}
// get user requested size of allocation
ULONG
CMemoryPoolManager::UserSizeOfAlloc(const void *ptr)
{
return CMemoryPoolTracker::UserSizeOfAlloc(ptr);
}
#ifdef GPOS_DEBUG
// Print contents of all allocated memory pools
IOstream &
CMemoryPoolManager::OsPrint(IOstream &os)
{
os << "Print memory pools: " << std::endl;
MemoryPoolIter iter(*m_ht_all_pools);
while (iter.Advance())
{
CMemoryPool *mp = nullptr;
{
MemoryPoolIterAccessor acc(iter);
mp = acc.Value();
}
if (nullptr != mp)
{
os << *mp << std::endl;
}
}
return os;
}
// Print memory pools with total allocated size above given threshold
void
CMemoryPoolManager::PrintOverSizedPools(
CMemoryPool *trace,
ULLONG size_threshold // size threshold in bytes
)
{
MemoryPoolIter iter(*m_ht_all_pools);
while (iter.Advance())
{
MemoryPoolIterAccessor acc(iter);
CMemoryPool *mp = acc.Value();
if (nullptr != mp)
{
ULLONG size = mp->TotalAllocatedSize();
if (size > size_threshold)
{
CAutoTrace at(trace);
at.Os() << std::endl
<< "OVERSIZED MEMORY POOL: " << size << " bytes "
<< std::endl;
}
}
}
}
#endif // GPOS_DEBUG
// Destroy a memory pool at shutdown
void
CMemoryPoolManager::DestroyMemoryPoolAtShutdown(CMemoryPool *mp)
{
GPOS_ASSERT(nullptr != mp);
#ifdef GPOS_DEBUG
gpos::oswcerr << "Leaked " << *mp << std::endl;
#endif // GPOS_DEBUG
mp->TearDown();
GPOS_DELETE(mp);
}
// Clean-up memory pools
// Counterpart to CMemoryPoolManager::Setup()
void
CMemoryPoolManager::Cleanup()
{
#ifdef GPOS_DEBUG
if (0 < m_global_memory_pool->TotalAllocatedSize())
{
// allocations made by calling global new operator are not deleted
gpos::oswcerr << "Memory leaks detected" << std::endl
<< *m_global_memory_pool << std::endl;
}
#endif // GPOS_DEBUG
GPOS_ASSERT(nullptr != m_global_memory_pool);
Destroy(m_global_memory_pool);
// cleanup left-over memory pools;
// any such pool means that we have a leak
m_ht_all_pools->DestroyEntries(DestroyMemoryPoolAtShutdown);
GPOS_DELETE(m_ht_all_pools);
}
// Delete memory pools and release manager
void
CMemoryPoolManager::Shutdown()
{
// cleanup remaining memory pools
Cleanup();
// save off pointers for explicit deletion
CMemoryPool *internal = m_internal_memory_pool;
::delete CMemoryPoolManager::m_memory_pool_mgr;
CMemoryPoolManager::m_memory_pool_mgr = nullptr;
#ifdef GPOS_DEBUG
internal->AssertEmpty(oswcerr);
#endif // GPOS_DEBUG
Free(internal);
}
// EOF
相关信息
相关文章
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦