Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add core::task::yield_now #74335

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions library/core/src/task/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@ pub use self::wake::{Context, RawWaker, RawWakerVTable, Waker};
mod ready;
#[unstable(feature = "ready_macro", issue = "70922")]
pub use ready::ready;

mod yield_now;
#[unstable(feature = "task_yield_now", issue = "74331")]
pub use self::yield_now::{yield_now, YieldNow};
58 changes: 58 additions & 0 deletions library/core/src/task/yield_now.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use crate::future::Future;
use crate::pin::Pin;
use crate::task::{Context, Poll};

/// Cooperatively gives up a timeslice to the executor.
///
/// Calling this function calls move the currently executing future to the back
/// of the execution queue, making room for other futures to execute. This is
Comment on lines +7 to +8
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling this function doesn’t do anything, awaiting the returned future does. The rest of this sentence sounds like a definitive guarantee whereas the comment in the code says "most executors" which is a much weaker.

This doc should probably be rephrased along the lines of:

Awaiting the future returned by this function yields control back to the executor, giving it an opportunity to run other tasks. Executors typically move the current task to the back of their execution queue.

/// especially useful after running CPU-intensive operations inside a future.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(task_yield_now)]
/// # async fn run() {
/// #
/// use core::task;
///
/// task::yield_now().await;
/// #
/// # }
/// ```
#[unstable(feature = "task_yield_now", issue = "74331")]
#[inline]
pub fn yield_now() -> YieldNow {
YieldNow { is_polled: false }
}

/// Creates a future that yields back to the executor exactly once.
///
/// This `struct` is created by the [`yield_now`] function. See its
/// documentation for more.
#[unstable(feature = "task_yield_now", issue = "74331")]
#[must_use = "futures do nothing unless you `.await` or poll them"]
#[derive(Debug)]
pub struct YieldNow {
is_polled: bool,
}

#[unstable(feature = "task_yield_now", issue = "74331")]
impl Future for YieldNow {
type Output = ();

// Most futures executors are implemented as a FIFO queue, so all this
// future does is re-schedule the future back to the end of the queue,
// giving room for other futures to progress.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most futures executors are implemented as a FIFO queue

Shouldn't this assumption be mentioned in the doc comments?

fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
if self.is_polled {
return Poll::Ready(());
}

self.is_polled = true;
cx.waker().wake_by_ref();
Poll::Pending
}
}
9 changes: 7 additions & 2 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@
#![feature(stdsimd)]
#![feature(stmt_expr_attributes)]
#![feature(str_internals)]
#![feature(task_yield_now)]
#![feature(test)]
#![feature(thread_local)]
#![feature(toowned_clone_into)]
Expand Down Expand Up @@ -478,11 +479,15 @@ pub mod task {

#[doc(inline)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub use core::task::*;
pub use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};

#[doc(inline)]
#[unstable(feature = "wake_trait", issue = "69912")]
pub use alloc::task::*;
pub use alloc::task::Wake;

#[doc(inline)]
#[unstable(feature = "task_yield_now", issue = "74331")]
pub use core::task::{yield_now, YieldNow};
}

#[stable(feature = "futures_api", since = "1.36.0")]
Expand Down