1use std::{future::Future, pin::Pin, task::Poll};
4
5pub fn yield_now() -> Yield {
7 Yield(true)
8}
9
10pub struct Yield(bool);
11
12impl Future for Yield {
13 type Output = ();
14
15 fn poll(mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
16 if self.0 {
17 cx.waker().wake_by_ref();
18 self.as_mut().0 = false;
19 Poll::Pending
20 } else {
21 Poll::Ready(())
22 }
23 }
24}
25#[cfg(test)]
26mod tests {
27 use super::*;
28
29 #[tokio::test]
30 async fn tokio_test() {
31 use std::cell::Cell;
32 let x = Cell::new(0u32);
33 let a = async {
34 for _ in 0..10000 {
35 x.set(x.get() + 1);
36 yield_now().await;
37 }
38 };
39 let b = async {
40 for i in 0..10000 {
41 assert_eq!(x.get(), i + 1);
42 tokio::task::yield_now().await;
43 }
44 };
45
46 futures::future::join(a, b).await;
47 }
48
49 #[async_std::test]
50 async fn async_std_test() {
51 use std::cell::Cell;
52 let x = Cell::new(0u32);
53 let a = async {
54 for _ in 0..10000 {
55 x.set(x.get() + 1);
56 yield_now().await;
57 }
58 };
59 let b = async {
60 for i in 0..10000 {
61 assert_eq!(x.get(), i + 1);
62 async_std::task::yield_now().await;
63 }
64 };
65
66 futures::future::join(a, b).await;
67 }
68}