spin-sleep icon indicating copy to clipboard operation
spin-sleep copied to clipboard

Async support.

Open lsk569937453 opened this issue 1 year ago • 2 comments

I just want to use spin-sleep in the tokio-runtime.Could you support it?Thanks.

lsk569937453 avatar Aug 11 '23 06:08 lsk569937453

One option is to use blocking spin-sleep (block_in_place, or spawn_blocking), e.g.

tokio::task::block_in_place(|| spin_sleep::sleep(GAP));

Alternatively it is possible to have a non-blocking future impl that continuously spin-wakes the task until the timeout has been reached.

pub struct SpinWakeUntil(Instant);

impl std::future::Future for SpinWakeUntil {
    type Output = ();

    fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Self::Output> {
        match self.as_ref().0 <= Instant::now() {
            true => std::task::Poll::Ready(()),
            false => {
                cx.waker().wake_by_ref();
                std::task::Poll::Pending
            }
        }
    }
}

Usage

SpinWakeUntil(Instant::now() + GAP).await;

That will use 100% of a thread's CPU but won't block other futures.

Perhaps something similar to how spin_sleep uses thread::sleep for long initial durations then spins could work here too. E.g. use tokio::time::sleep for the bulk of the first bit then spin-wake the remainder. tokio::time::sleep has quite poor accuracy though even worse than thread::sleep.

I would also imagine spin-waking is less reliable than spinning, since it relies on the runtime event loop not being blocked by something else.

I have some doubts about having async code in this crate. I think the problem may be different enough that it is better served by a separate crate leaving this one to focus on blocking impl.

alexheretic avatar Aug 11 '23 09:08 alexheretic

you might wanna checkout tokio-timerfd which provides nanosecond precision. thread::yield_now and spin_loop are all sync which means blocking other futures while spinning for the accuracy time

ogios avatar Aug 05 '24 02:08 ogios