MemoryPool的LockFree实现

由于未提供博客内容,无法生成包含关键信息的摘要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
#include "memoryPool.h" namespace Kama_memoryPool { MemoryPool::MemoryPool(size_t BlockSize) : BlockSize_(BlockSize) , SlotSize_(0) , firstBlock_(nullptr) , curSlot_(nullptr) , freeList_(nullptr) , lastSlot_(nullptr) {} MemoryPool::~MemoryPool() { // 把连续的block删除 Slot* cur = firstBlock_; while (cur) { Slot* next = cur->next; // 等同于 free(reinterpret_cast<void*>(firstBlock_)); // 转化为 void 指针,因为 void 类型不需要调用析构函数,只释放空间 operator delete(reinterpret_cast<void*>(cur)); cur = next; } } void MemoryPool::init(size_t size) { assert(size > 0); SlotSize_ = size; firstBlock_ = nullptr; curSlot_ = nullptr; freeList_ = nullptr; lastSlot_ = nullptr; } void* MemoryPool::allocate() { // 优先使用空闲链表中的内存槽 Slot* slot = popFreeList(); if (slot != nullptr) return slot; Slot* temp; { std::lock_guard<std::mutex> lock(mutexForBlock_); if (curSlot_ >= lastSlot_) { // 当前内存块已无内存槽可用,开辟一块新的内存 allocateNewBlock(); } temp = curSlot_; // 这里不能直接 curSlot_ += SlotSize_ 因为curSlot_是Slot*类型,所以需要除以SlotSize_再加1 curSlot_ += SlotSize_ / sizeof(Slot); } return temp; } void MemoryPool::deallocate(void* ptr) { if (!ptr) return; Slot* slot = reinterpret_cast<Slot*>(ptr); pushFreeList(slot); } void MemoryPool::allocateNewBlock() { //std::cout << "申请一块内存块,SlotSize: " << SlotSize_ << std::endl; // 头插法插入新的内存块 void* newBlock = operator new(BlockSize_); reinterpret_cast<Slot*>(newBlock)->next = firstBlock_; firstBlock_ = reinterpret_cast<Slot*>(newBlock); char* body = reinterpret_cast<char*>(newBlock) + sizeof(Slot*); size_t paddingSize = padPointer(body, SlotSize_); // 计算对齐需要填充内存的大小 curSlot_ = reinterpret_cast<Slot*>(body + paddingSize); // 超过该标记位置,则说明该内存块已无内存槽可用,需向系统申请新的内存块 lastSlot_ = reinterpret_cast<Slot*>(reinterpret_cast<size_t>(newBlock) + BlockSize_ - SlotSize_ + 1); freeList_ = nullptr; } // 让指针对齐到槽大小的倍数位置 size_t MemoryPool::padPointer(char* p, size_t align) { // align 是槽大小 return (align - reinterpret_cast<size_t>(p)) % align; } // 实现无锁入队操作 bool MemoryPool::pushFreeList(Slot* slot) { while (true) { // 获取当前头节点 Slot* oldHead = freeList_.load(std::memory_order_relaxed); // 将新节点的 next 指向当前头节点 slot->next.store(oldHead, std::memory_order_relaxed); // 尝试将新节点设置为头节点 if (freeList_.compare_exchange_weak(oldHead, slot, std::memory_order_release, std::memory_order_relaxed)) { return true; } // 失败:说明另一个线程可能已经修改了 freeList_ // CAS 失败则重试 } } // 实现无锁出队操作 Slot* MemoryPool::popFreeList() { while (true) { Slot* oldHead = freeList_.load(std::memory_order_acquire); if (oldHead == nullptr) return nullptr; // 队列为空 // 在访问 newHead 之前再次验证 oldHead 的有效性 Slot* newHead = nullptr; try { newHead = oldHead->next.load(std::memory_order_relaxed); } catch (...) { // 如果返回失败,则continue重新尝试申请内存 continue; } // 尝试更新头结点 // 原子性地尝试将 freeList_ 从 oldHead 更新为 newHead if (freeList_.compare_exchange_weak(oldHead, newHead, std::memory_order_acquire, std::memory_order_relaxed)) { return oldHead; } // 失败:说明另一个线程可能已经修改了 freeList_ // CAS 失败则重试 } } void HashBucket::initMemoryPool() { for (int i = 0; i < MEMORY_POOL_NUM; i++) { getMemoryPool(i).init((i + 1) * SLOT_BASE_SIZE); } } // 单例模式 MemoryPool& HashBucket::getMemoryPool(int index) { static MemoryPool memoryPool[MEMORY_POOL_NUM]; return memoryPool[index]; } } // namespace memoryPool 对这部分代码做注释,越详细越好
最新发布
06-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值