From 3c6c9381cfbc29b7913793984d62c7bcb5ccf1c1 Mon Sep 17 00:00:00 2001 From: james7132 Date: Mon, 13 Jun 2022 04:41:31 -0700 Subject: [PATCH 1/3] Replace parking with std::thread::park --- Cargo.toml | 3 +-- src/future.rs | 25 +++++++++++-------------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4fca8f2..b3c2dd7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ exclude = ["/.*"] [features] default = ["std"] -std = ["alloc", "fastrand", "futures-io", "parking", "memchr", "waker-fn"] +std = ["alloc", "fastrand", "futures-io", "memchr", "waker-fn"] alloc = [] [dependencies] @@ -29,7 +29,6 @@ fastrand = { version = "1.3.4", optional = true } futures-core = { version = "0.3.5", default-features = false } futures-io = { version = "0.3.5", optional = true } memchr = { version = "2.3.3", optional = true } -parking = { version = "2.0.0", optional = true } pin-project-lite = "0.2.0" waker-fn = { version = "1.0.0", optional = true } diff --git a/src/future.rs b/src/future.rs index b54fcee..449bdbf 100644 --- a/src/future.rs +++ b/src/future.rs @@ -55,25 +55,22 @@ pub fn block_on(future: impl Future) -> T { use std::cell::RefCell; use std::task::Waker; - use parking::Parker; use waker_fn::waker_fn; // Pin the future on the stack. crate::pin!(future); - // Creates a parker and an associated waker that unparks it. - fn parker_and_waker() -> (Parker, Waker) { - let parker = Parker::new(); - let unparker = parker.unparker(); - let waker = waker_fn(move || { - unparker.unpark(); - }); - (parker, waker) + // Creates a waker that unparks the current thread it. + fn waker() -> Waker { + let thread = std::thread::current(); + waker_fn(move || { + thread.unpark(); + }) } thread_local! { // Cached parker and waker for efficiency. - static CACHE: RefCell<(Parker, Waker)> = RefCell::new(parker_and_waker()); + static CACHE: RefCell = RefCell::new(waker()); } CACHE.with(|cache| { @@ -81,28 +78,28 @@ pub fn block_on(future: impl Future) -> T { match cache.try_borrow_mut() { Ok(cache) => { // Use the cached parker and waker. - let (parker, waker) = &*cache; + let waker = &*cache; let cx = &mut Context::from_waker(waker); // Keep polling until the future is ready. loop { match future.as_mut().poll(cx) { Poll::Ready(output) => return output, - Poll::Pending => parker.park(), + Poll::Pending => std::thread::park(), } } } Err(_) => { // Looks like this is a recursive `block_on()` call. // Create a fresh parker and waker. - let (parker, waker) = parker_and_waker(); + let waker = waker(); let cx = &mut Context::from_waker(&waker); // Keep polling until the future is ready. loop { match future.as_mut().poll(cx) { Poll::Ready(output) => return output, - Poll::Pending => parker.park(), + Poll::Pending => std::thread::park(), } } } From b95948d40bc2d1b262451192db0c25ed8e9ca61c Mon Sep 17 00:00:00 2001 From: james7132 Date: Mon, 13 Jun 2022 05:03:30 -0700 Subject: [PATCH 2/3] No longer need to split on whether it's recursive or not --- src/future.rs | 54 +++++++++++++++------------------------------------ 1 file changed, 16 insertions(+), 38 deletions(-) diff --git a/src/future.rs b/src/future.rs index 449bdbf..07c67c9 100644 --- a/src/future.rs +++ b/src/future.rs @@ -52,7 +52,6 @@ use core::task::{Context, Poll}; /// ``` #[cfg(feature = "std")] pub fn block_on(future: impl Future) -> T { - use std::cell::RefCell; use std::task::Waker; use waker_fn::waker_fn; @@ -60,48 +59,27 @@ pub fn block_on(future: impl Future) -> T { // Pin the future on the stack. crate::pin!(future); - // Creates a waker that unparks the current thread it. - fn waker() -> Waker { - let thread = std::thread::current(); - waker_fn(move || { - thread.unpark(); - }) - } - thread_local! { + // Creates a cached waker that unparks the current thread it. // Cached parker and waker for efficiency. - static CACHE: RefCell = RefCell::new(waker()); + static CACHE: Waker = { + let thread = std::thread::current(); + waker_fn(move || { + thread.unpark(); + }) + }; } CACHE.with(|cache| { - // Try grabbing the cached parker and waker. - match cache.try_borrow_mut() { - Ok(cache) => { - // Use the cached parker and waker. - let waker = &*cache; - let cx = &mut Context::from_waker(waker); - - // Keep polling until the future is ready. - loop { - match future.as_mut().poll(cx) { - Poll::Ready(output) => return output, - Poll::Pending => std::thread::park(), - } - } - } - Err(_) => { - // Looks like this is a recursive `block_on()` call. - // Create a fresh parker and waker. - let waker = waker(); - let cx = &mut Context::from_waker(&waker); - - // Keep polling until the future is ready. - loop { - match future.as_mut().poll(cx) { - Poll::Ready(output) => return output, - Poll::Pending => std::thread::park(), - } - } + // Use the cached waker. + let waker = &*cache; + let cx = &mut Context::from_waker(waker); + + // Keep polling until the future is ready. + loop { + match future.as_mut().poll(cx) { + Poll::Ready(output) => return output, + Poll::Pending => std::thread::park(), } } }) From 0420a257b1997fec5b3770485c2392bc3e8c7a5a Mon Sep 17 00:00:00 2001 From: james7132 Date: Mon, 13 Jun 2022 05:36:11 -0700 Subject: [PATCH 3/3] Shrink code a bit --- src/future.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/future.rs b/src/future.rs index 07c67c9..f37f8e4 100644 --- a/src/future.rs +++ b/src/future.rs @@ -64,9 +64,7 @@ pub fn block_on(future: impl Future) -> T { // Cached parker and waker for efficiency. static CACHE: Waker = { let thread = std::thread::current(); - waker_fn(move || { - thread.unpark(); - }) + waker_fn(move || thread.unpark()) }; }