aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cyccnt.rs205
-rw-r--r--src/export.rs56
-rw-r--r--src/lib.rs308
-rw-r--r--src/tq.rs117
4 files changed, 362 insertions, 324 deletions
diff --git a/src/cyccnt.rs b/src/cyccnt.rs
new file mode 100644
index 00000000..a2b216c1
--- /dev/null
+++ b/src/cyccnt.rs
@@ -0,0 +1,205 @@
+//! Data Watchpoint Trace (DWT) unit's CYCle CouNTer
+
+use core::{
+ cmp::Ordering,
+ convert::{Infallible, TryInto},
+ fmt,
+ marker::PhantomData,
+ ops,
+};
+
+use cortex_m::peripheral::DWT;
+
+/// A measurement of the CYCCNT. Opaque and useful only with `Duration`
+///
+/// This data type is only available on ARMv7-M
+#[derive(Clone, Copy, Eq, PartialEq)]
+pub struct Instant {
+ inner: i32,
+ _not_send_or_sync: PhantomData<*mut ()>,
+}
+
+unsafe impl Sync for Instant {}
+
+#[cfg(not(feature = "heterogeneous"))]
+unsafe impl Send for Instant {}
+
+impl Instant {
+ /// Returns an instant corresponding to "now"
+ pub fn now() -> Self {
+ Instant {
+ inner: DWT::get_cycle_count() as i32,
+ _not_send_or_sync: PhantomData,
+ }
+ }
+
+ /// Returns the amount of time elapsed since this instant was created.
+ pub fn elapsed(&self) -> Duration {
+ Instant::now() - *self
+ }
+
+ /// Returns the amount of time elapsed from another instant to this one.
+ pub fn duration_since(&self, earlier: Instant) -> Duration {
+ let diff = self.inner - earlier.inner;
+ assert!(diff >= 0, "second instant is later than self");
+ Duration { inner: diff as u32 }
+ }
+}
+
+impl fmt::Debug for Instant {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_tuple("Instant")
+ .field(&(self.inner as u32))
+ .finish()
+ }
+}
+
+impl ops::AddAssign<Duration> for Instant {
+ fn add_assign(&mut self, dur: Duration) {
+ debug_assert!(dur.inner < (1 << 31));
+ self.inner = self.inner.wrapping_add(dur.inner as i32);
+ }
+}
+
+impl ops::Add<Duration> for Instant {
+ type Output = Self;
+
+ fn add(mut self, dur: Duration) -> Self {
+ self += dur;
+ self
+ }
+}
+
+impl ops::SubAssign<Duration> for Instant {
+ fn sub_assign(&mut self, dur: Duration) {
+ // XXX should this be a non-debug assertion?
+ debug_assert!(dur.inner < (1 << 31));
+ self.inner = self.inner.wrapping_sub(dur.inner as i32);
+ }
+}
+
+impl ops::Sub<Duration> for Instant {
+ type Output = Self;
+
+ fn sub(mut self, dur: Duration) -> Self {
+ self -= dur;
+ self
+ }
+}
+
+impl ops::Sub<Instant> for Instant {
+ type Output = Duration;
+
+ fn sub(self, other: Instant) -> Duration {
+ self.duration_since(other)
+ }
+}
+
+impl Ord for Instant {
+ fn cmp(&self, rhs: &Self) -> Ordering {
+ self.inner.wrapping_sub(rhs.inner).cmp(&0)
+ }
+}
+
+impl PartialOrd for Instant {
+ fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
+ Some(self.cmp(rhs))
+ }
+}
+
+/// A `Duration` type to represent a span of time.
+///
+/// This data type is only available on ARMv7-M
+#[derive(Clone, Copy, Default, Eq, Ord, PartialEq, PartialOrd)]
+pub struct Duration {
+ inner: u32,
+}
+
+impl Duration {
+ /// Returns the total number of clock cycles contained by this `Duration`
+ pub fn as_cycles(&self) -> u32 {
+ self.inner
+ }
+}
+
+impl TryInto<u32> for Duration {
+ type Error = Infallible;
+
+ fn try_into(self) -> Result<u32, Infallible> {
+ Ok(self.as_cycles())
+ }
+}
+
+impl ops::AddAssign for Duration {
+ fn add_assign(&mut self, dur: Duration) {
+ self.inner += dur.inner;
+ }
+}
+
+impl ops::Add<Duration> for Duration {
+ type Output = Self;
+
+ fn add(self, other: Self) -> Self {
+ Duration {
+ inner: self.inner + other.inner,
+ }
+ }
+}
+
+impl ops::SubAssign for Duration {
+ fn sub_assign(&mut self, rhs: Duration) {
+ self.inner -= rhs.inner;
+ }
+}
+
+impl ops::Sub<Duration> for Duration {
+ type Output = Self;
+
+ fn sub(self, rhs: Self) -> Self {
+ Duration {
+ inner: self.inner - rhs.inner,
+ }
+ }
+}
+
+/// Adds the `cycles` method to the `u32` type
+///
+/// This trait is only available on ARMv7-M
+pub trait U32Ext {
+ /// Converts the `u32` value into clock cycles
+ fn cycles(self) -> Duration;
+}
+
+impl U32Ext for u32 {
+ fn cycles(self) -> Duration {
+ Duration { inner: self }
+ }
+}
+
+/// Implementation of the `Monotonic` trait based on CYCle CouNTer
+#[cfg(not(feature = "heterogeneous"))]
+pub struct CYCCNT;
+
+#[cfg(not(feature = "heterogeneous"))]
+unsafe impl crate::Monotonic for CYCCNT {
+ type Instant = Instant;
+
+ fn ratio() -> u32 {
+ 1
+ }
+
+ unsafe fn reset() {
+ (0xE0001004 as *mut u32).write_volatile(0)
+ }
+
+ fn now() -> Instant {
+ Instant::now()
+ }
+
+ fn zero() -> Instant {
+ Instant {
+ inner: 0,
+ _not_send_or_sync: PhantomData,
+ }
+ }
+}
diff --git a/src/export.rs b/src/export.rs
index afed9091..7646e3c5 100644
--- a/src/export.rs
+++ b/src/export.rs
@@ -1,21 +1,27 @@
-//! IMPLEMENTATION DETAILS. DO NOT USE ANYTHING IN THIS MODULE
-
-use core::{cell::Cell, u8};
+use core::{
+ cell::Cell,
+ sync::atomic::{AtomicBool, Ordering},
+};
+pub use crate::tq::{NotReady, TimerQueue};
#[cfg(armv7m)]
-use cortex_m::register::basepri;
+pub use cortex_m::register::basepri;
pub use cortex_m::{
- asm::wfi, interrupt, peripheral::scb::SystemHandler, peripheral::syst::SystClkSource,
- peripheral::Peripherals,
+ asm::wfi,
+ interrupt,
+ peripheral::{scb::SystemHandler, syst::SystClkSource, DWT},
+ Peripherals,
};
-use heapless::spsc::SingleCore;
-pub use heapless::{consts, i, spsc::Queue};
-
-#[cfg(feature = "timer-queue")]
-pub use crate::tq::{NotReady, TimerQueue};
+use heapless::spsc::{MultiCore, SingleCore};
+pub use heapless::{consts, i::Queue as iQueue, spsc::Queue};
+pub use heapless::{i::BinaryHeap as iBinaryHeap, BinaryHeap};
+#[cfg(feature = "heterogeneous")]
+pub use microamp::shared;
-pub type FreeQueue<N> = Queue<u8, N, u8, SingleCore>;
-pub type ReadyQueue<T, N> = Queue<(T, u8), N, u8, SingleCore>;
+pub type MCFQ<N> = Queue<u8, N, u8, MultiCore>;
+pub type MCRQ<T, N> = Queue<(T, u8), N, u8, MultiCore>;
+pub type SCFQ<N> = Queue<u8, N, u8, SingleCore>;
+pub type SCRQ<T, N> = Queue<(T, u8), N, u8, SingleCore>;
#[cfg(armv7m)]
#[inline(always)]
@@ -43,6 +49,26 @@ where
f();
}
+pub struct Barrier {
+ inner: AtomicBool,
+}
+
+impl Barrier {
+ pub const fn new() -> Self {
+ Barrier {
+ inner: AtomicBool::new(false),
+ }
+ }
+
+ pub fn release(&self) {
+ self.inner.store(true, Ordering::Release)
+ }
+
+ pub fn wait(&self) {
+ while !self.inner.load(Ordering::Acquire) {}
+ }
+}
+
// Newtype over `Cell` that forbids mutation through a shared reference
pub struct Priority {
inner: Cell<u8>,
@@ -95,7 +121,7 @@ pub unsafe fn lock<T, R>(
if current < ceiling {
if ceiling == (1 << nvic_prio_bits) {
- priority.set(u8::MAX);
+ priority.set(u8::max_value());
let r = interrupt::free(|_| f(&mut *ptr));
priority.set(current);
r
@@ -124,7 +150,7 @@ pub unsafe fn lock<T, R>(
let current = priority.get();
if current < ceiling {
- priority.set(u8::MAX);
+ priority.set(u8::max_value());
let r = interrupt::free(|_| f(&mut *ptr));
priority.set(current);
r
diff --git a/src/lib.rs b/src/lib.rs
index 1fe88c47..73e6e200 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -33,68 +33,45 @@
//!
//! # Cargo features
//!
-//! - `timer-queue`. This opt-in feature enables the `schedule` API which can be used to schedule
-//! tasks to run in the future. Also see [`Instant`] and [`Duration`].
-//!
-//! [`Instant`]: struct.Instant.html
-//! [`Duration`]: struct.Duration.html
-//!
-//! - `nightly`. Enabling this opt-in feature makes RTFM internally use the unstable `const_fn`
-//! language feature to reduce static memory usage, runtime overhead and initialization overhead.
-//! This feature requires a nightly compiler and may stop working at any time!
+//! - `heterogeneous`. This opt-in feature enables the *experimental* heterogeneous multi-core support.
#![deny(missing_docs)]
+#![deny(rust_2018_compatibility)]
+#![deny(rust_2018_idioms)]
#![deny(warnings)]
#![no_std]
-#[cfg(feature = "timer-queue")]
-use core::cmp::Ordering;
-use core::{fmt, ops};
+use core::ops::Sub;
-#[cfg(not(feature = "timer-queue"))]
-use cortex_m::peripheral::SYST;
use cortex_m::{
interrupt::Nr,
peripheral::{CBP, CPUID, DCB, DWT, FPB, FPU, ITM, MPU, NVIC, SCB, TPIU},
};
+#[cfg(not(feature = "heterogeneous"))]
+use cortex_m_rt as _; // vector table
pub use cortex_m_rtfm_macros::app;
+pub use rtfm_core::{Exclusive, Mutex};
+#[cfg(armv7m)]
+pub mod cyccnt;
#[doc(hidden)]
pub mod export;
#[doc(hidden)]
-#[cfg(feature = "timer-queue")]
mod tq;
-#[cfg(all(feature = "timer-queue", armv6m))]
-compile_error!(
- "The `timer-queue` feature is currently not supported on ARMv6-M (`thumbv6m-none-eabi`)"
-);
-
-/// Core peripherals
-///
-/// This is `cortex_m::Peripherals` minus the peripherals that the RTFM runtime uses
-///
-/// - The `NVIC` field is never present.
-/// - When the `timer-queue` feature is enabled the following fields are *not* present: `DWT` and
-/// `SYST`.
+/// `cortex_m::Peripherals` minus `SYST`
#[allow(non_snake_case)]
-pub struct Peripherals<'a> {
+pub struct Peripherals {
/// Cache and branch predictor maintenance operations (not present on Cortex-M0 variants)
pub CBP: CBP,
/// CPUID
pub CPUID: CPUID,
- /// Debug Control Block (by value if the `timer-queue` feature is disabled)
- #[cfg(feature = "timer-queue")]
- pub DCB: &'a mut DCB,
-
- /// Debug Control Block (borrowed if the `timer-queue` feature is enabled)
- #[cfg(not(feature = "timer-queue"))]
+ /// Debug Control Block
pub DCB: DCB,
- /// Data Watchpoint and Trace unit (not present if the `timer-queue` feature is enabled)
- #[cfg(not(feature = "timer-queue"))]
+ /// Data Watchpoint and Trace unit
pub DWT: DWT,
/// Flash Patch and Breakpoint unit (not present on Cortex-M0 variants)
@@ -109,245 +86,52 @@ pub struct Peripherals<'a> {
/// Memory Protection Unit
pub MPU: MPU,
- // Nested Vector Interrupt Controller
- // pub NVIC: NVIC,
- /// System Control Block
- pub SCB: &'a mut SCB,
+ /// Nested Vector Interrupt Controller
+ pub NVIC: NVIC,
- /// SysTick: System Timer (not present if the `timer-queue` is enabled)
- #[cfg(not(feature = "timer-queue"))]
- pub SYST: SYST,
+ /// System Control Block
+ pub SCB: SCB,
+ // SysTick: System Timer
+ // pub SYST: SYST,
/// Trace Port Interface Unit (not present on Cortex-M0 variants)
pub TPIU: TPIU,
}
-/// A measurement of a monotonically nondecreasing clock. Opaque and useful only with `Duration`
-///
-/// This data type is only available when the `timer-queue` feature is enabled
-#[derive(Clone, Copy, Debug, Eq, PartialEq)]
-#[cfg(feature = "timer-queue")]
-pub struct Instant(i32);
-
-#[cfg(feature = "timer-queue")]
-impl Instant {
- /// IMPLEMENTATION DETAIL. DO NOT USE
- #[doc(hidden)]
- pub unsafe fn artificial(timestamp: i32) -> Self {
- Instant(timestamp)
- }
-
- /// Returns an instant corresponding to "now"
- pub fn now() -> Self {
- Instant(DWT::get_cycle_count() as i32)
- }
-
- /// Returns the amount of time elapsed since this instant was created.
- pub fn elapsed(&self) -> Duration {
- Instant::now() - *self
- }
-
- /// Returns the amount of time elapsed from another instant to this one.
- pub fn duration_since(&self, earlier: Instant) -> Duration {
- let diff = self.0 - earlier.0;
- assert!(diff >= 0, "second instant is later than self");
- Duration(diff as u32)
- }
-}
-
-#[cfg(feature = "timer-queue")]
-impl ops::AddAssign<Duration> for Instant {
- fn add_assign(&mut self, dur: Duration) {
- debug_assert!(dur.0 < (1 << 31));
- self.0 = self.0.wrapping_add(dur.0 as i32);
+impl From<cortex_m::Peripherals> for Peripherals {
+ fn from(p: cortex_m::Peripherals) -> Self {
+ Self {
+ CBP: p.CBP,
+ CPUID: p.CPUID,
+ DCB: p.DCB,
+ DWT: p.DWT,
+ FPB: p.FPB,
+ FPU: p.FPU,
+ ITM: p.ITM,
+ MPU: p.MPU,
+ NVIC: p.NVIC,
+ SCB: p.SCB,
+ TPIU: p.TPIU,
+ }
}
}
-#[cfg(feature = "timer-queue")]
-impl ops::Add<Duration> for Instant {
- type Output = Self;
+/// A monotonic clock / counter
+pub unsafe trait Monotonic {
+ /// A measurement of this clock
+ type Instant: Copy + Ord + Sub;
- fn add(mut self, dur: Duration) -> Self {
- self += dur;
- self
- }
-}
+ /// The ratio between the SysTick (system timer) frequency and this clock frequency
+ fn ratio() -> u32;
-#[cfg(feature = "timer-queue")]
-impl ops::SubAssign<Duration> for Instant {
- fn sub_assign(&mut self, dur: Duration) {
- // XXX should this be a non-debug assertion?
- debug_assert!(dur.0 < (1 << 31));
- self.0 = self.0.wrapping_sub(dur.0 as i32);
- }
-}
+ /// Returns the current time
+ fn now() -> Self::Instant;
-#[cfg(feature = "timer-queue")]
-impl ops::Sub<Duration> for Instant {
- type Output = Self;
+ /// Resets the counter to *zero*
+ unsafe fn reset();
- fn sub(mut self, dur: Duration) -> Self {
- self -= dur;
- self
- }
-}
-
-#[cfg(feature = "timer-queue")]
-impl ops::Sub<Instant> for Instant {
- type Output = Duration;
-
- fn sub(self, other: Instant) -> Duration {
- self.duration_since(other)
- }
-}
-
-#[cfg(feature = "timer-queue")]
-impl Ord for Instant {
- fn cmp(&self, rhs: &Self) -> Ordering {
- self.0.wrapping_sub(rhs.0).cmp(&0)
- }
-}
-
-#[cfg(feature = "timer-queue")]
-impl PartialOrd for Instant {
- fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
- Some(self.cmp(rhs))
- }
-}
-
-/// A `Duration` type to represent a span of time.
-///
-/// This data type is only available when the `timer-queue` feature is enabled
-#[derive(Clone, Copy, Default, Eq, Ord, PartialEq, PartialOrd)]
-#[cfg(feature = "timer-queue")]
-pub struct Duration(u32);
-
-#[cfg(feature = "timer-queue")]
-impl Duration {
- /// Returns the total number of clock cycles contained by this `Duration`
- pub fn as_cycles(&self) -> u32 {
- self.0
- }
-}
-
-#[cfg(feature = "timer-queue")]
-impl ops::AddAssign for Duration {
- fn add_assign(&mut self, dur: Duration) {
- self.0 += dur.0;
- }
-}
-
-#[cfg(feature = "timer-queue")]
-impl ops::Add<Duration> for Duration {
- type Output = Self;
-
- fn add(self, other: Self) -> Self {
- Duration(self.0 + other.0)
- }
-}
-
-#[cfg(feature = "timer-queue")]
-impl ops::SubAssign for Duration {
- fn sub_assign(&mut self, rhs: Duration) {
- self.0 -= rhs.0;
- }
-}
-
-#[cfg(feature = "timer-queue")]
-impl ops::Sub<Duration> for Duration {
- type Output = Self;
-
- fn sub(self, rhs: Self) -> Self {
- Duration(self.0 - rhs.0)
- }
-}
-
-/// Adds the `cycles` method to the `u32` type
-///
-/// This trait is only available when the `timer-queue` feature is enabled
-#[cfg(feature = "timer-queue")]
-pub trait U32Ext {
- /// Converts the `u32` value into clock cycles
- fn cycles(self) -> Duration;
-}
-
-#[cfg(feature = "timer-queue")]
-impl U32Ext for u32 {
- fn cycles(self) -> Duration {
- Duration(self)
- }
-}
-
-/// Memory safe access to shared resources
-///
-/// In RTFM, locks are implemented as critical sections that prevent other tasks from *starting*.
-/// These critical sections are implemented by temporarily increasing the dynamic priority (see
-/// [BASEPRI]) of the current context. Entering and leaving these critical sections is always done
-/// in constant time (a few instructions).
-///
-/// [BASEPRI]: https://developer.arm.com/products/architecture/cpu-architecture/m-profile/docs/100701/latest/special-purpose-mask-registers
-pub trait Mutex {
- /// Data protected by the mutex
- type T;
-
- /// Creates a critical section and grants temporary access to the protected data
- fn lock<R>(&mut self, f: impl FnOnce(&mut Self::T) -> R) -> R;
-}
-
-impl<'a, M> Mutex for &'a mut M
-where
- M: Mutex,
-{
- type T = M::T;
-
- fn lock<R>(&mut self, f: impl FnOnce(&mut M::T) -> R) -> R {
- (**self).lock(f)
- }
-}
-
-/// Newtype over `&'a mut T` that implements the `Mutex` trait
-///
-/// The `Mutex` implementation for this type is a no-op, no critical section is created
-pub struct Exclusive<'a, T>(pub &'a mut T);
-
-impl<'a, T> Mutex for Exclusive<'a, T> {
- type T = T;
-
- fn lock<R>(&mut self, f: impl FnOnce(&mut T) -> R) -> R {
- f(self.0)
- }
-}
-
-impl<'a, T> fmt::Debug for Exclusive<'a, T>
-where
- T: fmt::Debug,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- (**self).fmt(f)
- }
-}
-
-impl<'a, T> fmt::Display for Exclusive<'a, T>
-where
- T: fmt::Display,
-{
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- (**self).fmt(f)
- }
-}
-
-impl<'a, T> ops::Deref for Exclusive<'a, T> {
- type Target = T;
-
- fn deref(&self) -> &T {
- self.0
- }
-}
-
-impl<'a, T> ops::DerefMut for Exclusive<'a, T> {
- fn deref_mut(&mut self) -> &mut T {
- self.0
- }
+ /// A `Self::Instant` that represents a count of *zero*
+ fn zero() -> Self::Instant;
}
/// Sets the given `interrupt` as pending
diff --git a/src/tq.rs b/src/tq.rs
index 8ca1bd3f..4f9b6e7e 100644
--- a/src/tq.rs
+++ b/src/tq.rs
@@ -1,36 +1,34 @@
-use core::cmp::{self, Ordering};
+use core::{
+ cmp::{self, Ordering},
+ convert::TryInto,
+ mem,
+ ops::Sub,
+};
use cortex_m::peripheral::{SCB, SYST};
use heapless::{binary_heap::Min, ArrayLength, BinaryHeap};
-use crate::Instant;
+use crate::Monotonic;
-pub struct TimerQueue<T, N>
+pub struct TimerQueue<M, T, N>(pub BinaryHeap<NotReady<M, T>, N, Min>)
where
- N: ArrayLength<NotReady<T>>,
- T: Copy,
-{
- pub syst: SYST,
- pub queue: BinaryHeap<NotReady<T>, N, Min>,
-}
+ M: Monotonic,
+ <M::Instant as Sub>::Output: TryInto<u32>,
+ N: ArrayLength<NotReady<M, T>>,
+ T: Copy;
-impl<T, N> TimerQueue<T, N>
+impl<M, T, N> TimerQueue<M, T, N>
where
- N: ArrayLength<NotReady<T>>,
+ M: Monotonic,
+ <M::Instant as Sub>::Output: TryInto<u32>,
+ N: ArrayLength<NotReady<M, T>>,
T: Copy,
{
- pub fn new(syst: SYST) -> Self {
- TimerQueue {
- syst,
- queue: BinaryHeap::new(),
- }
- }
-
#[inline]
- pub unsafe fn enqueue_unchecked(&mut self, nr: NotReady<T>) {
+ pub unsafe fn enqueue_unchecked(&mut self, nr: NotReady<M, T>) {
let mut is_empty = true;
if self
- .queue
+ .0
.peek()
.map(|head| {
is_empty = false;
@@ -39,77 +37,102 @@ where
.unwrap_or(true)
{
if is_empty {
- self.syst.enable_interrupt();
+ mem::transmute::<_, SYST>(()).enable_interrupt();
}
// set SysTick pending
SCB::set_pendst();
}
- self.queue.push_unchecked(nr);
+ self.0.push_unchecked(nr);
}
#[inline]
pub fn dequeue(&mut self) -> Option<(T, u8)> {
- if let Some(instant) = self.queue.peek().map(|p| p.instant) {
- let diff = instant.0.wrapping_sub(Instant::now().0);
-
- if diff < 0 {
- // task became ready
- let nr = unsafe { self.queue.pop_unchecked() };
-
- Some((nr.task, nr.index))
+ unsafe {
+ if let Some(instant) = self.0.peek().map(|p| p.instant) {
+ let now = M::now();
+
+ if instant < now {
+ // task became ready
+ let nr = self.0.pop_unchecked();
+
+ Some((nr.task, nr.index))
+ } else {
+ // set a new timeout
+ const MAX: u32 = 0x00ffffff;
+
+ let dur = match (instant - now)
+ .try_into()
+ .ok()
+ .and_then(|x| x.checked_mul(M::ratio()))
+ {
+ None => MAX,
+ Some(x) => cmp::min(MAX, x),
+ };
+ mem::transmute::<_, SYST>(()).set_reload(dur);
+
+ // start counting down from the new reload
+ mem::transmute::<_, SYST>(()).clear_current();
+
+ None
+ }
} else {
- // set a new timeout
- const MAX: u32 = 0x00ffffff;
-
- self.syst.set_reload(cmp::min(MAX, diff as u32));
-
- // start counting down from the new reload
- self.syst.clear_current();
+ // the queue is empty
+ mem::transmute::<_, SYST>(()).disable_interrupt();
None
}
- } else {
- // the queue is empty
- self.syst.disable_interrupt();
- None
}
}
}
-pub struct NotReady<T>
+pub struct NotReady<M, T>
where
T: Copy,
+ M: Monotonic,
+ <M::Instant as Sub>::Output: TryInto<u32>,
{
pub index: u8,
- pub instant: Instant,
+ pub instant: M::Instant,
pub task: T,
}
-impl<T> Eq for NotReady<T> where T: Copy {}
+impl<M, T> Eq for NotReady<M, T>
+where
+ T: Copy,
+ M: Monotonic,
+ <M::Instant as Sub>::Output: TryInto<u32>,
+{
+}
-impl<T> Ord for NotReady<T>
+impl<M, T> Ord for NotReady<M, T>
where
T: Copy,
+ M: Monotonic,
+ <M::Instant as Sub>::Output: TryInto<u32>,
{
fn cmp(&self, other: &Self) -> Ordering {
self.instant.cmp(&other.instant)
}
}
-impl<T> PartialEq for NotReady<T>
+impl<M, T> PartialEq for NotReady<M, T>
where
T: Copy,
+ M: Monotonic,
+ <M::Instant as Sub>::Output: TryInto<u32>,
{
fn eq(&self, other: &Self) -> bool {
self.instant == other.instant
}
}
-impl<T> PartialOrd for NotReady<T>
+impl<M, T> PartialOrd for NotReady<M, T>
where
T: Copy,
+ M: Monotonic,
+ <M::Instant as Sub>::Output: TryInto<u32>,
{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(&other))