spin-sleep
spin-sleep copied to clipboard
Async support.
I just want to use spin-sleep in the tokio-runtime.Could you support it?Thanks.
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.
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