File tree Expand file tree Collapse file tree 16 files changed +1113
-2
lines changed
docs/basic_coding/structure
i18n/en/docusaurus-plugin-content-docs/current/basic_coding/structure Expand file tree Collapse file tree 16 files changed +1113
-2
lines changed Original file line number Diff line number Diff line change @@ -6,4 +6,23 @@ sidebar_position: 2
6
6
7
7
# 数据结构
8
8
9
- 本模块汇总了 LibXR 中的数据结构,涵盖队列、栈、链表、红黑树、双缓冲区等,适用于嵌入式系统中的任务调度、数据通信与资源管理。每个数据结构根据用途和平台约束设计,有的具备线程安全性,有的为性能优化采用无锁机制,具体信息请查阅各子页面说明。
9
+ 本模块汇总了 LibXR 中用于任务调度、数据通信、资源管理等场景的通用数据结构,设计充分考虑嵌入式系统中的内存限制、并发访问与平台差异,涵盖如下内容:
10
+
11
+ ## 模块特性
12
+
13
+ - ** 平台独立** :所有接口均采用平台无关的抽象,支持移植。
14
+ - ** 内存可控** :多数结构支持外部缓冲或固定容量,避免运行时分配。
15
+ - ** 线程/中断安全** :部分结构使用互斥锁或无锁算法设计,适配多线程/中断上下文。
16
+ - ** 结构清晰** :每种结构均封装基础节点、模板节点与核心操作接口,易于扩展。
17
+
18
+ ## 快速导航
19
+
20
+ - [ Queue(队列)] ( ./queue.md )
21
+ - [ LockFreeQueue(无锁队列)] ( ./lockfree_queue.md )
22
+ - [ Stack(栈)] ( ./stack.md )
23
+ - [ List(链表)] ( ./list.md )
24
+ - [ LockFreeList(无锁链表)] ( ./lockfree_list.md )
25
+ - [ RBTree(红黑树)] ( ./rbt.md )
26
+ - [ DoubleBuffer(双缓冲区)] ( ./double_buffer.md )
27
+
28
+ 更多使用方式、性能差异与适用场景,请参考各页面的详细说明及设计思想。
Original file line number Diff line number Diff line change
1
+ ---
2
+ id : double_buffer
3
+ title : 双缓冲区
4
+ sidebar_position : 7
5
+ ---
6
+
7
+ # 双缓冲区(DoubleBuffer)
8
+
9
+ ` LibXR::DoubleBuffer ` 是一个嵌入式场景下的双缓冲数据结构,主要用于 DMA、USB 等高速传输中数据的无缝切换与填充控制。支持主动与备用缓冲的数据管理机制,在性能要求高的数据发送任务中尤为适用。
10
+
11
+ ## 核心特性
12
+
13
+ - 将一块连续内存分为两个缓冲区。
14
+ - 支持主动缓冲(active)与备用缓冲(pending)之间切换。
15
+ - 提供对两个缓冲区的直接访问与数据填充接口。
16
+ - 支持手动切换与自动有效性检测。
17
+ - 可查询备用区是否准备好、已填充长度。
18
+
19
+ ## 接口概览
20
+
21
+ ### 构造函数
22
+
23
+ ``` cpp
24
+ explicit DoubleBuffer (const LibXR::RawData& raw_data);
25
+ ```
26
+
27
+ - 接收一段连续内存,并自动划分为两个缓冲区。
28
+
29
+ ### 数据操作接口
30
+
31
+ - `uint8_t* ActiveBuffer()`:获取当前使用的缓冲区。
32
+ - `uint8_t* PendingBuffer()`:获取备用缓冲区。
33
+ - `bool FillActive(const uint8_t* data, size_t len)`:写入当前缓冲区。
34
+ - `bool FillPending(const uint8_t* data, size_t len)`:写入备用缓冲区。
35
+ - `void EnablePending()`:手动标记备用区为有效(与 FillActive 配合使用)。
36
+ - `bool HasPending() const`:是否存在准备切换的缓冲区。
37
+ - `void Switch()`:切换 active/pending 缓冲。
38
+ - `size_t PendingLength() const`:获取备用缓冲中的有效数据长度。
39
+ - `size_t Size() const`:每个缓冲区的容量。
40
+
41
+ ## 使用示例
42
+
43
+ ```cpp
44
+ LibXR::RawData mem{malloc(512), 512};
45
+ LibXR::DoubleBuffer buf(mem);
46
+
47
+ // 第一次写入备用缓冲区
48
+ buf.FillPending(data1, len1);
49
+ if (buf.HasPending()) {
50
+ buf.Switch(); // 切换为新的 active 缓冲
51
+ }
52
+
53
+ // 填充当前 active 区用于初始传输
54
+ buf.FillActive(data2, len2);
55
+ buf.EnablePending(); // 标记当前 active 将作为 pending 切换
56
+ ```
57
+
58
+ ## 注意事项
59
+
60
+ - 填充备用区后需调用 ` Switch() ` 才能激活其数据。
61
+ - 不支持动态分配,内存必须在构造前准备。
62
+ - ` FillPending ` 不可重入,调用前应确认 pending 状态为 false。
63
+ - ` EnablePending() ` 与 ` FillActive() ` 配合实现主动缓存切换。
64
+
65
+ ## 应用场景
66
+
67
+ - USB CDC / Audio 数据发送
68
+ - DMA 数据流优化
69
+ - 双缓存 ping-pong 通信机制
Original file line number Diff line number Diff line change
1
+ ---
2
+ id : list
3
+ title : 链表
4
+ sidebar_position : 4
5
+ ---
6
+
7
+ # 链表(List)
8
+
9
+ ` LibXR::List ` 是一个线程安全的通用链表容器,支持动态添加、删除和遍历节点。每个节点均继承自 ` BaseNode ` ,可以通过模板 ` Node<T> ` 封装任意数据类型。适用于事件回调、资源管理等灵活数据结构需求。
10
+
11
+ ## 核心特性
12
+
13
+ - 所有节点继承自 ` BaseNode ` ,统一结构。
14
+ - 提供 ` Node<T> ` 模板类封装数据。
15
+ - 支持线程安全的添加、删除和遍历。
16
+ - 内部使用循环链表结构,避免空指针问题。
17
+ - 遍历时支持结构大小校验,保障类型安全。
18
+
19
+ ## 类结构
20
+
21
+ - ` BaseNode ` :所有节点基类,记录大小与指针。
22
+ - ` Node<T> ` :模板节点类,封装用户数据。
23
+ - ` List ` :容器本体,提供 Add / Delete / Foreach 接口。
24
+
25
+ ## 接口说明
26
+
27
+ ### 节点类
28
+
29
+ ``` cpp
30
+ class BaseNode {
31
+ BaseNode* next_ ;
32
+ size_t size_ ;
33
+ };
34
+
35
+ template <typename T >
36
+ class Node : public BaseNode {
37
+ T data_ ;
38
+ };
39
+ ```
40
+
41
+ ### 构造与析构
42
+
43
+ - `List()`:初始化循环链表头。
44
+ - `~List()`:销毁链表并清空所有节点指针。
45
+
46
+ ### 插入与删除
47
+
48
+ - `void Add(BaseNode& node)`:将节点加入链表头部。
49
+ - `ErrorCode Delete(BaseNode& node)`:从链表中移除指定节点。
50
+
51
+ ### 查询与遍历
52
+
53
+ - `uint32_t Size()`:获取链表中节点数。
54
+ - `ErrorCode Foreach(Func func)`:遍历所有节点并调用函数。
55
+ - lambda中返回 `ErrorCode::OK` 时继续遍历,返回 `ErrorCode::ERROR` 时中断遍历。
56
+
57
+ ### Foreach 使用示例
58
+
59
+ ```cpp
60
+ LibXR::List list;
61
+ LibXR::List::Node<int> node1(42);
62
+ list.Add(node1);
63
+
64
+ list.Foreach<int>([](int& data) {
65
+ // 访问每个节点数据
66
+ return LibXR::ErrorCode::OK;
67
+ });
68
+ ```
69
+
70
+ ## 注意事项
71
+
72
+ - 节点由用户申请与释放,` List ` 不负责内存管理。
73
+ - 每个节点只能同时存在于一个链表中。
74
+ - ` Foreach ` 支持结构校验,确保类型匹配。
75
+
76
+ ## 典型应用
77
+
78
+ - 动态注册的回调列表
79
+ - 插件或模块管理
80
+ - 系统资源追踪
Original file line number Diff line number Diff line change
1
+ ---
2
+ id : lockfree_list
3
+ title : 无锁链表
4
+ sidebar_position : 5
5
+ ---
6
+
7
+ # LockFreeList(无锁链表)
8
+
9
+ ` LibXR::LockFreeList ` 是一个线程安全的无锁链表容器,基于原子操作实现,适用于高并发场景下的事件注册、回调管理、资源追踪等。
10
+
11
+ ## 核心特性
12
+
13
+ - 使用 C++11 原子操作实现的单向链表。
14
+ - 所有节点继承自 ` BaseNode ` ,具有统一结构与大小标识。
15
+ - 支持任意数据类型节点:通过模板 ` Node<T> ` 封装。
16
+ - 支持无锁添加与安全遍历(不可删除)。
17
+ - 遍历时自动进行结构大小检查,确保类型安全。
18
+ - 不涉及动态内存分配,节点由用户管理。
19
+
20
+ ## 类结构
21
+
22
+ - ` BaseNode ` :抽象节点类型,提供 ` next_ ` 原子指针和 ` size_ ` 成员。
23
+ - ` Node<T> ` :模板节点类,内嵌用户数据成员 ` data_ ` 。
24
+ - ` LockFreeList ` :容器本体,提供 ` Add ` 和 ` Foreach ` 接口。
25
+
26
+ ## 接口说明
27
+
28
+ ### 添加节点
29
+
30
+ ``` cpp
31
+ void Add (BaseNode& node);
32
+ ```
33
+
34
+ - 将新节点插入链表头部(LIFO 顺序),线程安全。
35
+
36
+ ### 遍历节点
37
+
38
+ ```cpp
39
+ template <typename Data, typename Func, SizeLimitMode LimitMode = MORE>
40
+ ErrorCode Foreach(Func func);
41
+ ```
42
+
43
+ - 遍历链表中所有节点,对数据调用回调 ` func(Data&) ` 。
44
+ - 使用 ` SizeLimitMode ` 模式检查节点数据类型。
45
+ - lambda中返回 ` ErrorCode::OK ` 时继续遍历,返回 ` ErrorCode::ERROR ` 时中断遍历。
46
+
47
+ ### 获取大小
48
+
49
+ ``` cpp
50
+ uint32_t Size ();
51
+ ```
52
+
53
+ - 返回链表中当前节点个数。
54
+
55
+ ### 使用示例
56
+
57
+ ``` cpp
58
+ LibXR::LockFreeList list;
59
+ LibXR::LockFreeList::Node<int > node1 (123);
60
+ list.Add(node1);
61
+
62
+ list.Foreach<int >([ ] (int& val) {
63
+ // 访问 val
64
+ return LibXR::ErrorCode::OK;
65
+ });
66
+ ```
67
+
68
+ ## 注意事项
69
+
70
+ - 本链表不支持删除节点,适合“只增不删”的注册场景。
71
+ - 节点生命周期由用户控制,需避免重复添加或早期析构。
72
+ - 遍历过程中不可修改链表结构。
73
+
74
+ ## 典型应用
75
+
76
+ - 中断/任务中注册的异步回调
77
+ - 模块注册与状态追踪
78
+ - 不可变注册表或只增表结构
Original file line number Diff line number Diff line change
1
+ ---
2
+ id : lockfree_queue
3
+ title : 无锁队列
4
+ sidebar_position : 2
5
+ ---
6
+
7
+ # LockFreeQueue(无锁队列)
8
+
9
+ ` LibXR::LockFreeQueue<T> ` 是一个高性能单生产者多消费者(SPMC)无锁队列,适用于实时性要求高、并发访问频繁的嵌入式系统中。
10
+
11
+ ## 类结构与原理
12
+
13
+ - 使用原子变量 ` head_ ` 和 ` tail_ ` 管理队列索引。
14
+ - 所有操作使用 C++11 原子内存序保证线程安全。
15
+ - 环形缓冲结构支持批量读写,避免频繁中断。
16
+ - 多个消费者可以并发 Pop,生产者唯一。
17
+
18
+ ## 特性概览
19
+
20
+ | 特性 | 支持 |
21
+ | ------| ------|
22
+ | 单生产者 | ✅ |
23
+ | 多消费者 | ✅ |
24
+ | 批量操作 | ✅ |
25
+ | Peek/Pop 分离 | ✅ |
26
+ | 动态容量 | ❌(固定容量) |
27
+ | 无锁保证 | ✅(C++11 atomic) |
28
+
29
+ ## 接口函数
30
+
31
+ ### 构造与销毁
32
+
33
+ - ` LockFreeQueue(size_t length) `
34
+ - ` ~LockFreeQueue() `
35
+
36
+ ### 数据操作
37
+
38
+ - ` ErrorCode Push(const T&) `
39
+ - ` ErrorCode Pop(T&) `
40
+ - ` ErrorCode Pop() ` (丢弃头部元素)
41
+ - ` ErrorCode Peek(T&) `
42
+
43
+ ### 批量操作
44
+
45
+ - ` PushBatch(const T* data, size_t size) `
46
+ - ` PopBatch(T* data, size_t size) `
47
+ - ` PeekBatch(T* data, size_t size) `
48
+
49
+ ### 工具接口
50
+
51
+ - ` Size() ` :当前元素数量
52
+ - ` EmptySize() ` :剩余空间
53
+ - ` Reset() ` :重置队列为空
54
+
55
+ ## 使用示例
56
+
57
+ ``` cpp
58
+ LibXR::LockFreeQueue<int > q (128);
59
+ q.Push(10);
60
+
61
+ int value;
62
+ if (q.Pop(value) == LibXR::ErrorCode::OK) {
63
+ // 使用 value
64
+ }
65
+ ```
66
+
67
+ ## 注意事项
68
+
69
+ - 仅适用于 **单生产者** 场景,多生产者需使用外部同步或其他队列方案。
70
+ - 容量固定,构造时需明确所需大小。
71
+ - 数据结构对齐至 cache line,可减少伪共享带来的性能损失。
72
+
73
+ ## 适用场景
74
+
75
+ - 中断与任务线程间的数据通信
76
+ - 实时日志收集
77
+ - 多线程传感器数据采样
You can’t perform that action at this time.
0 commit comments