One Framework 0.1.0
RoboMaster嵌入式框架“一键”解决方案,为你的“创意”服务。
载入中...
搜索中...
未找到
NBuf.hpp
浏览该文件的文档.
1#ifndef OF_TRIPLEBUF_HPP
2#define OF_TRIPLEBUF_HPP
3
4#include <new>
5#include <array>
6#include <zephyr/sys/atomic.h>
7#include <zephyr/kernel.h>
8
9#include <optional>
10
11using std::hardware_destructive_interference_size;
12
13namespace OF
14{
15 // SPMC N-Buffer Class
16 template <typename T, size_t N>
17 requires std::is_standard_layout_v<T> && (N >= 2)
18 class NBuf
19 {
20 public:
21 NBuf() = default;
22
23 NBuf(const NBuf&) = delete;
24 NBuf& operator =(const NBuf&) = delete;
25 NBuf(NBuf&& other) = delete;
26 NBuf& operator =(NBuf&& other) = delete;
27
28 void write(const T& data) noexcept
29 {
30 auto next_slot = (m_next_write_idx + 1) % N;
31 auto& slot = m_slots[next_slot];
32 atomic_inc(&slot.version);
33 compiler_barrier();
34 slot.data = data;
35 compiler_barrier();
36 atomic_inc(&slot.version);
37
38 atomic_set(&m_latest_idx, next_slot);
39 m_next_write_idx = next_slot;
40 }
41
42 template <typename Func>
43 void manipulate(const Func& func)
44 {
45 auto next_slot = (m_next_write_idx + 1) % N;
46 auto& slot = m_slots[next_slot];
47
48 atomic_inc(&slot.version);
49 compiler_barrier();
50 func(slot.data);
51 compiler_barrier();
52 atomic_inc(&slot.version);
53
54
55 atomic_set(&m_latest_idx, next_slot);
56 m_next_write_idx = next_slot;
57 }
58
59 std::optional<T> try_read() const noexcept
60 {
61 T out_data;
62 auto& slot = m_slots[atomic_get(&m_latest_idx)];
63
64 auto v1 = atomic_get(&slot.version);
65
66 compiler_barrier();
67 out_data = slot.data;
68 compiler_barrier();
69
70 auto v2 = atomic_get(&slot.version);
71 return v1 == v2 ? out_data : std::nullopt;
72
73 }
74
75
76 T read() const noexcept
77 {
78 T copy{};
79 auto& slot = m_slots[atomic_get(&m_latest_idx)];
80 atomic_val_t v1, v2{};
81 do
82 {
83 v1 = atomic_get(&slot.version);
84
85 if (v1 & 1)
86 {
87 k_yield();
88 continue;
89 }
90
91 compiler_barrier();
92 copy = slot.data;
93 compiler_barrier();
94
95 v2 = atomic_get(&slot.version);
96 }
97 while (v1 != v2);
98 return copy;
99 }
100
101 private:
102#ifdef __GNUC__
103# pragma GCC diagnostic push
104# pragma GCC diagnostic ignored "-Winterference-size"
105#endif
106 struct alignas (hardware_destructive_interference_size) Slot
107 {
108 atomic_t version = ATOMIC_INIT(0);
109 T data;
110 };
111#ifdef __GNUC__
112# pragma GCC diagnostic pop
113#endif
114
115 std::array<Slot, N> m_slots;
116
117 atomic_t m_latest_idx = ATOMIC_INIT(0);
118
119 atomic_val_t m_next_write_idx{0};
120 };
121}
122
123#endif //OF_TRIPLEBUF_HPP
void write(const T &data) noexcept
定义 NBuf.hpp:28
T read() const noexcept
定义 NBuf.hpp:76
NBuf(NBuf &&other)=delete
NBuf()=default
void manipulate(const Func &func)
定义 NBuf.hpp:43
NBuf(const NBuf &)=delete
std::optional< T > try_read() const noexcept
定义 NBuf.hpp:59
定义 Mecanum.hpp:6