libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
serialized_service.hpp
1#pragma once
2
3#include <atomic>
4#include <cstdint>
5
6#include "libxr_assert.hpp"
7
8namespace LibXR
9{
10
35{
36 public:
37 SerializedService() = default;
38
48 template <typename Handler>
49 bool Invoke(uint32_t events, bool in_isr, Handler&& handler) noexcept
50 {
51 ASSERT(IsEventMask(events));
52
53 uint32_t observed = state_.fetch_or(events, std::memory_order_release) | events;
54 while ((observed & OWNER_BIT) == 0U)
55 {
56 if (state_.compare_exchange_weak(observed, OWNER_BIT, std::memory_order_acquire,
57 std::memory_order_relaxed))
58 {
59 Handler& handler_ref = handler;
60 return Drain(handler_ref, in_isr, observed & EVENT_MASK);
61 }
62 }
63 return false;
64 }
65
74 void Publish(uint32_t events) noexcept
75 {
76 if (events == 0U)
77 {
78 return;
79 }
80 ASSERT(IsEventMask(events));
81 state_.fetch_or(events, std::memory_order_release);
82 }
83
84 SerializedService(const SerializedService&) = delete;
85 SerializedService& operator=(const SerializedService&) = delete;
86
87 private:
88 static constexpr uint32_t OWNER_BIT = 1U << 31U;
89 static constexpr uint32_t EVENT_MASK = ~OWNER_BIT;
90
91 static constexpr bool IsEventMask(uint32_t events)
92 {
93 return events != 0U && (events & OWNER_BIT) == 0U;
94 }
95
96 template <typename Handler>
97 bool Drain(Handler& handler, bool in_isr, uint32_t snapshot) noexcept
98 {
99 bool invoked = false;
100 while (true)
101 {
102 if (snapshot != 0U)
103 {
104 invoked = true;
105 handler(snapshot, in_isr);
106 }
107
108 uint32_t expected = OWNER_BIT;
109 if (state_.compare_exchange_strong(expected, 0U, std::memory_order_release,
110 std::memory_order_relaxed))
111 {
112 return invoked;
113 }
114
115 snapshot = state_.exchange(OWNER_BIT, std::memory_order_acq_rel) & EVENT_MASK;
116 }
117 }
118
119 std::atomic<uint32_t> state_{0U};
120};
121
122} // namespace LibXR
事件合并与回调串行化服务 / Event-coalescing serialized-callback service.
bool Invoke(uint32_t events, bool in_isr, Handler &&handler) noexcept
发布事件并尝试取得执行权 / Publish events and attempt to claim execution.
void Publish(uint32_t events) noexcept
为已有或确定会出现的执行者发布事件 / Publish for an active or guaranteed executor.
LibXR 命名空间 / LibXR namespace.
Definition ch32_can.hpp:14