12#include "libxr_cb.hpp"
13#include "libxr_def.hpp"
14#include "libxr_mem.hpp"
15#include "print/print_api.hpp"
16#include "libxr_type.hpp"
17#include "lockfree_queue.hpp"
19#include "semaphore.hpp"
31template <
typename Args>
73 :
data{.sem_info = {&sem, timeout}}, type(OperationType::BLOCK)
99 Operation(Operation&& op) noexcept : data{
nullptr}, type(OperationType::NONE)
101 *
this = std::move(op);
117 case OperationType::CALLBACK:
118 data.callback = op.
data.callback;
120 case OperationType::BLOCK:
121 data.sem_info.sem = op.
data.sem_info.sem;
122 data.sem_info.timeout = op.
data.sem_info.timeout;
124 case OperationType::POLLING:
125 data.status = op.
data.status;
127 case OperationType::NONE:
128 data.callback =
nullptr;
148 case OperationType::CALLBACK:
149 data.callback = op.data.callback;
151 case OperationType::BLOCK:
152 data.sem_info.sem = op.data.sem_info.sem;
153 data.sem_info.timeout = op.data.sem_info.timeout;
155 case OperationType::POLLING:
156 data.status = op.data.status;
158 case OperationType::NONE:
159 data.callback =
nullptr;
172 template <
typename Status>
177 case OperationType::CALLBACK:
178 data.callback->Run(in_isr, std::forward<Status>(status));
180 case OperationType::BLOCK:
184 data.sem_info.sem->PostFromCallback(in_isr);
186 case OperationType::POLLING:
187 *data.status = (status ==
ErrorCode::OK) ? OperationPollingStatus::DONE
188 : OperationPollingStatus::ERROR;
190 case OperationType::NONE:
210 if (type == OperationType::POLLING)
212 *data.status = OperationPollingStatus::RUNNING;
226 OperationPollingStatus* status;
245 enum class State : uint32_t
256 result_ = ErrorCode::OK;
257 state_.store(State::PENDING, std::memory_order_release);
260 void Cancel() { state_.store(State::IDLE, std::memory_order_release); }
264 ASSERT(sem_ !=
nullptr);
265 auto wait_ans = sem_->Wait(timeout);
266 if (wait_ans == ErrorCode::OK)
268#ifdef LIBXR_DEBUG_BUILD
269 ASSERT(state_.load(std::memory_order_acquire) == State::CLAIMED);
271 state_.store(State::IDLE, std::memory_order_release);
275 State expected = State::PENDING;
276 if (state_.compare_exchange_strong(expected, State::DETACHED,
277 std::memory_order_acq_rel,
278 std::memory_order_acquire))
280 return ErrorCode::TIMEOUT;
283 ASSERT(expected == State::CLAIMED || expected == State::DETACHED ||
284 expected == State::IDLE);
285 if (expected == State::DETACHED)
287 state_.store(State::IDLE, std::memory_order_release);
288 return ErrorCode::TIMEOUT;
290 if (expected == State::IDLE)
292 return ErrorCode::TIMEOUT;
295 auto finish_wait_ans = sem_->Wait(UINT32_MAX);
296 UNUSED(finish_wait_ans);
297 ASSERT(finish_wait_ans == ErrorCode::OK);
298 state_.store(State::IDLE, std::memory_order_release);
304 ASSERT(sem_ !=
nullptr);
306 State expected = State::PENDING;
307 if (!state_.compare_exchange_strong(expected, State::CLAIMED,
308 std::memory_order_acq_rel,
309 std::memory_order_acquire))
311 ASSERT(expected == State::DETACHED || expected == State::IDLE);
312 if (expected == State::DETACHED)
314 expected = State::DETACHED;
315 (void)state_.compare_exchange_strong(expected, State::IDLE,
316 std::memory_order_acq_rel,
317 std::memory_order_acquire);
323 sem_->PostFromCallback(in_isr);
329 std::atomic<State> state_{State::IDLE};
422 std::atomic<BusyState> busy_{BusyState::IDLE};
546 void ProcessPendingReads(
bool in_isr);
588 BLOCK_PUBLISHING = 1,
606 std::atomic<BusyState> busy_{BusyState::IDLE};
700 return owns_port_ ? (batch_capacity_ - buffered_size_) : 0;
713 [[nodiscard]]
ErrorCode SubmitBuffered();
723 size_t batch_capacity_ = 0;
724 size_t buffered_size_ = 0;
725 bool owns_port_ =
false;
746 WritePort(
size_t queue_size = 3,
size_t buffer_size = 128);
858 bool in_isr =
false);
901 [[nodiscard]]
ErrorCode Write(std::string_view chunk);
911 size_t retained_size_ = 0;
912 bool saturated_ =
false;
922 template <
typename CompiledFormat,
typename... Args>
934 auto& compiled_call = *
static_cast<CompiledCall*
>(context);
938 return Print::Write(sink, compiled_call.format,
939 std::forward<
decltype(unpacked)>(unpacked)...);
957 CompiledWriteFun write_fun);
969 [[nodiscard]]
static int WriteCompiledSession(
void* context, CompiledWriteFun write_fun);
981 template <
typename Call>
984 if (!BeginWriteSession())
989 return WriteCompiledSession(&call, &Call::Write);
997 template <
typename CompiledFormat,
typename... Args>
998 [[nodiscard]]
static int RunCompiled(
const CompiledFormat& format, Args&&... args)
1001 format, std::forward_as_tuple(std::forward<Args>(args)...)};
1002 return RunCompiledSession(call);
1009 [[nodiscard]]
static bool BeginWriteSession();
1017 size_t retained_size,
1034 return RunCompiled(format, std::forward<Args>(args)...);
1048 constexpr auto format = Print::Printf::Build<Source>();
1049 return RunCompiled(format, std::forward<Args>(args)...);
Shared BLOCK waiter handoff for synchronous driver operations.
通用回调包装,支持动态参数传递 / Generic callback wrapper supporting dynamic argument passing
只读原始数据视图 / Immutable raw data view
无锁队列实现 / Lock-free queue implementation
互斥锁类,提供线程同步机制 (Mutex class providing thread synchronization mechanisms).
Defines an operation with different execution modes.
Operation & operator=(const Operation &op)
Copy assignment operator.
Operation(Semaphore &sem, uint32_t timeout=UINT32_MAX)
Constructs a blocking operation with a semaphore and timeout.
Operation & operator=(Operation &&op) noexcept
Move assignment operator.
Operation(Callback &callback)
Constructs a callback-based operation.
union LibXR::Operation::@5 data
Operation()
Default constructor, initializes with NONE type.
void UpdateStatus(bool in_isr, Status &&status)
Updates operation status based on type.
void MarkAsRunning()
标记操作为运行状态。 Marks the operation as running.
Operation(OperationPollingStatus &status)
Constructs a polling operation.
可写原始数据视图 / Mutable raw data view
ReadPort class for handling read operations.
virtual void OnRxDequeue(bool)
RX 数据从软件队列成功出队后的通知。 Notification after bytes are popped from RX data queue.
WritePort::Stream & stream_
Active stream session receiving retained bytes. 接收保留字节的活动流会话。
size_t RetainedSize() const
返回当前会话最终保留下来的字节数。
STDIO interface for read/write ports.
static int Printf(Args &&... args)
Prints one compile-time printf literal to the active STDIO output.
static int RunCompiledSession(Call &call)
执行一次模板已知的 STDIO 编译格式会话。
ErrorCode(*)(void *context, CompiledSink &sink) CompiledWriteFun
Type-erased bridge for one compiled STDIO call. / 一次编译格式 STDIO 调用的类型擦除桥接函数。
static int Print(Args &&... args)
Prints one compile-time brace literal to the active STDIO output.
static int RunCompiled(const CompiledFormat &format, Args &&... args)
用一份已编译格式和一组运行时参数执行一次完整的 STDIO 写会话。
信号量类,实现线程同步机制 Semaphore class implementing thread synchronization
size_t EmptySize() const
获取当前批次还可追加的剩余字节数。
LibXR::WritePort * port_
写端口指针 Pointer to the WritePort
LibXR::WriteOperation op_
写操作对象 Write operation object
ErrorCode Write(std::string_view text)
追加一个文本片段到当前流批次。
WritePort class for handling write operations.
@ OK
操作成功 | Operation successful
ErrorCode(* ReadFun)(ReadPort &port, bool in_isr)
Function pointer type for read notifications.
ErrorCode(* WriteFun)(WritePort &port, bool in_isr)
Function pointer type for write operations.
Structural literal wrapper used as the NTTP source for printf formats.
Read information block structure.
RawData data
Data buffer. 数据缓冲区。
ReadOperation op
Read operation instance. 读取操作实例。
std::tuple< Args &&... > args
Forwarded runtime arguments. 转发保存的运行时参数。
static ErrorCode Write(void *context, CompiledSink &sink)
将当前模板上下文桥接到编译格式前端写入入口。
const CompiledFormat & format
Compile-time compiled format object. 编译期已编译的格式对象。
ConstRawData data
Data buffer. 数据缓冲区。
WriteOperation op
Write operation instance. 写入操作实例。