自由链表类的设计
由于申请的空间块经过对齐之后大小至少为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位置插入spanvoid Erase(Span* span); //删除spanSpan* 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;
}