libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
lockfree_list.hpp
1#pragma once
2
3#include <atomic>
4#include <utility>
5
6#include "libxr_assert.hpp"
7#include "libxr_def.hpp"
8
9namespace LibXR
10{
11
22class alignas(LIBXR_CACHE_LINE_SIZE) LockFreeList
23{
24 public:
30 {
31 public:
39 BaseNode(size_t size) : size_(size) {}
40
45 ~BaseNode() { ASSERT(next_ == nullptr); }
46
47 std::atomic<BaseNode*> next_ =
48 nullptr;
49 size_t size_;
50 };
51
59 template <typename Data>
60 class Node : public BaseNode
61 {
62 public:
67 Node() : BaseNode(sizeof(Data)) {}
68
76 explicit Node(const Data& data) : BaseNode(sizeof(Data)), data_(data) {}
77
83 template <typename... Args>
84 explicit Node(Args&&... args)
85 : BaseNode(sizeof(Data)), data_{std::forward<Args>(args)...}
86 {
87 }
88
98 Node& operator=(const Data& data)
99 {
100 data_ = data;
101 return *this;
102 }
103
108 Data* operator->() noexcept { return &data_; }
109 const Data* operator->() const noexcept { return &data_; }
110 Data& operator*() noexcept { return data_; }
111 operator Data&() noexcept { return data_; }
112
113 Data data_;
114 };
115
120 LockFreeList() noexcept : head_(0)
121 {
122 head_.next_.store(&head_, std::memory_order_relaxed);
123 }
124
130 {
131 for (auto pos = head_.next_.load(); pos != &head_;)
132 {
133 auto tmp = pos->next_.load();
134 pos->next_.store(nullptr);
135 pos = tmp;
136 }
137
138 head_.next_.store(nullptr);
139 }
140
148 void Add(BaseNode& data)
149 {
150 BaseNode* current_head = nullptr;
151 do
152 {
153 current_head = head_.next_.load(std::memory_order_acquire);
154 data.next_.store(current_head, std::memory_order_relaxed);
155 } while (!head_.next_.compare_exchange_weak(
156 current_head, &data, std::memory_order_release, std::memory_order_acquire));
157 }
158
166 uint32_t Size() noexcept
167 {
168 uint32_t size = 0;
169 for (auto pos = head_.next_.load(std::memory_order_acquire); pos != &head_;
170 pos = pos->next_.load(std::memory_order_relaxed))
171 {
172 ++size;
173 }
174 return size;
175 }
176
192 template <typename Data, typename Func, SizeLimitMode LimitMode = SizeLimitMode::MORE>
193 ErrorCode Foreach(Func func)
194 {
195 for (auto pos = head_.next_.load(std::memory_order_acquire); pos != &head_;
196 pos = pos->next_.load(std::memory_order_relaxed))
197 {
198 Assert::SizeLimitCheck<LimitMode>(sizeof(Data), pos->size_);
199 if (auto res = func(static_cast<Node<Data>*>(pos)->data_); res != ErrorCode::OK)
200 {
201 return res;
202 }
203 }
204 return ErrorCode::OK;
205 }
206
207 private:
209};
210
211} // namespace LibXR
链表基础节点,所有节点都继承自该类。 Base node for the linked list, serving as a parent for all nodes.
BaseNode(size_t size)
构造 BaseNode 并设置节点大小。 Constructs a BaseNode and sets its size.
size_t size_
当前节点的数据大小(字节)。 Size of the current node (in bytes).
std::atomic< BaseNode * > next_
指向下一个节点的原子指针。 Atomic pointer to the next node.
~BaseNode()
析构函数,确保节点不会在列表中残留。 Destructor ensuring the node does not remain in the list.
数据节点模板,继承自 BaseNode,用于存储具体数据类型。 Template data node that inherits from BaseNode to store specific data...
Node()
默认构造函数,初始化节点大小。 Default constructor initializing the node size.
Data data_
存储的数据。 The stored data.
Node & operator=(const Data &data)
赋值运算符重载,允许直接对节点赋值。 Overloaded assignment operator for assigning values to the node.
Node(Args &&... args)
通过参数列表构造节点 (Constructor initializing a node using arguments list).
Node(const Data &data)
使用数据值构造 Node 节点。 Constructs a Node with the given data value.
Data * operator->() noexcept
操作符重载,提供数据访问接口。 Operator overloads providing access to the data.
链表实现,用于存储和管理数据节点。 A linked list implementation for storing and managing data nodes.
ErrorCode Foreach(Func func)
遍历链表中的每个节点,并应用回调函数。 Iterates over each node in the list and applies a callback function.
LockFreeList() noexcept
默认构造函数,初始化链表头节点。 Default constructor initializing the linked list head node.
BaseNode head_
链表头节点。 The head node of the list.
uint32_t Size() noexcept
获取链表中的节点数量。 Gets the number of nodes in the linked list.
~LockFreeList()
析构函数,释放所有节点。 Destructor releasing all nodes.
void Add(BaseNode &data)
向链表添加一个节点。 Adds a node to the linked list.
LibXR 命名空间
Definition ch32_gpio.hpp:9