libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
LibXR::WritePort Class Reference

基于 SPSC 字节队列的写端口 / Write endpoint backed by an SPSC byte queue. More...

#include <write_port.hpp>

Classes

class  Stream
 合并多次写入的流接口 / Stream interface for batched writes. More...
 
class  WriteQueue
 已提交队头的出队接口 / Consumer interface for one released front. More...
 

Public Member Functions

 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.
 
size_t Size () const
 获取字节队列当前数据量 / Get current byte queue occupancy.
 
size_t Capacity () const
 获取字节队列总容量 / Get total byte queue capacity.
 
bool Writable () const
 检查端口是否支持写入 / Check whether the port supports writes.
 
WritePort & operator= (WriteFun fun)
 绑定写入进度通知函数 / Bind the write progress notification function.
 
WriteQueue GetWriteQueue (bool in_isr=false)
 获取已提交队头的出队接口 / Obtain a consumer interface for the released front.
 
ErrorCode operator() (ConstRawData data, WriteOperation &op, bool in_isr=false)
 提交写请求 / Submit a write request.
 

Friends

class Pipe
 

Detailed Description

基于 SPSC 字节队列的写端口 / Write endpoint backed by an SPSC byte queue.

普通后端按请求顺序取走数据,整个请求被后端接收后完成;Pipe 共用读写字节队列, 写入队列后即可完成。调用者的数据会复制到队列,完成通知对象仍由调用者持有。 Queued backends consume requests in FIFO order and complete each after accepting all its bytes. Pipe shares the byte queue with its reader and completes writes on admission. Payload is copied; completion targets remain caller-owned.

Precondition
后端负责串行化出队及完成通知。同一端口的 BLOCK 与非 BLOCK 操作不得重叠或 嵌套;同时只能有一个尚未返回的 BLOCK 调用。超时请求退出队列前仍属于 BLOCK。 The backend serializes consumption and completion. BLOCK and non-BLOCK work on the same port must not overlap or nest. Only one BLOCK caller may be live; a timed-out queued request remains BLOCK work until it retires.
Note
端口、所属后端和通知对象须在所有相关调用、回调及持有写入权的 Stream 结束前保持有效。完成表示后端已接收数据,具体接收位置由后端约定。 The port, backend, and notification targets must outlive related calls, callbacks, and owning Streams. Completion means acceptance at the storage boundary defined by the backend.

Definition at line 39 of file write_port.hpp.

Constructor & Destructor Documentation

◆ WritePort()

WritePort::WritePort ( size_t queue_size = 3U,
size_t buffer_size = 128U )

构造写端口并分配队列 / Construct a write port and allocate its queues.

Parameters
queue_size请求队列容量;正数采用后端逐请求完成模式,零采用 Pipe 使用的 入队即完成模式,不分配请求队列。最大值为 2^29 - 1。 Request capacity; positive selects queued completion, zero selects the admission completion used by Pipe, with no metadata. Maximum: 2^29 - 1.
buffer_size字节队列容量;零表示不分配字节存储。 Byte queue capacity; zero allocates no payload storage.
Note
使用前须绑定 WriteFun。模式由请求队列是否存在决定,构造后保持不变。 Bind WriteFun before use. Metadata presence fixes the mode at construction.

Definition at line 8 of file write_port.cpp.

9 : queue_requests_(queue_size != 0U
10 ? new (std::align_val_t(LibXR::CONCURRENCY_ALIGNMENT))
11 SPSCQueue<Request>(ValidateQueueSize(queue_size))
12 : nullptr),
13 queue_data_(buffer_size != 0U ? new (std::align_val_t(LibXR::CONCURRENCY_ALIGNMENT))
14 SPSCQueue<uint8_t>(buffer_size)
15 : nullptr)
16{
17}
单生产者单消费者无锁队列 / Single-producer single-consumer lock-free queue.
constexpr size_t CONCURRENCY_ALIGNMENT
并发结构对齐粒度(用于降低多核伪共享) / Alignment policy used by concurrency-oriented structures
Definition libxr_def.hpp:61

Member Function Documentation

◆ Capacity()

size_t WritePort::Capacity ( ) const
nodiscard

获取字节队列总容量 / Get total byte queue capacity.

Returns
总字节数,无队列时为零 / Capacity in bytes, or zero without a queue.

Definition at line 29 of file write_port.cpp.

30{
31 return queue_data_ == nullptr ? 0U : queue_data_->MaxSize();
32}
size_t MaxSize() const
获取队列最大容量 / Get the maximum queue capacity

◆ EmptySize()

size_t WritePort::EmptySize ( ) const
nodiscard

获取字节队列当前空闲空间 / Get current byte queue free space.

Returns
空闲字节数,无字节队列时为零;不反映请求槽或生产者是否可用。 Free bytes, or zero without a queue; no metadata or phase guarantee.
Note
查询不预留空间,并发进展可使结果变化。 Reserves no space; concurrent progress may change the value.

Definition at line 19 of file write_port.cpp.

20{
21 return queue_data_ == nullptr ? 0U : queue_data_->EmptySize();
22}
size_t EmptySize() const
获取剩余空槽数 / Get the current free-slot count

◆ GetWriteQueue()

WritePort::WriteQueue WritePort::GetWriteQueue ( bool in_isr = false)
nodiscard

获取已提交队头的出队接口 / Obtain a consumer interface for the released front.

Parameters
in_isr当前是否在中断中;本次析构结算和完成通知使用该上下文。 ISR context, captured for settlement and completion notifications.
Returns
当前队头剩余部分的接口,无已发布请求时返回空接口。 Interface for the current front remainder, or empty when none is released.
Precondition
仅供具有请求队列的后端使用,由唯一消费者串行调用;Pipe 不使用此接口。 Requires a metadata queue and a serialized sole consumer; not used by Pipe.
Note
后端可在生产者准备新请求时继续消费较早的已发布请求。 Older released requests remain consumable while a producer prepares a new one.

Definition at line 119 of file write_port.cpp.

120{
121 ASSERT_FROM_CALLBACK(queue_requests_ != nullptr, in_isr);
122
123 if (GetReleasedCount(state_.load(std::memory_order_acquire)) == 0U)
124 {
125 DEV_ASSERT_FROM_CALLBACK(front_remaining_ == 0U, in_isr);
126 return WriteQueue(*this, in_isr, 0U);
127 }
128
129 Request request{};
130 [[maybe_unused]] const auto peek_result = queue_requests_->Peek(request);
131 DEV_ASSERT_FROM_CALLBACK(peek_result == ErrorCode::OK, in_isr);
132 if (front_remaining_ == 0U)
133 {
134 DEV_ASSERT_FROM_CALLBACK(request.size != 0U, in_isr);
135 front_remaining_ = request.size;
136 }
137 else
138 {
139 DEV_ASSERT_FROM_CALLBACK(front_remaining_ <= request.size, in_isr);
140 }
141
142 return WriteQueue(*this, in_isr, front_remaining_);
143}
ErrorCode Peek(Data &item)
查看一个队头 payload 但不出队 / Peek one front payload without dequeuing it.
@ OK
操作成功 / Operation successful

◆ operator()()

ErrorCode WritePort::operator() ( ConstRawData data,
WriteOperation & op,
bool in_isr = false )

提交写请求 / Submit a write request.

Parameters
data数据源和字节数;正长度地址须有效,接纳时在本次调用内完整复制到队列, 返回后即可复用源缓冲区。 零长度允许空地址,在能力检查后立即成功,不通知后端,非 BLOCK 同步完成。 Source and byte count; admitted data is fully copied during this call. A positive size requires a valid address; the source is reusable after return. Zero size permits null and succeeds after the capability check, without backend notification, completing non-BLOCK inline.
op完成通知描述符;回调和轮询状态须保持到完成,BLOCK 信号量须保持到返回。 Completion descriptor; keep callback and polling targets through completion and the BLOCK semaphore through return.
in_isr当前调用是否位于中断 / Whether this call is in an ISR.
Returns
非 BLOCK 的 OK 表示请求已接纳;普通后端的 BLOCK 返回完成结果或 TIMEOUT。 Pipe 入队后返回 OK,无需等待读端消费。无写入能力返回 NOT_SUPPORT, 生产者状态冲突返回 BUSY,字节空间或请求槽不足返回 FULL,不部分接纳。 Non-BLOCK OK means admission; queued BLOCK returns completion or TIMEOUT. Pipe returns OK on admission without waiting for reads. NOT_SUPPORT when unavailable, BUSY for a phase conflict, FULL for insufficient byte space or request slots, without partial admission.
Precondition
BLOCK 仅在线程中调用,每个信号量只服务一个活动 BLOCK 调用;遵守类说明中的 BLOCK 与非 BLOCK 互斥约定。通知对象和端口须在仍可能访问它们的调用结束前有效。 BLOCK is task-only with a dedicated semaphore for one live call. Follow the class-level BLOCK/non-BLOCK exclusion and keep targets and the port alive through calls that may still access them.
Note
BLOCK 不等待普通队列空间。若旧 BLOCK 已超时且本次长度不超过 Capacity(), 可先等旧请求退出,再提交并等待本次完成;两次等待分别使用原 timeout。 第一段等待超时不提交本次数据;第二段超时不撤销已排队数据,后端仍可发送。 BLOCK does not wait for ordinary queue space. A later request no larger than Capacity() may first await a timed-out BLOCK's retirement, then submit and await its own completion; each wait uses the original timeout. A retirement timeout submits no new data; a completion timeout leaves queued data intact.
完成方已认领本次 BLOCK 时,超时方须等信号量交接并返回实际完成结果; 因此调用可能超过指定时间。超时返回后,旧请求不会再访问该调用的信号量。 If completion is already claimed, the caller waits for the semaphore handoff and returns the actual result, possibly exceeding the timeout. A detached request no longer accesses the timed-out caller's semaphore.
非 BLOCK 回调在实际完成的上下文执行,可能发生在本次调用内;可提交后续 非 BLOCK 写入,其结果仍受生产者占用与容量限制。轮询状态以 acquire 读取。 拒绝接纳的请求不发送完成通知;零长度和 Pipe 的 BLOCK 不等待或释放信号量。 Non-BLOCK callbacks run in the completion context, possibly inline, and may submit further non-BLOCK writes subject to admission and capacity. Load polling status with acquire ordering. Rejected requests emit no completion; zero-size and Pipe BLOCK writes neither wait nor post a semaphore.
回调不可阻塞等待依赖当前调用返回才能推进的操作。 Callbacks must not block on progress requiring the current call to return.

Definition at line 449 of file write_port.cpp.

450{
451 if (!Writable())
452 {
454 }
455
456 if (data.size_ == 0U)
457 {
458 if (op.type != WriteOperation::OperationType::BLOCK)
459 {
460 op.UpdateStatus(in_isr, ErrorCode::OK);
461 }
462 return ErrorCode::OK;
463 }
464
465 if (!TryClaimProducer())
466 {
467 if (op.type == WriteOperation::OperationType::BLOCK &&
468 LoadPhase() == Phase::BLOCK_DETACHED && data.size_ <= Capacity())
469 {
470 const ErrorCode retirement = WaitForRetirement(op);
471 if (retirement != ErrorCode::OK)
472 {
473 return retirement;
474 }
475 }
476 else
477 {
478 return ErrorCode::BUSY;
479 }
480 }
481
482 ASSERT_FROM_CALLBACK(data.addr_ != nullptr, in_isr);
483
484 if (queue_data_->EmptySize() < data.size_ ||
485 (!IsAdmissionMode() && queue_requests_->EmptySize() < 1U))
486 {
487 ReleaseProducer(Phase::IDLE, in_isr);
488 return ErrorCode::FULL;
489 }
490
491 [[maybe_unused]] const auto push_batch_result =
492 queue_data_->PushBatch(reinterpret_cast<const uint8_t*>(data.addr_), data.size_);
493 DEV_ASSERT_FROM_CALLBACK(push_batch_result == ErrorCode::OK, in_isr);
494
495 return IsAdmissionMode() ? CommitAdmission(data.size_, op, in_isr)
496 : CommitQueued(data.size_, op, in_isr);
497}
size_t size_
数据字节数 / Data size in bytes
const void * addr_
数据起始地址 / Data start address
void UpdateStatus(bool in_isr, Status &&status)
按通知方式报告完成结果 / Report completion using the selected mode.
OperationType type
当前通知方式 / Current notification mode.
ErrorCode PushBatch(const Data *data, size_t size)
批量推入多个 payload / Push multiple payloads into the queue.
bool Writable() const
检查端口是否支持写入 / Check whether the port supports writes.
size_t Capacity() const
获取字节队列总容量 / Get total byte queue capacity.
ErrorCode
定义错误码枚举 / Defines an enumeration for error codes
@ BUSY
忙碌 / Busy
@ NOT_SUPPORT
不支持 / Not supported
@ FULL
已满 / Full

◆ operator=()

WritePort & WritePort::operator= ( WriteFun fun)

绑定写入进度通知函数 / Bind the write progress notification function.

Parameters
fun接收端口和当前中断上下文的通知函数,不返回请求完成结果。 Notification receiving the port and ISR context, without a completion result.
Returns
当前端口 / This port.
Precondition
仅在端口或后端构造时绑定一次,运行前完成;Pipe 由自身构造函数绑定。 Bind once at construction, before use. Pipe binds its own callback.
Note
普通后端通过 GetWriteQueue 消费已提交请求,并负责保留、重新检查进度通知。 Queued backends consume released requests through GetWriteQueue and retain and recheck progress notifications.
Pipe 在持有写入权时通知读端,通知返回后释放写入权,再完成写操作。 Pipe notifies its reader while holding producer access, then releases access before completing the write.

Definition at line 39 of file write_port.cpp.

40{
41 write_fun_ = fun;
42 return *this;
43}

◆ Size()

size_t WritePort::Size ( ) const
nodiscard

获取字节队列当前数据量 / Get current byte queue occupancy.

Returns
队列字节数,包含 Stream 已追加但尚未提交的字节;无队列时为零。 Queued bytes, including uncommitted Stream appends, or zero without a queue.
Note
已交给后端存储的字节不计入此值;并发进展可使结果变化。 Excludes backend-owned bytes; concurrent progress may change the value.

Definition at line 24 of file write_port.cpp.

25{
26 return queue_data_ == nullptr ? 0U : queue_data_->Size();
27}
size_t Size() const
获取当前已用元素数 / Get the current element count

◆ Writable()

bool WritePort::Writable ( ) const
nodiscard

检查端口是否支持写入 / Check whether the port supports writes.

Returns
存在字节队列且已绑定 WriteFun 时为 true,不保证下一次写入可接纳。 True with a byte queue and bound WriteFun; does not guarantee admission.

Definition at line 34 of file write_port.cpp.

35{
36 return queue_data_ != nullptr && write_fun_ != nullptr;
37}

Friends And Related Symbol Documentation

◆ Pipe

friend class Pipe
friend

Definition at line 131 of file write_port.hpp.


The documentation for this class was generated from the following files: