C/C++ API Reference
Loading...
Searching...
No Matches
dispatcher_for_test.h
1// Copyright 2025 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14#pragma once
15
16#include <atomic>
17#include <utility>
18
19#include "pw_async2/future_task.h"
20#include "pw_async2/runnable_dispatcher.h"
21#include "pw_async2/waker.h"
22
23namespace pw::async2 {
24
26
35template <typename Native>
37 public:
40
42 DispatcherForTestFacade& operator=(const DispatcherForTestFacade&) = delete;
43
46
47 ~DispatcherForTestFacade() override;
48
51 void AllowBlocking() { blocking_is_allowed_ = true; }
52
54 template <typename T>
55 auto RunInTaskUntilStalled(T& future) PW_LOCKS_EXCLUDED(internal::lock()) {
56 FutureTask<T&> task(future);
57 native().Post(task);
58 native().RunUntilStalled();
59
60 // Ensure that the task is no longer registered, as it will be destroyed
61 // once we return.
62 //
63 // This operation will not block because we are on the dispatcher thread
64 // and the dispatcher is not currently running (we just ran it).
65 task.Deregister();
66
67 return task.TakePoll();
68 }
69
78
82 void Release();
83
86 uint32_t tasks_polled() const {
87 return tasks_polled_.load(std::memory_order_relaxed);
88 }
89
91 uint32_t tasks_completed() const {
92 return tasks_completed_.load(std::memory_order_relaxed);
93 }
94
96 uint32_t wake_count() const {
97 return wake_count_.load(std::memory_order_relaxed);
98 }
99
100 private:
101 // Task to keep the Dispatcher busy in RunToCompletionUntilReleased().
102 class IdleTask : public Task {
103 public:
104 IdleTask() : Task(PW_ASYNC_TASK_NAME("IdleTask")) {}
105
106 ~IdleTask() override;
107
108 void Complete() {
109 should_complete_.store(true, std::memory_order_relaxed);
110 waker_.Wake();
111 }
112
113 void Reset() {
114 PW_DASSERT(!IsRegistered());
115 should_complete_.store(false, std::memory_order_relaxed);
116 }
117
118 private:
119 Poll<> DoPend(Context& cx) override;
120
121 Waker waker_;
122 std::atomic<bool> should_complete_ = false;
123 };
124
125 // These functions are implemented in dispatcher_for_test.cc for the
126 // NativeDispatcherForTest specialization only.
127 bool DoRunUntilStalled() override;
128
129 void DoWake() override;
130
131 void DoWaitForWake() override;
132
133 RunnableDispatcher& native() { return native_; }
134
135 Native native_;
136 IdleTask idle_task_;
137 bool blocking_is_allowed_ = false;
138 std::atomic<int> blocking_until_released_ = false;
139
140 // TODO: b/401049619 - Optionally provide metrics for production dispatchers.
141 std::atomic<uint32_t> tasks_polled_ = 0u;
142 std::atomic<uint32_t> tasks_completed_ = 0u;
143 std::atomic<uint32_t> wake_count_ = 0u;
144};
145
147
148} // namespace pw::async2
149
150#include "pw_async2_backend/native_dispatcher_for_test.h"
151
152namespace pw::async2 {
153
155
160
162
163} // namespace pw::async2
Definition: dispatcher_for_test.h:36
uint32_t wake_count() const
Returns the total number of times the dispatcher has been woken.
Definition: dispatcher_for_test.h:96
DispatcherForTestFacade()=default
DispatcherForTest is default constructible.
uint32_t tasks_polled() const
Definition: dispatcher_for_test.h:86
uint32_t tasks_completed() const
Returns the total number of tasks the dispatcher has run to completion.
Definition: dispatcher_for_test.h:91
auto RunInTaskUntilStalled(T &future)
Runs a future in a FutureTask until no progress can be made.
Definition: dispatcher_for_test.h:55
void AllowBlocking()
Definition: dispatcher_for_test.h:51
void Post(Task &task)
Definition: future_task.h:39
Poll< value_type > TakePoll()
Definition: future_task.h:64
Definition: runnable_dispatcher.h:24
bool RunUntilStalled()
Definition: runnable_dispatcher.h:30
Definition: task.h:67
bool IsRegistered() const
#define PW_ASYNC_TASK_NAME(name)
Generates a token for use as a task name.
Definition: task.h:35
#define PW_LOCKS_EXCLUDED(...)
Definition: lock_annotations.h:176