目录
- 1.申请过程
- 2.释放过程
1.申请过程
当申请的内存大于256kb时直接向堆中申请:
static void* ConcurrentAlloc(size_t size)
{
if (size > MAX_BYTES)
{
size_t alignSize = SizeClass::RoundUp(size);
size_t kpage = alignSize >> PAGE_SHIFT;
PageCache::GetInstance()->_pageMtx.lock();
Span* span = PageCache::GetInstance()->NewSpan(kpage);
span->_objSize = size;
PageCache::GetInstance()->_pageMtx.unlock();
void* ptr = (void*)(span->_pageId << PAGE_SHIFT);
return ptr;
}
else
{
//通过TLS每个线程无锁的获取自己专属的ThreadCache对象
if (pTLSThreadCache == nullptr)
{
//pTLSThreadCache = new ThreadCache;
static ObjectPool<ThreadCache> tcPool;
pTLSThreadCache = tcPool.New();
}
//cout << "id:" << std::this_thread::get_id() << " pTLSThreadCache :" << pTLSThreadCache << endl;
return pTLSThreadCache->Allocate(size);
}
}
- NewSpan
//获取一个K页的span
Span* PageCache::NewSpan(size_t k)
{
assert(k > 0 );
//大于128页的直接向堆申请
if (k > NPAGES - 1)
{
void* ptr = SystemAlloc(k);
//Span* span = new Span;
Span* span = _spanPool.New();
span->_pageId = (PAGE_ID)ptr >> PAGE_SHIFT;
span->_n = k;
//_idSpanMap[span->_pageId] = span;
_idSpanMap.set(span->_pageId, span);
return span;
}
2.释放过程
static void ConcurrentFree(void* ptr)
{
assert(pTLSThreadCache);
assert(ptr);
Span* span = PageCache::GetInstance()->MapObjectToSpan(ptr);
size_t size = span->_objSize;
if (size > MAX_BYTES)
{
PageCache::GetInstance()->_pageMtx.lock();
PageCache::GetInstance()->ReleaseSpanToPageCache(span);
PageCache::GetInstance()->_pageMtx.unlock();
}
else
{
pTLSThreadCache->Deallocate(ptr, size);
}
}
直接还给堆。