48 template <
typename Handler>
49 bool Invoke(uint32_t events,
bool in_isr, Handler&& handler)
noexcept
51 ASSERT(IsEventMask(events));
53 uint32_t observed = state_.fetch_or(events, std::memory_order_release) | events;
54 while ((observed & OWNER_BIT) == 0U)
56 if (state_.compare_exchange_weak(observed, OWNER_BIT, std::memory_order_acquire,
57 std::memory_order_relaxed))
59 Handler& handler_ref = handler;
60 return Drain(handler_ref, in_isr, observed & EVENT_MASK);
80 ASSERT(IsEventMask(events));
81 state_.fetch_or(events, std::memory_order_release);
88 static constexpr uint32_t OWNER_BIT = 1U << 31U;
89 static constexpr uint32_t EVENT_MASK = ~OWNER_BIT;
91 static constexpr bool IsEventMask(uint32_t events)
93 return events != 0U && (events & OWNER_BIT) == 0U;
96 template <
typename Handler>
97 bool Drain(Handler& handler,
bool in_isr, uint32_t snapshot)
noexcept
105 handler(snapshot, in_isr);
108 uint32_t expected = OWNER_BIT;
109 if (state_.compare_exchange_strong(expected, 0U, std::memory_order_release,
110 std::memory_order_relaxed))
115 snapshot = state_.exchange(OWNER_BIT, std::memory_order_acq_rel) & EVENT_MASK;
119 std::atomic<uint32_t> state_{0U};