6#include "libxr_def.hpp"
24template <
typename Data>
41 union alignas(LIBXR_CACHE_LINE_SIZE)
Slot
49 uint8_t pad[LIBXR_CACHE_LINE_SIZE];
57 : SLOT_COUNT(slot_count),
58 slots_(new(std::align_val_t(LIBXR_CACHE_LINE_SIZE))
Slot[slot_count])
60 for (uint32_t index = 0; index < SLOT_COUNT; index++)
62 slots_[index].slot.state.store(SlotState::FREE, std::memory_order_relaxed);
79 ErrorCode
Put(
const Data &data)
81 uint32_t start_index = 0;
82 return Put(data, start_index);
95 ErrorCode
Put(
const Data &data, uint32_t &start_index)
97 for (uint32_t index = start_index; index < SLOT_COUNT; index++)
99 auto expected = slots_[index].slot.state.load(std::memory_order_relaxed);
100 if (expected == SlotState::FREE || expected == SlotState::RECYCLE)
102 if (slots_[index].slot.state.compare_exchange_strong(expected, SlotState::BUSY,
103 std::memory_order_release,
104 std::memory_order_relaxed))
106 slots_[index].slot.data = data;
107 slots_[index].slot.state.store(SlotState::READY, std::memory_order_release);
109 return ErrorCode::OK;
113 return ErrorCode::FULL;
127 auto expected = slots_[index].slot.state.load(std::memory_order_relaxed);
128 if (expected == SlotState::FREE || expected == SlotState::RECYCLE)
130 if (slots_[index].slot.state.compare_exchange_strong(expected, SlotState::BUSY,
131 std::memory_order_release,
132 std::memory_order_relaxed))
134 slots_[index].slot.data = data;
135 slots_[index].slot.state.store(SlotState::READY, std::memory_order_release);
136 return ErrorCode::OK;
139 return ErrorCode::FULL;
152 uint32_t start_index = 0;
154 return Get(data, start_index);
167 ErrorCode
Get(Data &data, uint32_t &start_index)
169 for (uint32_t index = start_index; index < SLOT_COUNT; index++)
171 auto expected = slots_[index].slot.state.load(std::memory_order_acquire);
172 if (expected == SlotState::READY)
174 if (slots_[index].slot.state.compare_exchange_strong(expected, SlotState::BUSY,
175 std::memory_order_acquire,
176 std::memory_order_relaxed))
178 data = slots_[index].slot.data;
179 slots_[index].slot.state.store(SlotState::RECYCLE, std::memory_order_release);
181 return ErrorCode::OK;
184 if (expected == SlotState::FREE)
187 return ErrorCode::EMPTY;
192 return ErrorCode::EMPTY;
206 auto expected = slots_[index].slot.state.load(std::memory_order_acquire);
207 if (expected == SlotState::READY)
209 if (slots_[index].slot.state.compare_exchange_strong(expected, SlotState::BUSY,
210 std::memory_order_acquire,
211 std::memory_order_relaxed))
213 data = slots_[index].slot.data;
214 slots_[index].slot.state.store(SlotState::RECYCLE, std::memory_order_release);
215 return ErrorCode::OK;
218 return ErrorCode::EMPTY;
231 auto expected = slots_[index].slot.state.load(std::memory_order_relaxed);
232 if (expected == SlotState::READY)
234 if (slots_[index].slot.state.compare_exchange_strong(expected, SlotState::RECYCLE,
235 std::memory_order_release,
236 std::memory_order_relaxed))
238 return ErrorCode::OK;
241 return ErrorCode::EMPTY;
248 [[nodiscard]]
size_t Size()
const
251 for (uint32_t index = 0; index < SLOT_COUNT; index++)
253 if (slots_[index].slot.state.load(std::memory_order_relaxed) == SlotState::READY)
268 for (uint32_t index = 0; index < SLOT_COUNT; index++)
270 auto state = slots_[index].slot.state.load(std::memory_order_relaxed);
271 if (state == SlotState::FREE || state == SlotState::RECYCLE)
无锁无序槽池 / Lock-free, unordered slot pool
size_t EmptySize()
查询当前池可用槽数量 / Query the number of writable slots in the pool
ErrorCode GetFromSlot(Data &data, uint32_t index)
从指定槽位开始,取出一个元素 / Retrieve an element from the pool
Slot * slots_
槽数组指针 / Array of slots
~LockFreePool()
析构,释放槽池内存 / Destructor, releasing pool memory
ErrorCode PutToSlot(const Data &data, uint32_t index)
向指定槽放入一个元素 / Put an element into a specific slot
ErrorCode Get(Data &data, uint32_t &start_index)
从指定槽位开始,取出一个元素 / Retrieve an element from the pool
SlotState
槽状态 / Slot state
@ RECYCLE
已读待回收 / Slot was read, waiting for next write.
@ READY
写入完成,可读 / Slot contains valid data, ready to read.
@ BUSY
正在写入 / Slot is being written.
@ FREE
空闲,可写 / Slot is free and can be written.
LockFreePool(uint32_t slot_count)
构造对象池 / Constructor for the pool
ErrorCode RecycleSlot(uint32_t index)
回收指定槽位 / Recycle a slot
ErrorCode Put(const Data &data)
向池中放入一个元素 / Put an element into the pool
const uint32_t SLOT_COUNT
槽总数 / Number of slots
ErrorCode Get(Data &data)
从池中取出一个元素 / Retrieve an element from the pool
ErrorCode Put(const Data &data, uint32_t &start_index)
向池中放入一个元素,返回起始槽索引 / Put an element into the pool and return the starting slot index
size_t Size() const
查询池中可取元素数量 / Query the number of available elements in the pool
单个槽结构体 / Individual slot structure (cache line aligned)
Data data
槽内数据 / Stored data
std::atomic< SlotState > state
当前槽状态 / Current state