libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
libxr_rw.cpp
1#include "libxr_rw.hpp"
2
3#include "libxr_def.hpp"
4#include "mutex.hpp"
5
6using namespace LibXR;
7
10
11ReadPort::ReadPort(size_t buffer_size)
12 : queue_data_(buffer_size > 0 ? new (std::align_val_t(LibXR::CACHE_LINE_SIZE))
13 LockFreeQueue<uint8_t>(buffer_size)
14 : nullptr)
15{
16}
17
19{
20 ASSERT(queue_data_ != nullptr);
21 return queue_data_->EmptySize();
22}
23
25{
26 ASSERT(queue_data_ != nullptr);
27 return queue_data_->Size();
28}
29
30bool ReadPort::Readable() { return read_fun_ != nullptr; }
31
33{
34 read_fun_ = fun;
35 return *this;
36}
37
38void ReadPort::Finish(bool in_isr, ErrorCode ans, ReadInfoBlock& info)
39{
40 if (info.op.type == ReadOperation::OperationType::BLOCK)
41 {
42 // Read completion must come from ProcessPendingReads(); drivers are not
43 // allowed to finish a BLOCK read directly.
44 // BLOCK 读完成只能来自 ProcessPendingReads();驱动不能直接 Finish。
46 if (busy_.compare_exchange_strong(expected, BusyState::IDLE,
47 std::memory_order_acq_rel,
48 std::memory_order_acquire))
49 {
50 return;
51 }
52
53 ASSERT(expected == BusyState::BLOCK_CLAIMED);
54 if (expected == BusyState::BLOCK_CLAIMED)
55 {
56 block_result_ = ans;
57 info.op.data.sem_info.sem->PostFromCallback(in_isr);
58 }
59 return;
60 }
61
62 busy_.store(BusyState::IDLE, std::memory_order_release);
63 info.op.UpdateStatus(in_isr, ans);
64}
65
67
69{
70 if (Readable())
71 {
72 BusyState is_busy = busy_.load(std::memory_order_acquire);
73
74 if (is_busy != BusyState::IDLE && is_busy != BusyState::EVENT)
75 {
76 return ErrorCode::BUSY;
77 }
78
79 while (true)
80 {
81 busy_.store(BusyState::IDLE, std::memory_order_release);
82
83 auto readable_size = queue_data_->Size();
84
85 if (readable_size >= data.size_ && readable_size != 0)
86 {
87 if (data.size_ > 0)
88 {
89 auto ans =
90 queue_data_->PopBatch(reinterpret_cast<uint8_t*>(data.addr_), data.size_);
91 ASSERT(ans == ErrorCode::OK);
92 }
93
94 OnRxDequeue(in_isr);
95
96 if (op.type != ReadOperation::OperationType::BLOCK)
97 {
98 op.UpdateStatus(in_isr, ErrorCode::OK);
99 }
100 return ErrorCode::OK;
101 }
102
103 info_ = ReadInfoBlock{data, op};
104
105 op.MarkAsRunning();
106
107 auto ans = read_fun_(*this, in_isr);
108
109 if (ans == ErrorCode::PENDING)
110 {
111 BusyState expected = BusyState::IDLE;
112 if (busy_.compare_exchange_weak(expected, BusyState::PENDING,
113 std::memory_order_acq_rel,
114 std::memory_order_acquire))
115 {
116 break;
117 }
118 else
119 {
120 continue;
121 }
122 }
123 else
124 {
125 if (op.type == ReadOperation::OperationType::BLOCK)
126 {
127 return ans;
128 }
129 op.UpdateStatus(in_isr, ans);
130 return ErrorCode::OK;
131 }
132 }
133
134 if (op.type == ReadOperation::OperationType::BLOCK)
135 {
136 ASSERT(!in_isr);
137 auto wait_ans = op.data.sem_info.sem->Wait(op.data.sem_info.timeout);
138 if (wait_ans == ErrorCode::OK)
139 {
140 // BLOCK_CLAIMED is always released by the waiter itself.
141 // BLOCK_CLAIMED 始终由 waiter 自己释放。
142#ifdef LIBXR_DEBUG_BUILD
143 auto state = busy_.load(std::memory_order_acquire);
144 ASSERT(state == BusyState::BLOCK_CLAIMED);
145#endif
146 busy_.store(BusyState::IDLE, std::memory_order_release);
147 return block_result_;
148 }
149
150 // Timeout won before completion claimed the waiter.
151 // 超时先赢,完成侧还没 claim 当前 waiter。
152 BusyState expected = BusyState::PENDING;
153 if (busy_.compare_exchange_strong(expected, BusyState::IDLE,
154 std::memory_order_acq_rel,
155 std::memory_order_acquire))
156 {
157 return ErrorCode::TIMEOUT;
158 }
159
160 if (expected != BusyState::BLOCK_CLAIMED)
161 {
162 // A detached late completion may already have cleared BLOCK_DETACHED
163 // back to IDLE before this waiter wakes from timeout.
164 // 分离后的迟到完成可能会在当前 waiter 超时醒来前,先把
165 // BLOCK_DETACHED 清回 IDLE。
166 ASSERT(expected == BusyState::BLOCK_DETACHED || expected == BusyState::IDLE);
167 if (expected == BusyState::BLOCK_DETACHED)
168 {
169 busy_.store(BusyState::IDLE, std::memory_order_release);
170 }
171 return ErrorCode::TIMEOUT;
172 }
173
174 // Timeout lost after completion had already claimed the waiter.
175 // 超时发生得太晚,完成侧已经 claim 了当前 waiter。
176 auto finish_wait_ans = op.data.sem_info.sem->Wait(UINT32_MAX);
177 UNUSED(finish_wait_ans);
178 ASSERT(finish_wait_ans == ErrorCode::OK);
179 busy_.store(BusyState::IDLE, std::memory_order_release);
180 return block_result_;
181 }
182 else
183 {
184 return ErrorCode::OK;
185 }
186 }
187 else
188 {
190 }
191}
192
194{
195 ASSERT(queue_data_ != nullptr);
196
197 auto is_busy = busy_.load(std::memory_order_relaxed);
198
199 if (is_busy == BusyState::PENDING)
200 {
201 auto size = queue_data_->Size();
202 if (size > 0 && size >= info_.data.size_)
203 {
204 if (info_.op.type == ReadOperation::OperationType::BLOCK)
205 {
206 // Read BLOCK completion is claimed here before copying data.
207 // BLOCK 读完成在这里先 claim,再拷数据。
208 BusyState expected = BusyState::PENDING;
209 if (!busy_.compare_exchange_strong(expected, BusyState::BLOCK_CLAIMED,
210 std::memory_order_acq_rel,
211 std::memory_order_acquire))
212 {
213 return;
214 }
215 }
216
217 if (info_.data.size_ > 0)
218 {
219 auto ans = queue_data_->PopBatch(reinterpret_cast<uint8_t*>(info_.data.addr_),
220 info_.data.size_);
221 UNUSED(ans);
222 ASSERT(ans == ErrorCode::OK);
223 }
224
225 Finish(in_isr, ErrorCode::OK, info_);
226 OnRxDequeue(in_isr);
227 }
228 }
229 else if (is_busy == BusyState::IDLE)
230 {
231 busy_.store(BusyState::EVENT, std::memory_order_release);
232 }
233}
234
236{
237 ASSERT(queue_data_ != nullptr);
238 queue_data_->Reset();
239
240 auto state = busy_.load(std::memory_order_acquire);
241 if (state == BusyState::PENDING && info_.op.type == ReadOperation::OperationType::BLOCK)
242 {
243 // Reset detaches the BLOCK waiter instead of reopening the port directly.
244 // Reset 先分离 BLOCK waiter,不直接重开端口。
245 BusyState expected = BusyState::PENDING;
246 if (busy_.compare_exchange_strong(expected, BusyState::BLOCK_DETACHED,
247 std::memory_order_acq_rel,
248 std::memory_order_acquire))
249 {
250 return;
251 }
252
253 state = busy_.load(std::memory_order_acquire);
254 }
255
257 {
258 return;
259 }
260
262 busy_.store(BusyState::IDLE, std::memory_order_release);
263}
264
265WritePort::WritePort(size_t queue_size, size_t buffer_size)
266 : queue_info_(new (std::align_val_t(LibXR::CACHE_LINE_SIZE))
267 LockFreeQueue<WriteInfoBlock>(queue_size)),
268 queue_data_(buffer_size > 0 ? new (std::align_val_t(LibXR::CACHE_LINE_SIZE))
269 LockFreeQueue<uint8_t>(buffer_size)
270 : nullptr)
271{
272}
273
275{
276 ASSERT(queue_data_ != nullptr);
277 return queue_data_->EmptySize();
278}
279
281{
282 ASSERT(queue_data_ != nullptr);
283 return queue_data_->Size();
284}
285
286bool WritePort::Writable() { return write_fun_ != nullptr; }
287
289{
290 write_fun_ = fun;
291 return *this;
292}
293
294void WritePort::Finish(bool in_isr, ErrorCode ans, WriteInfoBlock& info)
295{
296 if (info.op.type == WriteOperation::OperationType::BLOCK)
297 {
298 block_result_ = ans;
299
300 // Write completion claims BLOCK_WAITING and hands the wakeup to the waiter.
301 // 写完成从 BLOCK_WAITING claim 当前 waiter,并把唤醒交给它。
303 if (busy_.compare_exchange_strong(expected, BusyState::BLOCK_CLAIMED,
304 std::memory_order_acq_rel,
305 std::memory_order_acquire))
306 {
307 info.op.data.sem_info.sem->PostFromCallback(in_isr);
308 return;
309 }
310
311 ASSERT(expected == BusyState::BLOCK_DETACHED);
312 if (expected == BusyState::BLOCK_DETACHED)
313 {
314 expected = BusyState::BLOCK_DETACHED;
315 (void)busy_.compare_exchange_strong(expected, BusyState::IDLE,
316 std::memory_order_acq_rel,
317 std::memory_order_acquire);
318 }
319 return;
320 }
321
322 info.op.UpdateStatus(in_isr, ans);
323}
324
326
328{
329 if (Writable())
330 {
331 if (data.size_ == 0)
332 {
333 if (op.type != WriteOperation::OperationType::BLOCK)
334 {
335 op.UpdateStatus(in_isr, ErrorCode::OK);
336 }
337 return ErrorCode::OK;
338 }
339
340 BusyState expected = BusyState::IDLE;
341 if (!busy_.compare_exchange_strong(expected, BusyState::LOCKED,
342 std::memory_order_acq_rel,
343 std::memory_order_acquire))
344 {
345 return ErrorCode::BUSY;
346 }
347
348 return CommitWrite(data, op, false, in_isr);
349 }
350 else
351 {
353 }
354}
355
357 bool in_isr)
358{
359 if (!meta_pushed && queue_info_->EmptySize() < 1)
360 {
361 busy_.store(BusyState::IDLE, std::memory_order_release);
362 return ErrorCode::FULL;
363 }
364
366 if (!meta_pushed)
367 {
368 if (queue_data_->EmptySize() < data.size_)
369 {
370 busy_.store(BusyState::IDLE, std::memory_order_release);
371 return ErrorCode::FULL;
372 }
373
374 ans =
375 queue_data_->PushBatch(reinterpret_cast<const uint8_t*>(data.addr_), data.size_);
376 UNUSED(ans);
377 ASSERT(ans == ErrorCode::OK);
378
379 WriteInfoBlock info{data, op};
380 ans = queue_info_->Push(info);
381
382 ASSERT(ans == ErrorCode::OK);
383 }
384
385 op.MarkAsRunning();
386
387 if (op.type == WriteOperation::OperationType::BLOCK)
388 {
389 // BLOCK waiter must be armed before write_fun_() runs.
390 // 必须先挂起 BLOCK waiter,再调用 write_fun_()。
391 busy_.store(BusyState::BLOCK_WAITING, std::memory_order_release);
392 }
393
394 ans = write_fun_(*this, in_isr);
395
396 if (ans != ErrorCode::PENDING)
397 {
398 if (op.type == WriteOperation::OperationType::BLOCK)
399 {
400 busy_.store(BusyState::IDLE, std::memory_order_release);
401 return ans;
402 }
403
404 if (!meta_pushed)
405 {
406 busy_.store(BusyState::IDLE, std::memory_order_release);
407 }
408
409 if (op.type != WriteOperation::OperationType::BLOCK)
410 {
411 op.UpdateStatus(in_isr, ans);
412 }
413 return ErrorCode::OK;
414 }
415
416 if (op.type == WriteOperation::OperationType::BLOCK)
417 {
418 ASSERT(!in_isr);
419 auto wait_ans = op.data.sem_info.sem->Wait(op.data.sem_info.timeout);
420 if (wait_ans == ErrorCode::OK)
421 {
422 // BLOCK_CLAIMED is always released by the waiter itself.
423 // BLOCK_CLAIMED 始终由 waiter 自己释放。
424#ifdef LIBXR_DEBUG_BUILD
425 auto state = busy_.load(std::memory_order_acquire);
426 ASSERT(state == BusyState::BLOCK_CLAIMED);
427#endif
428 busy_.store(BusyState::IDLE, std::memory_order_release);
429 return block_result_;
430 }
431
432 // Timeout won before completion claimed the waiter.
433 // 超时先赢,完成侧还没 claim 当前 waiter。
435 if (busy_.compare_exchange_strong(expected, BusyState::BLOCK_DETACHED,
436 std::memory_order_acq_rel,
437 std::memory_order_acquire))
438 {
439 return ErrorCode::TIMEOUT;
440 }
441
442 if (expected != BusyState::BLOCK_CLAIMED)
443 {
444 ASSERT(expected == BusyState::BLOCK_DETACHED);
445 busy_.store(BusyState::IDLE, std::memory_order_release);
446 return ErrorCode::TIMEOUT;
447 }
448
449 // Timeout lost after completion had already claimed the waiter.
450 // 超时发生得太晚,完成侧已经 claim 了当前 waiter。
451 auto finish_wait_ans = op.data.sem_info.sem->Wait(UINT32_MAX);
452 UNUSED(finish_wait_ans);
453 ASSERT(finish_wait_ans == ErrorCode::OK);
454 busy_.store(BusyState::IDLE, std::memory_order_release);
455
456 return block_result_;
457 }
458
459 if (!meta_pushed)
460 {
461 busy_.store(BusyState::IDLE, std::memory_order_release);
462 }
463
464 return ErrorCode::OK;
465}
466
468{
469 ASSERT(queue_data_ != nullptr);
470 queue_data_->Reset();
471 queue_info_->Reset();
472
473 auto state = busy_.load(std::memory_order_acquire);
474 if (state == BusyState::BLOCK_WAITING)
475 {
476 // Reset detaches the BLOCK waiter instead of reopening the port directly.
477 // Reset 先分离 BLOCK waiter,不直接重开端口。
479 if (busy_.compare_exchange_strong(expected, BusyState::BLOCK_DETACHED,
480 std::memory_order_acq_rel,
481 std::memory_order_acquire))
482 {
483 return;
484 }
485
486 state = busy_.load(std::memory_order_acquire);
487 }
488
490 {
491 return;
492 }
493
495 busy_.store(BusyState::IDLE, std::memory_order_release);
496}
497
499 : port_(port), op_(op)
500{
501 BusyState expected = BusyState::IDLE;
502 if (!port_->busy_.compare_exchange_strong(expected, BusyState::LOCKED,
503 std::memory_order_acq_rel,
504 std::memory_order_acquire))
505 {
506 return;
507 }
508
509 if (port_->queue_info_->EmptySize() < 1)
510 {
511 port_->busy_.store(BusyState::IDLE, std::memory_order_release);
512 return;
513 }
514
515 locked_ = true;
516 cap_ = port_->queue_data_->EmptySize();
517}
518
520{
521 if (locked_ && size_ > 0)
522 {
523 auto ans =
524 port_->queue_info_->Push(WriteInfoBlock{ConstRawData{nullptr, size_}, op_});
525 ASSERT(ans == ErrorCode::OK);
526 port_->CommitWrite({nullptr, size_}, op_, true);
527 if (op_.type == WriteOperation::OperationType::BLOCK)
528 {
529 // WritePort now owns the BLOCK wait/finish state machine.
530 locked_ = false;
531 }
532 }
533
534 if (locked_)
535 {
536 port_->busy_.store(BusyState::IDLE, std::memory_order_release);
537 }
538}
539
541{
542 if (!locked_)
543 {
544 BusyState expected = BusyState::IDLE;
545 if (!port_->busy_.compare_exchange_strong(expected, BusyState::LOCKED,
546 std::memory_order_acq_rel,
547 std::memory_order_acquire))
548 {
549 return *this;
550 }
551
552 if (port_->queue_info_->EmptySize() < 1)
553 {
554 port_->busy_.store(BusyState::IDLE, std::memory_order_release);
555 return *this;
556 }
557
558 locked_ = true;
559 cap_ = port_->queue_data_->EmptySize();
560 }
561 if (size_ + data.size_ <= cap_)
562 {
563 auto ans = port_->queue_data_->PushBatch(reinterpret_cast<const uint8_t*>(data.addr_),
564 data.size_);
565 ASSERT(ans == ErrorCode::OK);
566 size_ += data.size_;
567 }
568
569 return *this;
570}
571
573{
574 auto ans = ErrorCode::OK;
575
576 if (locked_ && size_ > 0)
577 {
578 ans = port_->queue_info_->Push(WriteInfoBlock{ConstRawData{nullptr, size_}, op_});
579 ASSERT(ans == ErrorCode::OK);
580 ans = port_->CommitWrite({nullptr, size_}, op_, true);
581 if (op_.type == WriteOperation::OperationType::BLOCK)
582 {
583 // WritePort will release busy_ after the BLOCK handoff completes.
584 size_ = 0;
585 locked_ = false;
586 return ans;
587 }
588
589 ASSERT(ans == ErrorCode::OK);
590 size_ = 0;
591 }
592
593 if (locked_)
594 {
595 locked_ = false;
596 port_->busy_.store(BusyState::IDLE, std::memory_order_release);
597 }
598
599 return ans;
600}
601
602// NOLINTNEXTLINE
603int STDIO::Printf(const char* fmt, ...)
604{
605#if LIBXR_PRINTF_BUFFER_SIZE > 0
607 {
608 return -1;
609 }
610
611 if (!write_mutex_)
612 {
613 write_mutex_ = new LibXR::Mutex();
614 }
615
616 LibXR::Mutex::LockGuard lock_guard(*write_mutex_);
617
618 va_list args;
619 va_start(args, fmt);
620 int len = vsnprintf(STDIO::printf_buff_, LIBXR_PRINTF_BUFFER_SIZE, fmt, args);
621 va_end(args);
622
623 // Check result and limit length
624 if (len < 0)
625 {
626 return -1;
627 }
628 if (static_cast<size_t>(len) >= LIBXR_PRINTF_BUFFER_SIZE)
629 {
630 len = LIBXR_PRINTF_BUFFER_SIZE - 1;
631 }
632
633 ConstRawData data = {reinterpret_cast<const uint8_t*>(STDIO::printf_buff_),
634 static_cast<size_t>(len)};
635
636 static WriteOperation op; // NOLINT
637 auto ans = ErrorCode::OK;
638 if (write_stream_ == nullptr)
639 {
640 ans = STDIO::write_->operator()(data, op);
641 }
642 else
643 {
644 (*write_stream_) << data;
645 ans = write_stream_->Commit();
646 }
647
648 if (ans == ErrorCode::OK)
649 {
650 return len;
651 }
652 else
653 {
654 return -1;
655 }
656
657#else
658 UNUSED(fmt);
659 return 0;
660#endif
661}
常量原始数据封装类。 A class for encapsulating constant raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
const void * addr_
数据存储地址(常量)。 The storage address of the data (constant).
无锁队列实现 / Lock-free queue implementation
void Reset()
重置队列 / Resets the queue
ErrorCode PushBatch(const Data *data, size_t size)
批量推入数据 / Pushes multiple elements into the queue
size_t EmptySize()
计算队列剩余可用空间 / Calculates the remaining available space in the queue
size_t Size() const
获取当前队列中的元素数量 / Returns the number of elements currently in the queue
ErrorCode PopBatch(Data *data, size_t size)
批量弹出数据 / Pops multiple elements from the queue
互斥锁的 RAII 机制封装 (RAII-style mechanism for automatic mutex management).
Definition mutex.hpp:65
互斥锁类,提供线程同步机制 (Mutex class providing thread synchronization mechanisms).
Definition mutex.hpp:18
union LibXR::Operation::@5 data
void UpdateStatus(bool in_isr, Status &&status)
Updates operation status based on type.
Definition libxr_rw.hpp:178
void MarkAsRunning()
标记操作为运行状态。 Marks the operation as running.
Definition libxr_rw.hpp:213
OperationType type
Definition libxr_rw.hpp:237
原始数据封装类。 A class for encapsulating raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
void * addr_
数据存储地址。 The storage address of the data.
ReadPort class for handling read operations.
Definition libxr_rw.hpp:379
bool Readable()
Checks if read operations are supported.
Definition libxr_rw.cpp:30
void Finish(bool in_isr, ErrorCode ans, ReadInfoBlock &info)
更新读取操作的状态。 Updates the status of the read operation.
Definition libxr_rw.cpp:38
ReadPort(size_t buffer_size=128)
Constructs a ReadPort with queue sizes.
Definition libxr_rw.cpp:11
void Reset()
Resets the ReadPort.
Definition libxr_rw.cpp:235
ErrorCode block_result_
Final status for the current BLOCK read.
Definition libxr_rw.hpp:409
@ IDLE
No active waiter and no pending completion. 无等待者、无挂起完成。
size_t EmptySize()
获取队列的剩余可用空间。 Gets the remaining available space in the queue.
Definition libxr_rw.cpp:18
ErrorCode operator()(RawData data, ReadOperation &op, bool in_isr=false)
读取操作符重载,用于执行读取操作。 Overloaded function call operator to perform a read operation.
Definition libxr_rw.cpp:68
void ProcessPendingReads(bool in_isr)
Processes pending reads.
Definition libxr_rw.cpp:193
ReadPort & operator=(ReadFun fun)
赋值运算符重载,用于设置读取函数。 Overloaded assignment operator to set the read function.
Definition libxr_rw.cpp:32
size_t Size()
获取当前队列的已使用大小。 Gets the currently used size of the queue.
Definition libxr_rw.cpp:24
virtual void OnRxDequeue(bool)
RX 数据从软件队列成功出队后的通知。 Notification after bytes are popped from RX data queue.
Definition libxr_rw.hpp:517
void MarkAsRunning(ReadInfoBlock &info)
标记读取操作为运行中。 Marks the read operation as running.
Definition libxr_rw.cpp:66
static int Printf(const char *fmt,...)
Prints a formatted string to the write port (like printf).
Definition libxr_rw.cpp:603
static WritePort * write_
Write port instance. 写入端口。
Definition libxr_rw.hpp:772
void PostFromCallback(bool in_isr)
从中断回调中释放(增加)信号量 Releases (increments) the semaphore from an ISR (Interrupt Service Routine)
ErrorCode Wait(uint32_t timeout=UINT32_MAX)
等待(减少)信号量 Waits (decrements) the semaphore
Definition semaphore.cpp:53
WritePort 的流式写入操作器,支持链式 << 操作和批量提交。
Definition libxr_rw.hpp:585
bool locked_
是否持有写锁 Whether write lock is held
Definition libxr_rw.hpp:629
ErrorCode Commit()
手动提交已写入的数据到队列,并释放当前锁。
Definition libxr_rw.cpp:572
size_t cap_
当前队列容量 Current queue capacity
Definition libxr_rw.hpp:627
LibXR::WritePort * port_
写端口指针 Pointer to the WritePort
Definition libxr_rw.hpp:625
~Stream()
析构时自动提交已累积的数据并释放锁。
Definition libxr_rw.cpp:519
Stream(LibXR::WritePort *port, LibXR::WriteOperation op)
构造流写入对象,并尝试锁定端口。
Definition libxr_rw.cpp:498
Stream & operator<<(const ConstRawData &data)
追加写入数据,支持链式调用。
Definition libxr_rw.cpp:540
WritePort class for handling write operations.
Definition libxr_rw.hpp:538
size_t EmptySize()
获取数据队列的剩余可用空间。 Gets the remaining available space in the data queue.
Definition libxr_rw.cpp:274
size_t Size()
获取当前数据队列的已使用大小。 Gets the used size of the current data queue.
Definition libxr_rw.cpp:280
void Finish(bool in_isr, ErrorCode ans, WriteInfoBlock &info)
更新写入操作的状态。 Updates the status of the write operation.
Definition libxr_rw.cpp:294
ErrorCode block_result_
Final status for the current BLOCK write.
Definition libxr_rw.hpp:571
WritePort(size_t queue_size=3, size_t buffer_size=128)
构造一个新的 WritePort 对象。 Constructs a new WritePort object.
Definition libxr_rw.cpp:265
WritePort & operator=(WriteFun fun)
赋值运算符重载,用于设置写入函数。 Overloaded assignment operator to set the write function.
Definition libxr_rw.cpp:288
@ BLOCK_CLAIMED
Final wakeup belongs to the current waiter. 最终唤醒已归当前等待者所有。
@ LOCKED
Submission path owns queue mutation. 提交路径占有写队列/元数据修改权。
bool Writable()
判断端口是否可写。 Checks whether the port is writable.
Definition libxr_rw.cpp:286
ErrorCode CommitWrite(ConstRawData data, WriteOperation &op, bool pushed=false, bool in_isr=false)
提交写入操作。 Commits a write operation.
Definition libxr_rw.cpp:356
void MarkAsRunning(WriteOperation &op)
标记写入操作为运行中。 Marks the write operation as running.
Definition libxr_rw.cpp:325
void Reset()
Resets the WritePort.
Definition libxr_rw.cpp:467
ErrorCode operator()(ConstRawData data, WriteOperation &op, bool in_isr=false)
执行写入操作。 Performs a write operation.
Definition libxr_rw.cpp:327
LibXR 命名空间
Definition ch32_can.hpp:14
ErrorCode
定义错误码枚举
@ TIMEOUT
超时 | Timeout
@ BUSY
忙碌 | Busy
@ NOT_SUPPORT
不支持 | Not supported
@ FULL
已满 | Full
@ PENDING
等待中 | Pending
@ OK
操作成功 | Operation successful
ErrorCode(* ReadFun)(ReadPort &port, bool in_isr)
Function pointer type for read operations.
Definition libxr_rw.hpp:356
ErrorCode(* WriteFun)(WritePort &port, bool in_isr)
Function pointer type for write operations.
Definition libxr_rw.hpp:352
constexpr size_t CACHE_LINE_SIZE
缓存行大小 / Cache line size
Definition libxr_def.hpp:32
Read information block structure.
Definition libxr_rw.hpp:363
RawData data
Data buffer. 数据缓冲区。
Definition libxr_rw.hpp:364
ReadOperation op
Read operation instance. 读取操作实例。
Definition libxr_rw.hpp:365
WriteOperation op
Write operation instance. 写入操作实例。
Definition libxr_rw.hpp:371