20 #include <type_traits>
28 namespace runtime::detail {
30 template<std::
size_t MaxWaiters>
34 [[nodiscard]]
bool add(task_context& context) noexcept
39 [](
auto const& waiter) {
40 return waiter.context != nullptr &&
41 waiter.context->generation() != waiter.generation;
47 waiters_.begin(), waiters_.end(), [&context](
auto const& waiter) {
48 return waiter.context == &context &&
49 waiter.generation == context.generation();
53 auto slot = std::find_if(
54 waiters_.begin(), waiters_.end(), [](
auto const& waiter) {
55 return waiter.context == nullptr;
57 if (slot != waiters_.end()) {
58 *slot = waiter_record{ &context, context.generation() };
67 void remove(task_context& context) noexcept
72 [&context](
auto const& waiter) { return waiter.context == &context; },
76 void wake_one() noexcept
80 for (
auto& waiter : waiters_) {
81 if (waiter.context ==
nullptr) {
84 if (waiter.context->generation() == waiter.generation) {
85 waiter.context->mark_ready();
92 void wake_all() noexcept
94 for (
auto& waiter : waiters_) {
95 if (waiter.context !=
nullptr) {
96 if (waiter.context->generation() == waiter.generation) {
97 waiter.context->mark_ready();
107 task_context* context{};
108 std::uint32_t generation{};
111 std::array<waiter_record, MaxWaiters> waiters_{};
120 template<std::
size_t MaxWaiters = 4U>
139 [[nodiscard]]
bool is_set() const noexcept
159 (void)flag_->waiters_.add(handle.promise().context());
164 flag_->waiters_.remove(context);
180 runtime::detail::waiter_list<MaxWaiters> waiters_{};
189 template<std::
size_t MaxWaiters = 4U>
205 [[nodiscard]]
bool is_set() const noexcept
207 return flag_.is_set();
210 [[nodiscard]]
auto wait() noexcept
219 template<std::
size_t MaxWaiters = 4U>
222 template<std::
size_t MaxWaiters>
226 template<std::
size_t MaxWaiters = 4U>
253 (void)source_->waiters_.add(handle.promise().context());
258 source_->waiters_.remove(context);
289 template<std::
size_t MaxWaiters = 4U>
318 runtime::detail::waiter_list<MaxWaiters> waiters_{};
325 template<
typename T, std::
size_t MaxWaiters = 4U>
338 value_ = std::move(
value);
353 [[nodiscard]]
bool ready() const noexcept
357 [[nodiscard]] T
const&
value() const noexcept
372 return source_->
ready();
377 (void)source_->waiters_.add(handle.promise().context());
382 source_->waiters_.remove(context);
387 return source_->value_;
402 runtime::detail::waiter_list<MaxWaiters> waiters_{};
413 template<
typename Channel>
416 , send_const_([](
void*
object, T
const& value) {
417 return static_cast<Channel*
>(object)->
try_send(value);
419 , send_move_([](
void*
object, T&& value) {
420 return static_cast<Channel*
>(object)->
try_send(std::move(value));
427 return send_const_ !=
nullptr && send_const_(object_, value);
432 return send_move_ !=
nullptr && send_move_(object_, std::move(value));
436 using send_const_fn = bool (*)(
void*, T
const&);
437 using send_move_fn = bool (*)(
void*, T&&);
440 send_const_fn send_const_{};
441 send_move_fn send_move_{};
450 template<
typename Channel>
453 , receive_([](
void*
object, T& value) {
454 return static_cast<Channel*
>(object)->
try_receive(value);
461 return receive_ !=
nullptr && receive_(object_, value);
465 using receive_fn = bool (*)(
void*, T&);
468 receive_fn receive_{};
477 template<
typename Channel>
480 , latest_([](
void const*
object, T& value) {
481 return static_cast<Channel const*
>(object)->
latest(value);
486 [[nodiscard]]
bool latest(T& value)
const
488 return latest_ !=
nullptr && latest_(object_, value);
492 using latest_fn = bool (*)(
void const*, T&);
494 void const* object_{};
503 std::size_t Capacity,
505 std::size_t MaxWaiters = 4U>
508 static_assert(Capacity > 0U,
"tsm: channel requires non-zero capacity");
510 "tsm: channel requires a known overflow policy");
519 const bool accepted = push(value);
521 latest_ = data_[latest_index()];
523 receivers_.wake_one();
530 const bool accepted = push(std::move(value));
532 latest_ = data_[latest_index()];
534 receivers_.wake_one();
556 value = std::move(data_[pop_index_]);
557 pop_index_ = next(pop_index_);
562 [[nodiscard]]
bool empty() const noexcept
566 [[nodiscard]]
bool full() const noexcept
568 return size_ == Capacity;
570 [[nodiscard]] std::size_t
size() const noexcept
574 [[nodiscard]]
static constexpr std::size_t
capacity() noexcept
579 [[nodiscard]]
bool latest(T& value)
const
603 template<
typename Value>
609 , value_(std::forward<Value>(value))
617 accepted_ = target_->
try_send(std::move(value_));
633 template<
typename Value>
634 [[nodiscard]]
auto send(Value&& value)
657 (void)source_->receivers_.add(handle.promise().context());
662 source_->receivers_.remove(context);
672 return std::move(value_);
687 static constexpr std::size_t next(std::size_t index) noexcept
689 return (index + 1U) % Capacity;
692 static constexpr std::size_t previous(std::size_t index) noexcept
694 return index == 0U ? Capacity - 1U : index - 1U;
697 [[nodiscard]] std::size_t latest_index() const noexcept
699 return previous(push_index_);
702 template<
typename Value>
703 [[nodiscard]]
bool push(Value&& value)
706 if constexpr (std::same_as<OverflowPolicy,
709 }
else if constexpr (std::same_as<OverflowPolicy,
711 pop_index_ = next(pop_index_);
714 data_[previous(push_index_)] = std::forward<Value>(value);
721 data_[push_index_] = std::forward<Value>(value);
722 push_index_ = next(push_index_);
727 std::array<T, Capacity> data_{};
729 std::size_t push_index_{};
730 std::size_t pop_index_{};
733 runtime::detail::waiter_list<MaxWaiters> receivers_{};
739 std::size_t Capacity,
741 std::size_t MaxWaiters = 4U>
749 template<
typename T, std::
size_t MaxWaiters = 4U>
753 template<
typename... Args>
755 : value_(std::forward<Args>(args)...)
771 if (!target_->locked_) {
772 target_->locked_ =
true;
781 (void)target_->waiters_.add(handle.promise().context());
786 target_->waiters_.remove(context);
794 target_->locked_ =
true;
796 return target_->value_;
818 template<
typename Fn>
821 return std::forward<Fn>(fn)(value_);
824 [[nodiscard]]
bool locked() const noexcept
840 runtime::detail::waiter_list<MaxWaiters> waiters_{};
cancellation_token< MaxWaiters > token() noexcept
Definition: sync.h:293
void reset() noexcept
Definition: sync.h:304
bool stop_requested() const noexcept
Definition: sync.h:309
void request_cancel() noexcept
Definition: sync.h:298
void await_resume() const noexcept
Definition: sync.h:261
bool await_ready() const noexcept
Definition: sync.h:246
void await_suspend(task::handle_type handle) noexcept
Definition: sync.h:251
void await_cancel(task_context &context) noexcept
Definition: sync.h:256
wait_awaitable(cancellation_source< MaxWaiters > &source) noexcept
Definition: sync.h:240
Read-only cancellation capability for cooperative tasks.
Definition: sync.h:228
cancellation_token()=default
wait_awaitable wait() const noexcept
Definition: sync.h:267
friend class cancellation_source< MaxWaiters >
Definition: sync.h:273
bool stop_requested() const noexcept
Definition: sync.h:232
void await_suspend(task::handle_type handle) noexcept
Definition: sync.h:157
void await_cancel(task_context &context) noexcept
Definition: sync.h:162
void await_resume() const noexcept
Definition: sync.h:167
wait_awaitable(event_flag &flag) noexcept
Definition: sync.h:147
bool await_ready() const noexcept
Definition: sync.h:152
void set() noexcept
Definition: sync.h:124
void reset() noexcept
Definition: sync.h:135
bool is_set() const noexcept
Definition: sync.h:139
void set_from_isr() noexcept
Definition: sync.h:130
wait_awaitable wait() noexcept
Definition: sync.h:173
bool is_set() const noexcept
Definition: sync.h:205
auto wait() noexcept
Definition: sync.h:210
void notify_from_isr() noexcept
Definition: sync.h:197
void reset() noexcept
Definition: sync.h:201
void notify() noexcept
Definition: sync.h:193
lock_awaitable(mutex &target) noexcept
Definition: sync.h:764
T & await_resume() noexcept
Definition: sync.h:789
void await_cancel(task_context &context) noexcept
Definition: sync.h:784
void await_suspend(task::handle_type handle) noexcept
Definition: sync.h:779
bool await_ready() noexcept
Definition: sync.h:769
decltype(auto) with_lock(Fn &&fn)
Definition: sync.h:819
void unlock() noexcept
Definition: sync.h:809
T & unsafe_value() noexcept
Definition: sync.h:828
bool locked() const noexcept
Definition: sync.h:824
mutex(Args &&... args)
Definition: sync.h:754
lock_awaitable lock() noexcept
Definition: sync.h:804
T const & unsafe_value() const noexcept
Definition: sync.h:832
T await_resume()
Definition: sync.h:665
receive_awaitable(channel &source) noexcept
Definition: sync.h:642
void await_suspend(task::handle_type handle) noexcept
Definition: sync.h:653
bool await_ready()
Definition: sync.h:647
void await_cancel(task_context &context) noexcept
Definition: sync.h:660
void await_suspend(task::handle_type) noexcept
Definition: sync.h:621
bool await_ready()
Definition: sync.h:613
bool await_resume() const noexcept
Definition: sync.h:622
send_awaitable(channel &target, Value &&value)
Definition: sync.h:607
OverflowPolicy overflow_policy
Definition: sync.h:514
auto send(Value &&value)
Definition: sync.h:634
static constexpr std::size_t static_capacity
Definition: sync.h:515
runtime::sender< T > sender() noexcept
Definition: sync.h:588
bool try_send(T const &value)
Definition: sync.h:517
bool try_send_from_isr(T const &value)
Definition: sync.h:539
static constexpr std::size_t capacity() noexcept
Definition: sync.h:574
bool try_send(T &&value)
Definition: sync.h:528
bool empty() const noexcept
Definition: sync.h:562
runtime::latest_reader< T > latest_reader() const noexcept
Definition: sync.h:598
std::size_t size() const noexcept
Definition: sync.h:570
bool try_send_from_isr(T &&value)
Definition: sync.h:544
bool try_receive(T &value)
Definition: sync.h:549
bool latest(T &value) const
Definition: sync.h:579
T value_type
Definition: sync.h:513
receive_awaitable receive() noexcept
Definition: sync.h:681
bool full() const noexcept
Definition: sync.h:566
runtime::receiver< T > receiver() noexcept
Definition: sync.h:593
latest_reader(Channel const &channel) noexcept
Definition: sync.h:478
bool latest(T &value) const
Definition: sync.h:486
receiver(Channel &channel) noexcept
Definition: sync.h:451
bool try_receive(T &value) const
Definition: sync.h:459
bool try_send(T const &value) const
Definition: sync.h:425
bool try_send(T &&value) const
Definition: sync.h:430
sender(Channel &channel) noexcept
Definition: sync.h:414
T await_resume() const
Definition: sync.h:385
void await_suspend(task::handle_type handle) noexcept
Definition: sync.h:375
wait_awaitable(signal &source) noexcept
Definition: sync.h:365
bool await_ready() const noexcept
Definition: sync.h:370
void await_cancel(task_context &context) noexcept
Definition: sync.h:380
T const & value() const noexcept
Definition: sync.h:357
void publish_from_isr(T &&value)
Definition: sync.h:348
bool ready() const noexcept
Definition: sync.h:353
void publish(T &&value)
Definition: sync.h:336
void publish_from_isr(T const &value)
Definition: sync.h:343
wait_awaitable wait() noexcept
Definition: sync.h:394
void publish(T const &value)
Definition: sync.h:329
Definition: coroutine.h:196
std::coroutine_handle< promise_type > handle_type
Definition: coroutine.h:46
Static coroutine tasks for tsm runtime executors.
::tsm::overflow::reject_newest reject_newest
Definition: concepts.h:87
Definition: bare_metal.h:20
Runtime policy tags for dispatch and bounded queue admission.