一.ConcurrentAlloc
提供给上一层用户申请内存调用,调用时会创建出当前线程的内存线程缓冲区,同时进入内存池逻辑
static void* ConcurrentAlloc(size_t size)
{
//当申请小于等于256kb内存的时候可直接使用当前内存池也是内存大小在(1~32)页的内存范围内时
//当申请内存大于32页并小于128页的时候,可以跳过当前内存池的前半部分直接去page里去申请,这样也能利用到内存池
//当申请内存大于128页的时候直接调用内存函数去内存里申请
if (size > MAX_BYTES)//统一处理大于内存池大小的内存存申请
{
//同样先计算内存对齐数数
size_t alignSize = SizeRules::ApplicationSize(size);
//通过内存对齐数计算计算申请几页内存
size_t kpage = alignSize >> PAGE_SHIFT;
//直接通过pagecache区申请内存需要加锁
PageCache::GetInstance()->Getmtx().lock();
Span* span = PageCache::GetInstance()->NewSpan(kpage);
span->_objSize = size;
PageCache::GetInstance()->Getmtx().unlock();
//获得到的大块内存块span就是要返回的内存地址,通过span页号转换为物理地址并返回
void* ret = (void*)(span->_pageid << PAGE_SHIFT);
return ret;
}
else
{
//通过定长内存池获取线程内部专属缓存空间
if (pTLSThreadCache == nullptr)
{
static ObjectPool<ThreadCache> tcpool;
pTLSThreadCache = tcpool.New();
//pTLSThreadCache = new ThreadCache;
}
//测试
//cout << std::this_thread::get_id << ":线程内存地址:" << pTLSThreadCache<<endl;
//调用线程内部缓存空间调用allocate函数分配内存
return pTLSThreadCache->Allocate(size);
}
}
二.释放函数
//内存释放函数
static void* ConcurrentFree(void* ptr)
{
assert(ptr);
Span* span = PageCache::GetInstance()->MapObjectToSpan(ptr);//通过物理地址转换出span并获取到span结构体内部的小块内存大小
size_t size = span->_objSize;
if (size > MAX_BYTES)//大于内存池范围的统一直接还给page区
{
Span* span = PageCache::GetInstance()->MapObjectToSpan(ptr);
PageCache::GetInstance()->Getmtx().lock();
PageCache::GetInstance()->ReleaseSpanToPageCache(span);
PageCache::GetInstance()->Getmtx().unlock();
return nullptr;
}
//调用线程内部缓存空间调用Deallocate函数释放内存
else
{
return pTLSThreadCache->Deallocate(ptr, size);
}
}
因为我们需要知道释放内存的大小才能把它挂到自由链表上,后期处理。