高并发内存池——链表设计

自由链表类的设计

由于申请的空间块经过对齐之后大小至少为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;
}
  • 15
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shall#

你的鼓励将是我前进的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值