11#include "operation.hpp"
43 enum class Phase : uint32_t
51 BLOCK_RETIRE_WAITING = 5U,
55 static constexpr uint32_t PHASE_BITS = 3U;
56 static constexpr uint32_t PHASE_MASK = (1U << PHASE_BITS) - 1U;
58 static constexpr uint32_t RELEASED_INCREMENT = 1U << PHASE_BITS;
60 static constexpr uint32_t MAX_RELEASED_REQUESTS = UINT32_MAX >> PHASE_BITS;
62 static_assert(
static_cast<uint32_t
>(Phase::BLOCK_RETIRE_WAITING) <= PHASE_MASK);
71 static_assert(std::is_trivially_copyable_v<Request>);
72 static_assert(std::is_trivially_destructible_v<Request>);
75 static constexpr uint32_t MakeState(Phase phase, uint32_t released)
77 return (released << PHASE_BITS) |
static_cast<uint32_t
>(phase);
81 static Phase GetPhase(uint32_t state) {
return static_cast<Phase
>(state & PHASE_MASK); }
84 static uint32_t GetReleasedCount(uint32_t state) {
return state >> PHASE_BITS; }
87 static uint32_t WithPhase(uint32_t state, Phase phase)
89 return (state & ~PHASE_MASK) |
static_cast<uint32_t
>(phase);
93 static size_t ValidateQueueSize(
size_t queue_size)
95 ASSERT(queue_size <= MAX_RELEASED_REQUESTS);
100 [[nodiscard]]
bool IsAdmissionMode()
const {
return queue_requests_ ==
nullptr; }
102 [[nodiscard]] Phase LoadPhase()
const
104 return GetPhase(state_.load(std::memory_order_acquire));
107 [[nodiscard]]
bool TryClaimProducer();
119 void ReleaseProducer(Phase next,
bool in_isr);
121 void PublishQueuedRequest(Phase next,
bool in_isr);
123 void DecrementReleasedRequest(
bool in_isr);
125 void NotifyBackend(
bool in_isr);
127 void SettleWriteQueue(
size_t accepted,
ErrorCode result,
bool in_isr)
noexcept;
129 void CompleteRequest(Request& request,
ErrorCode result,
bool in_isr);
169 DEV_ASSERT_FROM_CALLBACK(popped_size_ <= front_size_, in_isr_);
170 return front_size_ - popped_size_;
190 void PopAll(uint8_t* destination);
213 template <
typename Writer>
225 [&](
const uint8_t* first,
size_t first_size,
const uint8_t* second,
226 size_t second_size) ->
size_t
228 const size_t accepted = writer(first, first_size, second, second_size);
229 ASSERT_FROM_CALLBACK(accepted <= first_size + second_size, in_isr_);
232 popped_size_ += accepted;
254 ASSERT_FROM_CALLBACK(!action_used_, in_isr_);
259 WriteQueue(
WritePort& port,
bool in_isr,
size_t front_size)
260 : port_(port), in_isr_(in_isr), front_size_(front_size)
266 const size_t front_size_;
268 size_t popped_size_ = 0U;
271 bool action_used_ =
false;
393 return owns_port_ && port_ !=
nullptr && port_->queue_data_ !=
nullptr
400 [[nodiscard]]
ErrorCode SubmitBuffered();
404 void CompleteEmpty();
409 size_t buffered_size_ = 0U;
411 bool owns_port_ =
false;
425 WritePort(
size_t queue_size = 3U,
size_t buffer_size = 128U);
443 [[nodiscard]]
size_t Size()
const;
449 [[nodiscard]]
size_t Capacity()
const;
456 [[nodiscard]]
bool Writable()
const;
547 std::atomic<uint32_t> state_{MakeState(Phase::IDLE, 0U)};
551 size_t front_remaining_ = 0U;
554 Semaphore* admission_waiter_ =
nullptr;
只读原始数据视图 / Immutable raw data view
由读写端口组成的单向管道 / Unidirectional pipe connecting read and write ports.
size_t EmptySize() const
获取剩余空槽数 / Get the current free-slot count
单生产者单消费者无锁队列 / Single-producer single-consumer lock-free queue.
size_t ConsumeWithReader(size_t limit, Reader &&reader)
通过一次双 span 回调消费 payload 前缀 / Consume a payload prefix through one two-span reader callback.
合并多次写入的流接口 / Stream interface for batched writes.
ErrorCode Acquire()
尝试取得端口写入权 / Try to acquire the port's producer access.
ErrorCode Commit()
提交批次并释放写入权 / Submit the batch and release producer access.
size_t EmptySize() const
获取当前批次可追加的空间 / Get current free space for appending.
Stream(WritePort *port, WriteOperation op)
构造流并尝试取得写入权 / Construct a stream and try to acquire the port.
~Stream()
提交剩余批次并结束流 / Submit the remaining batch and destroy the stream.
ErrorCode Write(ConstRawData data)
向当前批次追加数据 / Append data to the current batch.
ErrorCode Write(std::string_view text)
向当前批次追加文本 / Append text to the current batch.
Stream & operator<<(const ConstRawData &data)
尝试追加数据并返回流引用 / Try to append data and return the stream.
已提交队头的出队接口 / Consumer interface for one released front.
void FailFront(ErrorCode reason)
丢弃剩余数据并结束队头 / Discard the remainder and fail the front.
size_t PopWithWriter(size_t limit, Writer &&writer)
通过回调取走队头前缀 / Consume a front prefix through a callback.
void PopAll(uint8_t *destination)
复制并取走队头剩余数据 / Copy and consume the entire front remainder.
~WriteQueue() noexcept
结算出队,使用获取时的上下文 / Settle progress using the captured context.
bool Empty() const
检查本接口是否还有数据 / Check whether this interface has remaining data.
size_t AvailableSize() const
获取当前队头的剩余长度 / Get the current front remainder.
基于 SPSC 字节队列的写端口 / Write endpoint backed by an SPSC byte queue.
WriteQueue GetWriteQueue(bool in_isr=false)
获取已提交队头的出队接口 / Obtain a consumer interface for the released front.
bool Writable() const
检查端口是否支持写入 / Check whether the port supports writes.
size_t Size() const
获取字节队列当前数据量 / Get current byte queue occupancy.
WritePort & operator=(WriteFun fun)
绑定写入进度通知函数 / Bind the write progress notification function.
size_t Capacity() const
获取字节队列总容量 / Get total byte queue capacity.
WritePort(size_t queue_size=3U, size_t buffer_size=128U)
构造写端口并分配队列 / Construct a write port and allocate its queues.
size_t EmptySize() const
获取字节队列当前空闲空间 / Get current byte queue free space.
ErrorCode operator()(ConstRawData data, WriteOperation &op, bool in_isr=false)
提交写请求 / Submit a write request.
LibXR 命名空间 / LibXR namespace.
ErrorCode
定义错误码枚举 / Defines an enumeration for error codes
@ OK
操作成功 / Operation successful
void(* WriteFun)(WritePort &port, bool in_isr)
写入进度通知函数类型 / Write progress notification function type.