libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
serialized_service.hpp
1#pragma once
2
3#include <atomic>
4#include <cstdint>
5
6namespace LibXR
7{
8
34{
35 public:
36 SerializedService() = default;
37
47 template <typename Handler>
48 bool Invoke(uint32_t events, Handler&& handler) noexcept
49 {
50 if ((events == 0U) || ((events & OWNER_BIT) != 0U))
51 {
52 return false;
53 }
54
55 uint32_t observed = state_.fetch_or(events, std::memory_order_release) | events;
56
57 while ((observed & OWNER_BIT) == 0U)
58 {
59 // Another owner may have consumed this invocation's event and released the state
60 // before our CAS. An empty state means there is no remaining work to claim.
61 if ((observed & EVENT_MASK) == 0U)
62 {
63 return false;
64 }
65
66 const uint32_t desired = observed | OWNER_BIT;
67 if (state_.compare_exchange_weak(observed, desired, std::memory_order_acquire,
68 std::memory_order_relaxed))
69 {
70 break;
71 }
72 }
73
74 if ((observed & OWNER_BIT) != 0U)
75 {
76 return false;
77 }
78
79 while (true)
80 {
81 const uint32_t snapshot =
82 state_.exchange(OWNER_BIT, std::memory_order_acq_rel) & EVENT_MASK;
83 if (snapshot != 0U)
84 {
85 handler(snapshot);
86 }
87
88 uint32_t expected = OWNER_BIT;
89 if (state_.compare_exchange_strong(expected, 0U, std::memory_order_release,
90 std::memory_order_acquire))
91 {
92 return true;
93 }
94 // A publisher ORed new events while OWNER_BIT was set. Keep ownership and consume
95 // the next snapshot; release cannot race past an already-published event.
96 }
97 }
98
99 SerializedService(const SerializedService&) = delete;
100 SerializedService& operator=(const SerializedService&) = delete;
101
102 private:
103 static constexpr uint32_t OWNER_BIT = 1U << 31U;
104 static constexpr uint32_t EVENT_MASK = ~OWNER_BIT;
105
106 std::atomic<uint32_t> state_{0U};
107};
108
109} // namespace LibXR
合并通知并串行执行服务函数 / Coalesce notifications and serialize service execution
bool Invoke(uint32_t events, Handler &&handler) noexcept
发布事件并尝试执行服务 / Publish events and try to run the service
LibXR 命名空间
Definition ch32_can.hpp:14