1use std::pin::pin;
2use std::sync::atomic::AtomicBool;
3use std::task::Poll::*;
4
5use crate::rt::worker::current_worker;
6use crate::rt::{poll, waker};
7use crate::{
8 rt::block_on,
9 time::{Duration, Instant, TimeUnit, wait_until},
10};
11
12pub struct Yield {
13 until: Instant,
14 ready: AtomicBool,
15}
16
17impl Yield {
18 pub fn new(until: Instant) -> Self {
19 Self {
20 until,
21 ready: AtomicBool::new(false),
22 }
23 }
24}
25
26impl Future for Yield {
27 type Output = ();
28
29 fn poll(
30 self: std::pin::Pin<&mut Self>,
31 cx: &mut std::task::Context<'_>,
32 ) -> std::task::Poll<Self::Output> {
33 let waker = cx.waker().clone();
34 poll(cx, async move {
35 if self.until > Instant::now() {
36 let waker = waker.clone();
37 wait_until(self.until, move || {
38 dbg!("WOAHHHHHH");
39 waker.wake_by_ref();
40 })
41 .await;
42 }
43
44 loop {
45 if self.ready.load(std::sync::atomic::Ordering::Relaxed) {
46 return;
47 } else {
48 self.ready.store(true, std::sync::atomic::Ordering::Relaxed);
49 }
50 }
51 })
52 }
53}
54
55pub fn yield_until(until: Instant) -> Yield {
56 Yield::new(until)
57}
58
59pub fn yield_for<T: TimeUnit>(duration: Duration<T>) -> Yield {
60 Yield::new(Instant::now() + duration)
61}
62
63pub fn yield_now() -> Yield {
64 Yield::new(Instant::now())
65}