aboutsummaryrefslogtreecommitdiff
path: root/embassy-executor/tests
diff options
context:
space:
mode:
authorDániel Buga <[email protected]>2024-11-26 00:20:34 +0100
committerDániel Buga <[email protected]>2024-12-17 16:52:13 +0100
commitc6ca46c82529e014aaceb218ad88978c50f0db07 (patch)
treeed976c45f41a34e6b7ba59aaa047dfc6adc00728 /embassy-executor/tests
parent2853308d8f7b845a9255bd7f68911a5214f17ca1 (diff)
Set RUN_QUEUED unconditionally
Diffstat (limited to 'embassy-executor/tests')
-rw-r--r--embassy-executor/tests/test.rs133
1 files changed, 133 insertions, 0 deletions
diff --git a/embassy-executor/tests/test.rs b/embassy-executor/tests/test.rs
index 0ce1f1891..78c49c071 100644
--- a/embassy-executor/tests/test.rs
+++ b/embassy-executor/tests/test.rs
@@ -138,6 +138,139 @@ fn executor_task_self_wake_twice() {
138} 138}
139 139
140#[test] 140#[test]
141fn waking_after_completion_does_not_poll() {
142 use embassy_sync::waitqueue::AtomicWaker;
143
144 #[task]
145 async fn task1(trace: Trace, waker: &'static AtomicWaker) {
146 poll_fn(|cx| {
147 trace.push("poll task1");
148 waker.register(cx.waker());
149 Poll::Ready(())
150 })
151 .await
152 }
153
154 let waker = Box::leak(Box::new(AtomicWaker::new()));
155
156 let (executor, trace) = setup();
157 executor.spawner().spawn(task1(trace.clone(), waker)).unwrap();
158
159 unsafe { executor.poll() };
160 waker.wake();
161 unsafe { executor.poll() };
162
163 // Exited task may be waken but is not polled
164 waker.wake();
165 waker.wake();
166 unsafe { executor.poll() }; // Clears running status
167
168 // Can respawn waken-but-dead task
169 executor.spawner().spawn(task1(trace.clone(), waker)).unwrap();
170
171 unsafe { executor.poll() };
172
173 assert_eq!(
174 trace.get(),
175 &[
176 "pend", // spawning a task pends the executor
177 "poll task1", //
178 "pend", // manual wake, gets cleared by poll
179 "pend", // manual wake, single pend for two wakes
180 "pend", // respawning a task pends the executor
181 "poll task1", //
182 ]
183 )
184}
185
186#[test]
187fn waking_with_old_waker_after_respawn() {
188 use embassy_sync::waitqueue::AtomicWaker;
189
190 async fn yield_now(trace: Trace) {
191 let mut yielded = false;
192 poll_fn(|cx| {
193 if yielded {
194 Poll::Ready(())
195 } else {
196 trace.push("yield_now");
197 yielded = true;
198 cx.waker().wake_by_ref();
199 Poll::Pending
200 }
201 })
202 .await
203 }
204
205 #[task]
206 async fn task1(trace: Trace, waker: &'static AtomicWaker) {
207 yield_now(trace.clone()).await;
208 poll_fn(|cx| {
209 trace.push("poll task1");
210 waker.register(cx.waker());
211 Poll::Ready(())
212 })
213 .await;
214 }
215
216 let waker = Box::leak(Box::new(AtomicWaker::new()));
217
218 let (executor, trace) = setup();
219 executor.spawner().spawn(task1(trace.clone(), waker)).unwrap();
220
221 unsafe { executor.poll() };
222 unsafe { executor.poll() }; // progress to registering the waker
223 waker.wake();
224 unsafe { executor.poll() };
225 // Task has exited
226
227 assert_eq!(
228 trace.get(),
229 &[
230 "pend", // spawning a task pends the executor
231 "yield_now", //
232 "pend", // yield_now wakes the task
233 "poll task1", //
234 "pend", // task self-wakes
235 ]
236 );
237
238 // Can respawn task on another executor
239 let (other_executor, other_trace) = setup();
240 other_executor
241 .spawner()
242 .spawn(task1(other_trace.clone(), waker))
243 .unwrap();
244
245 unsafe { other_executor.poll() }; // just run to the yield_now
246 waker.wake(); // trigger old waker registration
247 unsafe { executor.poll() };
248 unsafe { other_executor.poll() };
249
250 // First executor's trace has not changed
251 assert_eq!(
252 trace.get(),
253 &[
254 "pend", // spawning a task pends the executor
255 "yield_now", //
256 "pend", // yield_now wakes the task
257 "poll task1", //
258 "pend", // task self-wakes
259 ]
260 );
261
262 assert_eq!(
263 other_trace.get(),
264 &[
265 "pend", // spawning a task pends the executor
266 "yield_now", //
267 "pend", // manual wake, gets cleared by poll
268 "poll task1", //
269 ]
270 );
271}
272
273#[test]
141fn executor_task_cfg_args() { 274fn executor_task_cfg_args() {
142 // simulate cfg'ing away argument c 275 // simulate cfg'ing away argument c
143 #[task] 276 #[task]