Merge pull request #286 from embassy-rs/time-feature
Make embassy::time optional
This commit is contained in:
		
						commit
						b8e23bc74e
					
				@ -21,7 +21,7 @@ nrf52840 = ["nrf52840-pac"]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
embassy = { version = "0.1.0", path = "../embassy" }
 | 
			
		||||
embassy = { version = "0.1.0", path = "../embassy", features = ["time-tick-32768hz"] }
 | 
			
		||||
embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["nrf"]}
 | 
			
		||||
embassy-extras = {version = "0.1.0", path = "../embassy-extras" }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -12,7 +12,7 @@ defmt-warn = [ ]
 | 
			
		||||
defmt-error = [ ]
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
embassy = { version = "0.1.0", path = "../embassy" }
 | 
			
		||||
embassy = { version = "0.1.0", path = "../embassy", features = [ "time-tick-1mhz" ] }
 | 
			
		||||
embassy-extras = {version = "0.1.0", path = "../embassy-extras" }
 | 
			
		||||
embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["rp"]}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,6 @@ authors = ["Dario Nieuwenhuis <dirbaio@dirbaio.net>"]
 | 
			
		||||
edition = "2018"
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
embassy     = { version = "0.1.0", path = "../embassy", features = ["std"] }
 | 
			
		||||
embassy = { version = "0.1.0", path = "../embassy", features = ["std", "time-tick-32768hz"] }
 | 
			
		||||
embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["std"]}
 | 
			
		||||
lazy_static = "1.4.0"
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,7 @@ edition = "2018"
 | 
			
		||||
resolver = "2"
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
embassy = { version = "0.1.0", path = "../embassy" }
 | 
			
		||||
embassy = { version = "0.1.0", path = "../embassy", features = ["time-tick-32768hz"] }
 | 
			
		||||
embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["stm32"] }
 | 
			
		||||
embassy-extras = {version = "0.1.0", path = "../embassy-extras" }
 | 
			
		||||
embassy-traits = {version = "0.1.0", path = "../embassy-traits" }
 | 
			
		||||
 | 
			
		||||
@ -5,11 +5,13 @@ authors = ["Dario Nieuwenhuis <dirbaio@dirbaio.net>"]
 | 
			
		||||
edition = "2018"
 | 
			
		||||
 | 
			
		||||
[features]
 | 
			
		||||
default = ["tick-32768hz"]
 | 
			
		||||
default = []
 | 
			
		||||
std = ["futures/std", "embassy-traits/std"]
 | 
			
		||||
tick-32768hz = []
 | 
			
		||||
tick-1000hz = []
 | 
			
		||||
tick-1mhz = []
 | 
			
		||||
 | 
			
		||||
time = []
 | 
			
		||||
time-tick-32768hz = ["time"]
 | 
			
		||||
time-tick-1000hz = ["time"]
 | 
			
		||||
time-tick-1mhz = ["time"]
 | 
			
		||||
 | 
			
		||||
defmt-trace = []
 | 
			
		||||
defmt-debug = []
 | 
			
		||||
 | 
			
		||||
@ -4,13 +4,12 @@ use core::{mem, ptr};
 | 
			
		||||
 | 
			
		||||
pub mod raw;
 | 
			
		||||
mod run_queue;
 | 
			
		||||
pub(crate) mod timer;
 | 
			
		||||
#[cfg(feature = "time")]
 | 
			
		||||
mod timer_queue;
 | 
			
		||||
mod util;
 | 
			
		||||
mod waker;
 | 
			
		||||
 | 
			
		||||
use crate::interrupt::{Interrupt, InterruptExt};
 | 
			
		||||
use crate::time::Alarm;
 | 
			
		||||
 | 
			
		||||
#[must_use = "Calling a task function does nothing on its own. You must pass the returned SpawnToken to Executor::spawn()"]
 | 
			
		||||
pub struct SpawnToken<F> {
 | 
			
		||||
@ -117,7 +116,8 @@ impl Executor {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn set_alarm(&mut self, alarm: &'static dyn Alarm) {
 | 
			
		||||
    #[cfg(feature = "time")]
 | 
			
		||||
    pub fn set_alarm(&mut self, alarm: &'static dyn crate::time::Alarm) {
 | 
			
		||||
        self.inner.set_alarm(alarm);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -161,7 +161,8 @@ impl<I: Interrupt> InterruptExecutor<I> {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn set_alarm(&mut self, alarm: &'static dyn Alarm) {
 | 
			
		||||
    #[cfg(feature = "time")]
 | 
			
		||||
    pub fn set_alarm(&mut self, alarm: &'static dyn crate::time::Alarm) {
 | 
			
		||||
        self.inner.set_alarm(alarm);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,18 +1,20 @@
 | 
			
		||||
use atomic_polyfill::{AtomicU32, Ordering};
 | 
			
		||||
use core::cell::Cell;
 | 
			
		||||
use core::cmp::min;
 | 
			
		||||
use core::future::Future;
 | 
			
		||||
use core::marker::PhantomData;
 | 
			
		||||
use core::pin::Pin;
 | 
			
		||||
use core::ptr::NonNull;
 | 
			
		||||
use core::task::{Context, Poll, Waker};
 | 
			
		||||
use core::task::{Context, Poll};
 | 
			
		||||
use core::{mem, ptr};
 | 
			
		||||
 | 
			
		||||
use super::run_queue::{RunQueue, RunQueueItem};
 | 
			
		||||
use super::timer_queue::{TimerQueue, TimerQueueItem};
 | 
			
		||||
use super::util::UninitCell;
 | 
			
		||||
use super::waker;
 | 
			
		||||
use super::SpawnToken;
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "time")]
 | 
			
		||||
use super::timer_queue::{TimerQueue, TimerQueueItem};
 | 
			
		||||
#[cfg(feature = "time")]
 | 
			
		||||
use crate::time::{Alarm, Instant};
 | 
			
		||||
 | 
			
		||||
/// Task is spawned (has a future)
 | 
			
		||||
@ -20,26 +22,33 @@ pub(crate) const STATE_SPAWNED: u32 = 1 << 0;
 | 
			
		||||
/// Task is in the executor run queue
 | 
			
		||||
pub(crate) const STATE_RUN_QUEUED: u32 = 1 << 1;
 | 
			
		||||
/// Task is in the executor timer queue
 | 
			
		||||
#[cfg(feature = "time")]
 | 
			
		||||
pub(crate) const STATE_TIMER_QUEUED: u32 = 1 << 2;
 | 
			
		||||
 | 
			
		||||
pub struct TaskHeader {
 | 
			
		||||
    pub(crate) state: AtomicU32,
 | 
			
		||||
    pub(crate) run_queue_item: RunQueueItem,
 | 
			
		||||
    pub(crate) expires_at: Cell<Instant>,
 | 
			
		||||
    pub(crate) timer_queue_item: TimerQueueItem,
 | 
			
		||||
    pub(crate) executor: Cell<*const Executor>, // Valid if state != 0
 | 
			
		||||
    pub(crate) poll_fn: UninitCell<unsafe fn(NonNull<TaskHeader>)>, // Valid if STATE_SPAWNED
 | 
			
		||||
 | 
			
		||||
    #[cfg(feature = "time")]
 | 
			
		||||
    pub(crate) expires_at: Cell<Instant>,
 | 
			
		||||
    #[cfg(feature = "time")]
 | 
			
		||||
    pub(crate) timer_queue_item: TimerQueueItem,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl TaskHeader {
 | 
			
		||||
    pub(crate) const fn new() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            state: AtomicU32::new(0),
 | 
			
		||||
            expires_at: Cell::new(Instant::from_ticks(0)),
 | 
			
		||||
            run_queue_item: RunQueueItem::new(),
 | 
			
		||||
            timer_queue_item: TimerQueueItem::new(),
 | 
			
		||||
            executor: Cell::new(ptr::null()),
 | 
			
		||||
            poll_fn: UninitCell::uninit(),
 | 
			
		||||
 | 
			
		||||
            #[cfg(feature = "time")]
 | 
			
		||||
            expires_at: Cell::new(Instant::from_ticks(0)),
 | 
			
		||||
            #[cfg(feature = "time")]
 | 
			
		||||
            timer_queue_item: TimerQueueItem::new(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -154,9 +163,12 @@ unsafe impl<F: Future + 'static> Sync for Task<F> {}
 | 
			
		||||
 | 
			
		||||
pub struct Executor {
 | 
			
		||||
    run_queue: RunQueue,
 | 
			
		||||
    timer_queue: TimerQueue,
 | 
			
		||||
    signal_fn: fn(*mut ()),
 | 
			
		||||
    signal_ctx: *mut (),
 | 
			
		||||
 | 
			
		||||
    #[cfg(feature = "time")]
 | 
			
		||||
    timer_queue: TimerQueue,
 | 
			
		||||
    #[cfg(feature = "time")]
 | 
			
		||||
    alarm: Option<&'static dyn Alarm>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -164,13 +176,17 @@ impl Executor {
 | 
			
		||||
    pub const fn new(signal_fn: fn(*mut ()), signal_ctx: *mut ()) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            run_queue: RunQueue::new(),
 | 
			
		||||
            timer_queue: TimerQueue::new(),
 | 
			
		||||
            signal_fn,
 | 
			
		||||
            signal_ctx,
 | 
			
		||||
 | 
			
		||||
            #[cfg(feature = "time")]
 | 
			
		||||
            timer_queue: TimerQueue::new(),
 | 
			
		||||
            #[cfg(feature = "time")]
 | 
			
		||||
            alarm: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[cfg(feature = "time")]
 | 
			
		||||
    pub fn set_alarm(&mut self, alarm: &'static dyn Alarm) {
 | 
			
		||||
        self.alarm = Some(alarm);
 | 
			
		||||
    }
 | 
			
		||||
@ -192,6 +208,7 @@ impl Executor {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub unsafe fn run_queued(&'static self) {
 | 
			
		||||
        #[cfg(feature = "time")]
 | 
			
		||||
        if self.alarm.is_some() {
 | 
			
		||||
            self.timer_queue.dequeue_expired(Instant::now(), |p| {
 | 
			
		||||
                p.as_ref().enqueue();
 | 
			
		||||
@ -200,6 +217,8 @@ impl Executor {
 | 
			
		||||
 | 
			
		||||
        self.run_queue.dequeue_all(|p| {
 | 
			
		||||
            let task = p.as_ref();
 | 
			
		||||
 | 
			
		||||
            #[cfg(feature = "time")]
 | 
			
		||||
            task.expires_at.set(Instant::MAX);
 | 
			
		||||
 | 
			
		||||
            let state = task.state.fetch_and(!STATE_RUN_QUEUED, Ordering::AcqRel);
 | 
			
		||||
@ -216,11 +235,13 @@ impl Executor {
 | 
			
		||||
            task.poll_fn.read()(p as _);
 | 
			
		||||
 | 
			
		||||
            // Enqueue or update into timer_queue
 | 
			
		||||
            #[cfg(feature = "time")]
 | 
			
		||||
            self.timer_queue.update(p);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // If this is in the past, set_alarm will immediately trigger the alarm,
 | 
			
		||||
        // which will make the wfe immediately return so we do another loop iteration.
 | 
			
		||||
        #[cfg(feature = "time")]
 | 
			
		||||
        if let Some(alarm) = self.alarm {
 | 
			
		||||
            let next_expiration = self.timer_queue.next_expiration();
 | 
			
		||||
            alarm.set_callback(self.signal_fn, self.signal_ctx);
 | 
			
		||||
@ -242,9 +263,10 @@ pub unsafe fn wake_task(task: NonNull<TaskHeader>) {
 | 
			
		||||
    task.as_ref().enqueue();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub(crate) unsafe fn register_timer(at: Instant, waker: &Waker) {
 | 
			
		||||
#[cfg(feature = "time")]
 | 
			
		||||
pub(crate) unsafe fn register_timer(at: Instant, waker: &core::task::Waker) {
 | 
			
		||||
    let task = waker::task_from_waker(waker);
 | 
			
		||||
    let task = task.as_ref();
 | 
			
		||||
    let expires_at = task.expires_at.get();
 | 
			
		||||
    task.expires_at.set(min(expires_at, at));
 | 
			
		||||
    task.expires_at.set(expires_at.min(at));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,7 @@ pub(crate) mod fmt;
 | 
			
		||||
pub mod executor;
 | 
			
		||||
pub mod interrupt;
 | 
			
		||||
pub mod io;
 | 
			
		||||
#[cfg(feature = "time")]
 | 
			
		||||
pub mod time;
 | 
			
		||||
pub mod util;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										67
									
								
								embassy/src/time/delay.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								embassy/src/time/delay.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,67 @@
 | 
			
		||||
use core::future::Future;
 | 
			
		||||
 | 
			
		||||
use super::{Duration, Instant, Timer};
 | 
			
		||||
 | 
			
		||||
/// Type implementing async delays and blocking `embedded-hal` delays.
 | 
			
		||||
///
 | 
			
		||||
/// For this interface to work, the Executor's clock must be correctly initialized before using it.
 | 
			
		||||
/// The delays are implemented in a "best-effort" way, meaning that the cpu will block for at least
 | 
			
		||||
/// the amount provided, but accuracy can be affected by many factors, including interrupt usage.
 | 
			
		||||
/// Make sure to use a suitable tick rate for your use case. The tick rate can be chosen through
 | 
			
		||||
/// features flags of this crate.
 | 
			
		||||
pub struct Delay;
 | 
			
		||||
 | 
			
		||||
impl crate::traits::delay::Delay for Delay {
 | 
			
		||||
    type DelayFuture<'a> = impl Future<Output = ()> + 'a;
 | 
			
		||||
 | 
			
		||||
    fn delay_ms<'a>(&'a mut self, millis: u64) -> Self::DelayFuture<'a> {
 | 
			
		||||
        Timer::after(Duration::from_millis(millis))
 | 
			
		||||
    }
 | 
			
		||||
    fn delay_us<'a>(&'a mut self, micros: u64) -> Self::DelayFuture<'a> {
 | 
			
		||||
        Timer::after(Duration::from_micros(micros))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl embedded_hal::blocking::delay::DelayMs<u8> for Delay {
 | 
			
		||||
    fn delay_ms(&mut self, ms: u8) {
 | 
			
		||||
        block_for(Duration::from_millis(ms as u64))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl embedded_hal::blocking::delay::DelayMs<u16> for Delay {
 | 
			
		||||
    fn delay_ms(&mut self, ms: u16) {
 | 
			
		||||
        block_for(Duration::from_millis(ms as u64))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl embedded_hal::blocking::delay::DelayMs<u32> for Delay {
 | 
			
		||||
    fn delay_ms(&mut self, ms: u32) {
 | 
			
		||||
        block_for(Duration::from_millis(ms as u64))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl embedded_hal::blocking::delay::DelayUs<u8> for Delay {
 | 
			
		||||
    fn delay_us(&mut self, us: u8) {
 | 
			
		||||
        block_for(Duration::from_micros(us as u64))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl embedded_hal::blocking::delay::DelayUs<u16> for Delay {
 | 
			
		||||
    fn delay_us(&mut self, us: u16) {
 | 
			
		||||
        block_for(Duration::from_micros(us as u64))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl embedded_hal::blocking::delay::DelayUs<u32> for Delay {
 | 
			
		||||
    fn delay_us(&mut self, us: u32) {
 | 
			
		||||
        block_for(Duration::from_micros(us as u64))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Blocks the cpu for at least `duration`.
 | 
			
		||||
///
 | 
			
		||||
/// For this interface to work, the Executor's clock must be correctly initialized before using it.
 | 
			
		||||
pub fn block_for(duration: Duration) {
 | 
			
		||||
    let expires_at = Instant::now() + duration;
 | 
			
		||||
    while Instant::now() < expires_at {}
 | 
			
		||||
}
 | 
			
		||||
@ -1,30 +1,25 @@
 | 
			
		||||
//! Time abstractions
 | 
			
		||||
//! To use these abstractions, first call `set_clock` with an instance of an [Clock](trait.Clock.html).
 | 
			
		||||
//!
 | 
			
		||||
mod delay;
 | 
			
		||||
mod duration;
 | 
			
		||||
mod instant;
 | 
			
		||||
mod timer;
 | 
			
		||||
mod traits;
 | 
			
		||||
 | 
			
		||||
pub use crate::executor::timer::{with_timeout, Delay, Ticker, TimeoutError, Timer};
 | 
			
		||||
pub use delay::{block_for, Delay};
 | 
			
		||||
pub use duration::Duration;
 | 
			
		||||
pub use instant::Instant;
 | 
			
		||||
pub use timer::{with_timeout, Ticker, TimeoutError, Timer};
 | 
			
		||||
pub use traits::*;
 | 
			
		||||
 | 
			
		||||
#[cfg(any(
 | 
			
		||||
    all(feature = "tick-32768hz", feature = "tick-1000hz"),
 | 
			
		||||
    all(feature = "tick-32768hz", feature = "tick-1mhz"),
 | 
			
		||||
))]
 | 
			
		||||
compile_error!(
 | 
			
		||||
    "Disable default-features to be able to use a tick rate other than the default (32768 Hz)"
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "tick-1000hz")]
 | 
			
		||||
#[cfg(feature = "time-tick-1000hz")]
 | 
			
		||||
pub const TICKS_PER_SECOND: u64 = 1_000;
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "tick-32768hz")]
 | 
			
		||||
#[cfg(feature = "time-tick-32768hz")]
 | 
			
		||||
pub const TICKS_PER_SECOND: u64 = 32_768;
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "tick-1mhz")]
 | 
			
		||||
#[cfg(feature = "time-tick-1mhz")]
 | 
			
		||||
pub const TICKS_PER_SECOND: u64 = 1_000_000;
 | 
			
		||||
 | 
			
		||||
static mut CLOCK: Option<&'static dyn Clock> = None;
 | 
			
		||||
@ -42,56 +37,3 @@ pub unsafe fn set_clock(clock: &'static dyn Clock) {
 | 
			
		||||
pub(crate) fn now() -> u64 {
 | 
			
		||||
    unsafe { unwrap!(CLOCK, "No clock set").now() }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Type used for blocking delays through embedded-hal traits.
 | 
			
		||||
///
 | 
			
		||||
/// For this interface to work, the Executor's clock must be correctly initialized before using it.
 | 
			
		||||
/// The delays are implemented in a "best-effort" way, meaning that the cpu will block for at least
 | 
			
		||||
/// the amount provided, but accuracy can be affected by many factors, including interrupt usage.
 | 
			
		||||
/// Make sure to use a suitable tick rate for your use case. The tick rate can be chosen through
 | 
			
		||||
/// features flags of this crate.
 | 
			
		||||
pub struct BlockingTimer;
 | 
			
		||||
 | 
			
		||||
impl embedded_hal::blocking::delay::DelayMs<u8> for BlockingTimer {
 | 
			
		||||
    fn delay_ms(&mut self, ms: u8) {
 | 
			
		||||
        block_for(Duration::from_millis(ms as u64))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl embedded_hal::blocking::delay::DelayMs<u16> for BlockingTimer {
 | 
			
		||||
    fn delay_ms(&mut self, ms: u16) {
 | 
			
		||||
        block_for(Duration::from_millis(ms as u64))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl embedded_hal::blocking::delay::DelayMs<u32> for BlockingTimer {
 | 
			
		||||
    fn delay_ms(&mut self, ms: u32) {
 | 
			
		||||
        block_for(Duration::from_millis(ms as u64))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl embedded_hal::blocking::delay::DelayUs<u8> for BlockingTimer {
 | 
			
		||||
    fn delay_us(&mut self, us: u8) {
 | 
			
		||||
        block_for(Duration::from_micros(us as u64))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl embedded_hal::blocking::delay::DelayUs<u16> for BlockingTimer {
 | 
			
		||||
    fn delay_us(&mut self, us: u16) {
 | 
			
		||||
        block_for(Duration::from_micros(us as u64))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl embedded_hal::blocking::delay::DelayUs<u32> for BlockingTimer {
 | 
			
		||||
    fn delay_us(&mut self, us: u32) {
 | 
			
		||||
        block_for(Duration::from_micros(us as u64))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Blocks the cpu for at least `duration`.
 | 
			
		||||
///
 | 
			
		||||
/// For this interface to work, the Executor's clock must be correctly initialized before using it.
 | 
			
		||||
pub fn block_for(duration: Duration) {
 | 
			
		||||
    let expires_at = Instant::now() + duration;
 | 
			
		||||
    while Instant::now() < expires_at {}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,36 +1,11 @@
 | 
			
		||||
use core::future::Future;
 | 
			
		||||
use core::marker::PhantomData;
 | 
			
		||||
use core::pin::Pin;
 | 
			
		||||
use core::task::{Context, Poll};
 | 
			
		||||
use futures::{future::select, future::Either, pin_mut, Stream};
 | 
			
		||||
 | 
			
		||||
use super::raw;
 | 
			
		||||
use crate::executor::raw;
 | 
			
		||||
use crate::time::{Duration, Instant};
 | 
			
		||||
 | 
			
		||||
/// Delay abstraction using embassy's clock.
 | 
			
		||||
pub struct Delay {
 | 
			
		||||
    _data: PhantomData<bool>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Delay {
 | 
			
		||||
    pub fn new() -> Self {
 | 
			
		||||
        Delay {
 | 
			
		||||
            _data: PhantomData {},
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl crate::traits::delay::Delay for Delay {
 | 
			
		||||
    type DelayFuture<'a> = impl Future<Output = ()> + 'a;
 | 
			
		||||
 | 
			
		||||
    fn delay_ms<'a>(&'a mut self, millis: u64) -> Self::DelayFuture<'a> {
 | 
			
		||||
        Timer::after(Duration::from_millis(millis))
 | 
			
		||||
    }
 | 
			
		||||
    fn delay_us<'a>(&'a mut self, micros: u64) -> Self::DelayFuture<'a> {
 | 
			
		||||
        Timer::after(Duration::from_micros(micros))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct TimeoutError;
 | 
			
		||||
pub async fn with_timeout<F: Future>(timeout: Duration, fut: F) -> Result<F::Output, TimeoutError> {
 | 
			
		||||
    let timeout_fut = Timer::after(timeout);
 | 
			
		||||
@ -30,15 +30,3 @@ pub trait Alarm {
 | 
			
		||||
    /// If no alarm was set, this is a noop.
 | 
			
		||||
    fn clear(&self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<T: Alarm + ?Sized> Alarm for &T {
 | 
			
		||||
    fn set_callback(&self, callback: fn(*mut ()), ctx: *mut ()) {
 | 
			
		||||
        T::set_callback(self, callback, ctx);
 | 
			
		||||
    }
 | 
			
		||||
    fn set(&self, timestamp: u64) {
 | 
			
		||||
        T::set(self, timestamp);
 | 
			
		||||
    }
 | 
			
		||||
    fn clear(&self) {
 | 
			
		||||
        T::clear(self)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user