6#include "libxr_def.hpp"
24template <
typename Data>
41 union alignas(LIBXR_CACHE_LINE_SIZE)
Slot
49 uint8_t pad[LIBXR_CACHE_LINE_SIZE];
60 : SLOT_COUNT(slot_count),
61 slots_(new(std::align_val_t(LIBXR_CACHE_LINE_SIZE))
Slot[slot_count])
63 for (uint32_t index = 0; index < SLOT_COUNT; index++)
65 slots_[index].slot.state.store(SlotState::FREE, std::memory_order_relaxed);
82 ErrorCode
Put(
const Data &data)
84 uint32_t start_index = 0;
85 return Put(data, start_index);
98 ErrorCode
Put(
const Data &data, uint32_t &start_index)
100 for (uint32_t index = start_index; index < SLOT_COUNT; index++)
102 auto expected = slots_[index].slot.state.load(std::memory_order_relaxed);
103 if (expected == SlotState::FREE || expected == SlotState::RECYCLE)
105 if (slots_[index].slot.state.compare_exchange_strong(expected, SlotState::BUSY,
106 std::memory_order_release,
107 std::memory_order_relaxed))
109 slots_[index].slot.data = data;
110 slots_[index].slot.state.store(SlotState::READY, std::memory_order_release);
112 return ErrorCode::OK;
116 return ErrorCode::FULL;
130 auto expected = slots_[index].slot.state.load(std::memory_order_relaxed);
131 if (expected == SlotState::FREE || expected == SlotState::RECYCLE)
133 if (slots_[index].slot.state.compare_exchange_strong(expected, SlotState::BUSY,
134 std::memory_order_release,
135 std::memory_order_relaxed))
137 slots_[index].slot.data = data;
138 slots_[index].slot.state.store(SlotState::READY, std::memory_order_release);
139 return ErrorCode::OK;
142 return ErrorCode::FULL;
155 uint32_t start_index = 0;
157 return Get(data, start_index);
170 ErrorCode
Get(Data &data, uint32_t &start_index)
172 for (uint32_t index = start_index; index < SLOT_COUNT; index++)
174 auto expected = slots_[index].slot.state.load(std::memory_order_acquire);
175 if (expected == SlotState::READY)
177 if (slots_[index].slot.state.compare_exchange_strong(expected, SlotState::BUSY,
178 std::memory_order_acquire,
179 std::memory_order_relaxed))
181 data = slots_[index].slot.data;
182 slots_[index].slot.state.store(SlotState::RECYCLE, std::memory_order_release);
184 return ErrorCode::OK;
187 if (expected == SlotState::FREE)
190 return ErrorCode::EMPTY;
195 return ErrorCode::EMPTY;
209 auto expected = slots_[index].slot.state.load(std::memory_order_acquire);
210 if (expected == SlotState::READY)
212 if (slots_[index].slot.state.compare_exchange_strong(expected, SlotState::BUSY,
213 std::memory_order_acquire,
214 std::memory_order_relaxed))
216 data = slots_[index].slot.data;
217 slots_[index].slot.state.store(SlotState::RECYCLE, std::memory_order_release);
218 return ErrorCode::OK;
221 return ErrorCode::EMPTY;
234 auto expected = slots_[index].slot.state.load(std::memory_order_relaxed);
235 if (expected == SlotState::READY)
237 if (slots_[index].slot.state.compare_exchange_strong(expected, SlotState::RECYCLE,
238 std::memory_order_release,
239 std::memory_order_relaxed))
241 return ErrorCode::OK;
244 return ErrorCode::EMPTY;
251 [[nodiscard]]
size_t Size()
const
254 for (uint32_t index = 0; index < SLOT_COUNT; index++)
256 if (slots_[index].slot.state.load(std::memory_order_relaxed) == SlotState::READY)
271 for (uint32_t index = 0; index < SLOT_COUNT; index++)
273 auto state = slots_[index].slot.state.load(std::memory_order_relaxed);
274 if (state == SlotState::FREE || state == SlotState::RECYCLE)
290 Slot &operator[](uint32_t index)
292 if (index >= SLOT_COUNT)
296 return slots_[index];
无锁无序槽池 / 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
uint32_t SlotCount() const
获取槽总数 / Get the total number of slots in the pool
单个槽结构体 / Individual slot structure (cache line aligned)
Data data
槽内数据 / Stored data
std::atomic< SlotState > state
当前槽状态 / Current state