libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
slot_pool.hpp
Go to the documentation of this file.
1#pragma once
2
9#include <atomic>
10#include <cstddef>
11#include <cstdint>
12#include <new>
13#include <type_traits>
14
15#include "libxr_def.hpp"
16#include "libxr_mem.hpp"
17
18namespace LibXR
19{
36{
37 public:
47 SlotPoolBase(size_t slot_size, size_t slot_align, size_t slot_count);
52
66 ErrorCode Acquire(size_t& index);
81 void Publish(size_t index);
96 ErrorCode Take(size_t& index);
108 void Release(size_t index);
113 [[nodiscard]] size_t Size() const { return slot_count_; }
114
115 protected:
117 [[nodiscard]] void* SlotPtr(size_t index);
119 [[nodiscard]] const void* SlotPtr(size_t index) const;
120
122 static constexpr size_t INVALID_INDEX = static_cast<size_t>(-1);
123
125 enum SlotState : uint32_t
126 {
130 SLOT_READING = 3
131 };
132
133 const size_t slot_size_;
134 const size_t slot_count_;
135 const size_t slot_stride_;
136 const size_t alloc_align_;
138 std::atomic<uint32_t>* states_;
139 std::atomic<uint32_t>* seqs_;
140 std::byte* slots_;
141
144 alignas(LibXR::CONCURRENCY_ALIGNMENT) std::atomic<uint32_t> publish_seq_;
147 alignas(LibXR::CONCURRENCY_ALIGNMENT) std::atomic<uint32_t> release_count_;
148
149 private:
152 static bool SeqBefore(uint32_t a, uint32_t b)
153 {
154 return static_cast<int32_t>(a - b) < 0;
155 }
156
158 [[nodiscard]] static size_t AlignUp(size_t value, size_t align);
159
161 SlotPoolBase& operator=(const SlotPoolBase&);
163 SlotPoolBase& operator=(SlotPoolBase&&);
164};
165
194template <typename T>
195class SlotPool : public SlotPoolBase
196{
197 public:
205 explicit SlotPool(size_t slot_count) : SlotPoolBase(sizeof(T), alignof(T), slot_count)
206 {
207 }
208
215 T& At(size_t index) { return *static_cast<T*>(SlotPtr(index)); }
217 const T& At(size_t index) const { return *static_cast<const T*>(SlotPtr(index)); }
218
228 ErrorCode Put(const T& value)
229 {
230 static_assert(std::is_trivially_copyable_v<T>,
231 "SlotPool::Put requires a trivially copyable type");
232 size_t index = INVALID_INDEX;
233 const ErrorCode ec = Acquire(index);
234 if (ec != ErrorCode::OK)
235 {
236 return ec;
237 }
238 Memory::FastCopy(SlotPtr(index), &value, sizeof(T));
239 Publish(index);
240 return ErrorCode::OK;
241 }
242
252 ErrorCode Get(T& value)
253 {
254 static_assert(std::is_trivially_copyable_v<T>,
255 "SlotPool::Get requires a trivially copyable type");
256 size_t index = INVALID_INDEX;
257 const ErrorCode ec = Take(index);
258 if (ec != ErrorCode::OK)
259 {
260 return ec;
261 }
262 Memory::FastCopy(&value, SlotPtr(index), sizeof(T));
263 Release(index);
264 return ErrorCode::OK;
265 }
266};
267} // namespace LibXR
static void FastCopy(void *dst, const void *src, size_t size)
快速内存拷贝 / Fast memory copy
槽池的无类型内核:槽状态机、发布序号与扫描逻辑。 Typeless core of the slot pool: slot state machine, publish sequence and sca...
Definition slot_pool.hpp:36
~SlotPoolBase()
析构槽池内核 / Destroy the slot-pool core.
Definition slot_pool.cpp:40
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.
size_t Size() const
获取槽总数 / Get the total number of slots.
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).
Definition slot_pool.cpp:49
SlotPoolBase(size_t slot_size, size_t slot_align, size_t slot_count)
构造槽池内核 / Construct the slot-pool core.
Definition slot_pool.cpp:8
SlotState
槽状态 / Slot state.
@ 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...
Definition slot_pool.cpp:88
面向任务与中断的小容量消息槽池。 Small message slot pool shared between tasks and interrupts.
ErrorCode Get(T &value)
便捷出队:Take + 拷贝 + Release / Convenient dequeue: Take + copy + Release.
ErrorCode Put(const T &value)
便捷入队:Acquire + 拷贝 + Publish / Convenient enqueue: Acquire + copy + Publish.
const T & At(size_t index) const
只读访问自己持有的槽 / Read-only access to an owned slot.
T & At(size_t index)
访问自己持有的槽(写入中或读取中)/ Access an owned slot (writing or reading).
SlotPool(size_t slot_count)
构造槽池 / Construct one slot pool.
LibXR 命名空间 / LibXR namespace.
Definition ch32_can.hpp:14
ErrorCode
定义错误码枚举 / Defines an enumeration for error codes
@ OK
操作成功 / Operation successful
constexpr size_t CONCURRENCY_ALIGNMENT
并发结构对齐粒度(用于降低多核伪共享) / Alignment policy used by concurrency-oriented structures
Definition libxr_def.hpp:61