9 : slot_size_(slot_size),
10 slot_count_(slot_count),
11 slot_stride_(AlignUp(slot_size_, slot_align)),
12 alloc_align_(std::
max(alignof(std::max_align_t), slot_align)),
21 ASSERT(slot_align > 0);
23 ASSERT(
slot_stride_ <= std::numeric_limits<size_t>::max() / slot_align);
30 slots_ =
static_cast<std::byte*
>(
33 for (
size_t index = 0; index <
slot_count_; ++index)
36 seqs_[index].store(0, std::memory_order_relaxed);
54 uint32_t release_begin =
release_count_.load(std::memory_order_acquire);
55 bool rescanned =
false;
68 std::memory_order_acq_rel,
69 std::memory_order_acquire))
78 const uint32_t release_end =
release_count_.load(std::memory_order_acquire);
79 if (release_end == release_begin || rescanned)
83 release_begin = release_end;
95 const uint32_t seq =
publish_seq_.fetch_add(1, std::memory_order_release);
96 seqs_[index].store(seq, std::memory_order_relaxed);
99 const bool ok =
states_[index].compare_exchange_strong(
100 expected,
SLOT_READY, std::memory_order_release, std::memory_order_acquire);
106 bool rescanned =
false;
113 const uint32_t pass_begin =
publish_seq_.load(std::memory_order_acquire);
115 uint32_t best_seq = 0;
124 const uint32_t seq =
seqs_[i].load(std::memory_order_relaxed);
142 if (!SeqBefore(best_seq, pass_begin))
149 std::memory_order_acq_rel,
150 std::memory_order_acquire))
159 if (
seqs_[best].load(std::memory_order_relaxed) == best_seq)
165 const bool undone =
states_[best].compare_exchange_strong(
166 reading,
SLOT_READY, std::memory_order_release, std::memory_order_acquire);
175 const uint32_t publish_end =
publish_seq_.load(std::memory_order_acquire);
176 if (publish_end == pass_begin || rescanned)
193 uint32_t expected =
states_[index].load(std::memory_order_relaxed);
197 const bool ok =
states_[index].compare_exchange_strong(
198 expected,
SLOT_FREE, std::memory_order_release, std::memory_order_acquire);
214size_t SlotPoolBase::AlignUp(
size_t value,
size_t align)
216 ASSERT(value <= std::numeric_limits<size_t>::max() - (align - 1));
217 return ((value + align - 1) / align) * align;
~SlotPoolBase()
析构槽池内核 / Destroy the slot-pool core.
ErrorCode Take(size_t &index)
认领序号最小的就绪槽(就绪 → 读取中) / Claim the oldest ready slot (ready -> reading).
void * SlotPtr(size_t index)
获取指定槽位的存储地址 / Get the storage address of one slot.
const size_t alloc_align_
std::byte * slots_
槽存储缓冲区 / Byte buffer storing slots.
const size_t slot_count_
槽总数 / Total number of slots.
std::atomic< uint32_t > publish_seq_
std::atomic< uint32_t > * states_
每槽状态字 / Per-slot atomic state word.
std::atomic< uint32_t > release_count_
const size_t slot_stride_
相邻槽位之间的步长 / Byte stride between slots.
const size_t slot_size_
单个槽的字节数 / Byte size of one slot.
std::atomic< uint32_t > * seqs_
每槽发布序号 / Per-slot publish sequence.
static constexpr size_t INVALID_INDEX
无效槽位下标 / Sentinel for "no slot chosen".
ErrorCode Acquire(size_t &index)
认领一个空闲槽(空闲 → 写入中) / Claim one free slot (free -> writing).
SlotPoolBase(size_t slot_size, size_t slot_align, size_t slot_count)
构造槽池内核 / Construct the slot-pool core.
@ SLOT_READING
读取中,已被消费者持有 / Reading, owned by a consumer
@ SLOT_READY
就绪,等待 Take / Ready, waiting for Take
@ SLOT_FREE
空闲,可被 Acquire 认领 / Free, claimable by Acquire
@ SLOT_WRITING
写入中,已被生产者持有 / Writing, owned by a producer
void Release(size_t index)
释放自己持有的槽(写入中或读取中 → 空闲) / Release an owned slot (writing or reading -> free).
void Publish(size_t index)
发布已写好的槽(写入中 → 就绪),并取得发布序号 / Publish a fully written slot (writing -> ready) and take a publish sequen...
LibXR 命名空间 / LibXR namespace.
ErrorCode
定义错误码枚举 / Defines an enumeration for error codes
@ OK
操作成功 / Operation successful
constexpr size_t CONCURRENCY_ALIGNMENT
并发结构对齐粒度(用于降低多核伪共享) / Alignment policy used by concurrency-oriented structures
constexpr auto max(LeftType a, RightType b) -> std::common_type_t< LeftType, RightType >
计算两个数的最大值 / Computes the maximum of two numbers
定长槽池:任务与中断共享的小容量消息槽 / Fixed-size slot pool for small task/interrupt shared message slots.