自由链表类的设计
由于申请的空间块经过对齐之后大小至少为8,因此可以考虑在未被使用的内存块中取前8字节存储下一个空间的地址
FreeList类初步声明
class FreeList
{
private:
void* _freelist=nullptr; //自由链表头指针
size_t _size=0; //自由链表的长度
size_t _maxsize=1; //长度上限
public:
void Push(void* obj); //头插,从自由链表中插入一块空间
void* Pop(); //头删,从自由链表中取出一块空间
void PushRange(void* start,void* end,size_t n); //头插一段空间
void PopRange(void* end,size_t n);//头删一段空间
//start为一段空间的首地址,end为末地址,n为空间块个数
bool IsEmpty(); //判空
size_t& Maxsize(); //返回上限
size_t Size(); //返回当前长度
void* PeekHead(); //取表头,不删除
};
实现Push方法
void FreeList::Push(void* obj)
{
*(void**)obj=_freelist;
_freelist=obj;
++_size;
实现Pop方法
void* FreeList::Pop()
{
void* obj=_freelist;
_freelist=*(void**)obj;
--_size;
return obj;
}
当threadcache中空间不足(过剩)时需要向centralcache申请(归还)一批指定大小的空间,所得到(归还)的空间往往不会只有一个,而是一段已经链接好的空间块,因此还需要在FreeList中实现头插一段空间和头删一段空间
实现PopRange方法
void FreeList::PopRange(void* end,size_t n)
{
*(void**)end=_freelist;
_size-=n;
}
实现PushRange()方法
void FreeList::PushRange(void* start,void* end,size_t n)
{
*(void**)end=_freelist;
_freelist=start;
_size+=n;
}
SpanList的设计
声明Span结构
struct Span //管理
{
Span* _next = nullptr;
Span* _prev = nullptr;
void* _freelist = nullptr; //自由链表
size_t _useCount = 0; //分配的threadcache的个数
bool _isuse = false; //是否在被使用
size_t _objsize = 0; //切好的块大小
PAGE_ID _pageid = 0; //大块内存页码
size_t _n = 0; //页的数量
};
SpanList初步声明
class SpanList
{
private:
Span* _head=nullptr; //哨兵位
public:
std::mutex _mtx;//桶锁
public:
SpanList();
void Insert(Span* cur,Span* span); //在cur位置插入span
void Erase(Span* span); //删除span
Span* Begin(); //返回头节点
Span* End(); //返回尾节点
Span* Front(); //头删并返回
};
实现构造函数
SpanList::SpanList()
{
_head= new Span;
_head->_next=head;
_head->_prev=head
}
实现Insert方法
void SpanList::Insert(Span* cur, Span* newSpan)
{
assert(cur && newSpan);
newSpan->_next = cur;
newSpan->_prev = cur->_prev;
cur->_prev->_next = newSpan;
cur->_prev = newSpan;
}
实现Erase,Front方法
void SpanList::Erase(Span* cur)
{
assert(cur && cur != _head);
cur->_prev->_next = cur->_next;
cur->_next->_prev = cur->_prev;
//不需要delete cur,将cur交给下一层,不是系统
}
Span* SpanList::Front()
{
Span* span= _head->_next;
Erase(span);
return span;
}
实现Begin,End方法
Span* SpanList::Begin()
{
return _head->_next;
}
Span* SpanList::End()
{
return _head;
}