mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-23 20:22:51 +01:00
Added interface for cancel/reschedule
Use wrapping add for marker No need to store handle to queue Remove unnecessary `SpawnHandle::new` Fix test Updated interface to follow proposal
This commit is contained in:
parent
4bdc187912
commit
1087f2ee64
6 changed files with 108 additions and 249 deletions
|
@ -26,18 +26,29 @@ mod app {
|
||||||
|
|
||||||
let mono = DwtSystick::new(&mut dcb, dwt, systick, 8_000_000);
|
let mono = DwtSystick::new(&mut dcb, dwt, systick, 8_000_000);
|
||||||
|
|
||||||
let _: Result<(), ()> = foo::spawn_after(Seconds(1_u32));
|
let a: Result<foo::MyMono::SpawnHandle, ()> = foo::spawn_after(Seconds(1_u32));
|
||||||
let _: Result<(), u32> = bar::spawn_after(Seconds(2_u32), 0);
|
if let Ok(handle) = a {
|
||||||
let _: Result<(), (u32, u32)> = baz::spawn_after(Seconds(3_u32), 0, 1);
|
let _: Result<foo::MyMono::SpawnHandle, ()> = handle.reschedule_after(Seconds(1_u32));
|
||||||
|
}
|
||||||
|
|
||||||
|
let b: Result<bar::MyMono::SpawnHandle, u32> = bar::spawn_after(Seconds(2_u32), 0);
|
||||||
|
if let Ok(handle) = b {
|
||||||
|
let _: Result<u32, ()> = handle.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
let _: Result<baz::MyMono::SpawnHandle, (u32, u32)> =
|
||||||
|
baz::spawn_after(Seconds(3_u32), 0, 1);
|
||||||
|
|
||||||
(init::LateResources {}, init::Monotonics(mono))
|
(init::LateResources {}, init::Monotonics(mono))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[idle]
|
#[idle]
|
||||||
fn idle(_: idle::Context) -> ! {
|
fn idle(_: idle::Context) -> ! {
|
||||||
let _: Result<(), ()> = foo::spawn_at(MyMono::now() + Seconds(3_u32));
|
let _: Result<foo::MyMono::SpawnHandle, ()> = foo::spawn_at(MyMono::now() + Seconds(3_u32));
|
||||||
let _: Result<(), u32> = bar::spawn_at(MyMono::now() + Seconds(4_u32), 0);
|
let _: Result<bar::MyMono::SpawnHandle, u32> =
|
||||||
let _: Result<(), (u32, u32)> = baz::spawn_at(MyMono::now() + Seconds(5_u32), 0, 1);
|
bar::spawn_at(MyMono::now() + Seconds(4_u32), 0);
|
||||||
|
let _: Result<baz::MyMono::SpawnHandle, (u32, u32)> =
|
||||||
|
baz::spawn_at(MyMono::now() + Seconds(5_u32), 0, 1);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
cortex_m::asm::nop();
|
cortex_m::asm::nop();
|
||||||
|
|
|
@ -264,15 +264,64 @@ pub fn codegen(
|
||||||
};
|
};
|
||||||
|
|
||||||
let user_imports = &app.user_imports;
|
let user_imports = &app.user_imports;
|
||||||
|
let tq_marker = util::mark_internal_ident(&util::timer_queue_marker_ident());
|
||||||
|
|
||||||
items.push(quote!(
|
items.push(quote!(
|
||||||
/// Holds methods related to this monotonic
|
/// Holds methods related to this monotonic
|
||||||
pub mod #m {
|
pub mod #m {
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use #app_path::#tq_marker;
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use #app_path::#t;
|
||||||
#(
|
#(
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
#user_imports
|
#user_imports
|
||||||
)*
|
)*
|
||||||
|
|
||||||
|
pub struct SpawnHandle {
|
||||||
|
#[doc(hidden)]
|
||||||
|
marker: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: remove
|
||||||
|
impl core::fmt::Debug for SpawnHandle
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
|
let handle = unsafe { &#app_path::#tq as *const _ as u32 };
|
||||||
|
f.debug_struct("SpawnHandle")
|
||||||
|
.field("marker", &self.marker)
|
||||||
|
.field("handle", &handle)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SpawnHandle {
|
||||||
|
pub fn cancel(self) -> Result<#ty, ()> {
|
||||||
|
// TODO: Actually cancel...
|
||||||
|
// &mut #app_path::#tq;
|
||||||
|
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn reschedule_after<D>(self, duration: D) -> Result<Self, ()>
|
||||||
|
where D: rtic::time::duration::Duration + rtic::time::fixed_point::FixedPoint,
|
||||||
|
D::T: Into<<#app_path::#mono_type as rtic::time::Clock>::T>,
|
||||||
|
{
|
||||||
|
self.reschedule_at(#app_path::#m::now() + duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reschedule_at(self, instant: rtic::time::Instant<#app_path::#mono_type>) -> Result<Self, ()>
|
||||||
|
{
|
||||||
|
let _ = instant;
|
||||||
|
|
||||||
|
// TODO: Actually reschedule...
|
||||||
|
// &mut #app_path::#tq;
|
||||||
|
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#(#cfgs)*
|
#(#cfgs)*
|
||||||
/// Spawns the task after a set duration relative to the current time
|
/// Spawns the task after a set duration relative to the current time
|
||||||
///
|
///
|
||||||
|
@ -281,7 +330,7 @@ pub fn codegen(
|
||||||
pub fn spawn_after<D>(
|
pub fn spawn_after<D>(
|
||||||
duration: D
|
duration: D
|
||||||
#(,#args)*
|
#(,#args)*
|
||||||
) -> Result<(), #ty>
|
) -> Result<SpawnHandle, #ty>
|
||||||
where D: rtic::time::duration::Duration + rtic::time::fixed_point::FixedPoint,
|
where D: rtic::time::duration::Duration + rtic::time::fixed_point::FixedPoint,
|
||||||
D::T: Into<<#app_path::#mono_type as rtic::time::Clock>::T>,
|
D::T: Into<<#app_path::#mono_type as rtic::time::Clock>::T>,
|
||||||
{
|
{
|
||||||
|
@ -300,7 +349,7 @@ pub fn codegen(
|
||||||
pub fn spawn_at(
|
pub fn spawn_at(
|
||||||
instant: rtic::time::Instant<#app_path::#mono_type>
|
instant: rtic::time::Instant<#app_path::#mono_type>
|
||||||
#(,#args)*
|
#(,#args)*
|
||||||
) -> Result<(), #ty> {
|
) -> Result<SpawnHandle, #ty> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let input = #tupled;
|
let input = #tupled;
|
||||||
if let Some(index) = rtic::export::interrupt::free(|_| #app_path::#fq.dequeue()) {
|
if let Some(index) = rtic::export::interrupt::free(|_| #app_path::#fq.dequeue()) {
|
||||||
|
@ -314,13 +363,17 @@ pub fn codegen(
|
||||||
.as_mut_ptr()
|
.as_mut_ptr()
|
||||||
.write(instant);
|
.write(instant);
|
||||||
|
|
||||||
|
rtic::export::interrupt::free(|_| {
|
||||||
|
let marker = #tq_marker;
|
||||||
let nr = rtic::export::NotReady {
|
let nr = rtic::export::NotReady {
|
||||||
instant,
|
instant,
|
||||||
index,
|
index,
|
||||||
task: #app_path::#t::#name,
|
task: #app_path::#t::#name,
|
||||||
|
marker,
|
||||||
};
|
};
|
||||||
|
|
||||||
rtic::export::interrupt::free(|_|
|
#tq_marker = #tq_marker.wrapping_add(1);
|
||||||
|
|
||||||
if let Some(mono) = #app_path::#m_ident.as_mut() {
|
if let Some(mono) = #app_path::#m_ident.as_mut() {
|
||||||
#app_path::#tq.enqueue_unchecked(
|
#app_path::#tq.enqueue_unchecked(
|
||||||
nr,
|
nr,
|
||||||
|
@ -331,9 +384,10 @@ pub fn codegen(
|
||||||
// We can only use the timer queue if `init` has returned, and it
|
// We can only use the timer queue if `init` has returned, and it
|
||||||
// writes the `Some(monotonic)` we are accessing here.
|
// writes the `Some(monotonic)` we are accessing here.
|
||||||
core::hint::unreachable_unchecked()
|
core::hint::unreachable_unchecked()
|
||||||
});
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(SpawnHandle { marker })
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(input)
|
Err(input)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,15 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
|
||||||
let mut items = vec![];
|
let mut items = vec![];
|
||||||
|
|
||||||
if !app.monotonics.is_empty() {
|
if !app.monotonics.is_empty() {
|
||||||
|
// Generate the marker counter used to track for `cancel` and `reschedule`
|
||||||
|
let tq_marker = util::mark_internal_ident(&util::timer_queue_marker_ident());
|
||||||
|
items.push(quote!(
|
||||||
|
// #[doc = #doc]
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
static mut #tq_marker: u32 = 0;
|
||||||
|
));
|
||||||
|
|
||||||
let t = util::schedule_t_ident();
|
let t = util::schedule_t_ident();
|
||||||
|
|
||||||
// Enumeration of `schedule`-able tasks
|
// Enumeration of `schedule`-able tasks
|
||||||
|
@ -32,7 +41,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
enum #t {
|
pub enum #t {
|
||||||
#(#variants,)*
|
#(#variants,)*
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
|
@ -89,6 +89,11 @@ pub fn interrupt_ident() -> Ident {
|
||||||
Ident::new("interrupt", span)
|
Ident::new("interrupt", span)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn timer_queue_marker_ident() -> Ident {
|
||||||
|
let span = Span::call_site();
|
||||||
|
Ident::new("TIMER_QUEUE_MARKER", span)
|
||||||
|
}
|
||||||
|
|
||||||
/// Whether `name` is an exception with configurable priority
|
/// Whether `name` is an exception with configurable priority
|
||||||
pub fn is_exception(name: &Ident) -> bool {
|
pub fn is_exception(name: &Ident) -> bool {
|
||||||
let s = name.to_string();
|
let s = name.to_string();
|
||||||
|
|
221
src/cyccnt.rs
221
src/cyccnt.rs
|
@ -1,221 +0,0 @@
|
||||||
//! Data Watchpoint Trace (DWT) unit's CYCle CouNTer (CYCCNT)
|
|
||||||
|
|
||||||
use core::{
|
|
||||||
cmp::Ordering,
|
|
||||||
convert::{Infallible, TryInto},
|
|
||||||
fmt, ops,
|
|
||||||
};
|
|
||||||
|
|
||||||
use cortex_m::peripheral::DWT;
|
|
||||||
|
|
||||||
use crate::Fraction;
|
|
||||||
|
|
||||||
/// A measurement of the CYCCNT. Opaque and useful only with `Duration`
|
|
||||||
///
|
|
||||||
/// This data type is only available on ARMv7-M
|
|
||||||
///
|
|
||||||
/// # Correctness
|
|
||||||
///
|
|
||||||
/// Adding or subtracting a `Duration` of more than `(1 << 31)` cycles to an `Instant` effectively
|
|
||||||
/// makes it "wrap around" and creates an incorrect value. This is also true if the operation is
|
|
||||||
/// done in steps, e.g. `(instant + dur) + dur` where `dur` is `(1 << 30)` ticks.
|
|
||||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
|
||||||
pub struct Instant {
|
|
||||||
inner: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Instant {
|
|
||||||
/// Returns an instant corresponding to "now"
|
|
||||||
///
|
|
||||||
/// *HEADS UP* this function can, and will, return nonsensical values if called within `init`.
|
|
||||||
/// Only use it in `idle` and tasks. In `init`, use the `init::Context.start` field, or the
|
|
||||||
/// `CYCCNT::zero` function, instead of this function
|
|
||||||
pub fn now() -> Self {
|
|
||||||
Instant {
|
|
||||||
inner: DWT::get_cycle_count() as i32,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the amount of time elapsed since this instant was created.
|
|
||||||
pub fn elapsed(&self) -> Duration {
|
|
||||||
let diff = Instant::now().inner.wrapping_sub(self.inner);
|
|
||||||
assert!(diff >= 0, "instant now is earlier than self");
|
|
||||||
Duration { inner: diff as u32 }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the amount of time elapsed from another instant to this one.
|
|
||||||
pub fn duration_since(&self, earlier: Instant) -> Duration {
|
|
||||||
let diff = self.inner.wrapping_sub(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) {
|
|
||||||
// NOTE this is a debug assertion because there's no foolproof way to detect a wrap around;
|
|
||||||
// the user may write `(instant + dur) + dur` where `dur` is `(1<<31)-1` ticks.
|
|
||||||
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) {
|
|
||||||
// NOTE see the NOTE in `<Instant as AddAssign<Duration>>::add_assign`
|
|
||||||
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
|
|
||||||
///
|
|
||||||
/// # Correctness
|
|
||||||
///
|
|
||||||
/// This type is *not* appropriate for representing time spans in the order of, or larger than,
|
|
||||||
/// seconds because it can hold a maximum of `(1 << 31)` "ticks" where each tick is the inverse of
|
|
||||||
/// the CPU frequency, which usually is dozens of MHz.
|
|
||||||
#[derive(Clone, Copy, Default, Eq, Ord, PartialEq, PartialOrd)]
|
|
||||||
pub struct Duration {
|
|
||||||
inner: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Duration {
|
|
||||||
/// Creates a new `Duration` from the specified number of clock cycles
|
|
||||||
pub fn from_cycles(cycles: u32) -> Self {
|
|
||||||
Duration { inner: cycles }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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
|
|
||||||
pub struct CYCCNT;
|
|
||||||
|
|
||||||
impl crate::Monotonic for CYCCNT {
|
|
||||||
type Instant = Instant;
|
|
||||||
|
|
||||||
fn ratio() -> Fraction {
|
|
||||||
Fraction {
|
|
||||||
numerator: 1,
|
|
||||||
denominator: 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn reset() {
|
|
||||||
(0xE0001004 as *mut u32).write_volatile(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn now() -> Instant {
|
|
||||||
Instant::now()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn zero() -> Instant {
|
|
||||||
Instant { inner: 0 }
|
|
||||||
}
|
|
||||||
}
|
|
23
src/tq.rs
23
src/tq.rs
|
@ -5,6 +5,15 @@ use crate::{
|
||||||
use core::cmp::Ordering;
|
use core::cmp::Ordering;
|
||||||
use heapless::{binary_heap::Min, ArrayLength, BinaryHeap};
|
use heapless::{binary_heap::Min, ArrayLength, BinaryHeap};
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn unwrapper<T, E>(val: Result<T, E>) -> T {
|
||||||
|
if let Ok(v) = val {
|
||||||
|
v
|
||||||
|
} else {
|
||||||
|
unreachable!("Your monotonic is not infallible")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct TimerQueue<Mono, Task, N>(pub BinaryHeap<NotReady<Mono, Task>, N, Min>)
|
pub struct TimerQueue<Mono, Task, N>(pub BinaryHeap<NotReady<Mono, Task>, N, Min>)
|
||||||
where
|
where
|
||||||
Mono: Monotonic,
|
Mono: Monotonic,
|
||||||
|
@ -66,15 +75,6 @@ where
|
||||||
self.0.is_empty()
|
self.0.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn unwrapper<T, E>(val: Result<T, E>) -> T {
|
|
||||||
if let Ok(v) = val {
|
|
||||||
v
|
|
||||||
} else {
|
|
||||||
unreachable!("Your monotonic is not infallible")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Dequeue a task from the TimerQueue
|
/// Dequeue a task from the TimerQueue
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn dequeue<F>(&mut self, disable_interrupt: F, mono: &mut Mono) -> Option<(Task, u8)>
|
pub fn dequeue<F>(&mut self, disable_interrupt: F, mono: &mut Mono) -> Option<(Task, u8)>
|
||||||
|
@ -84,7 +84,7 @@ where
|
||||||
mono.clear_compare_flag();
|
mono.clear_compare_flag();
|
||||||
|
|
||||||
if let Some(instant) = self.0.peek().map(|p| p.instant) {
|
if let Some(instant) = self.0.peek().map(|p| p.instant) {
|
||||||
if instant <= Self::unwrapper(Clock::try_now(mono)) {
|
if instant <= unwrapper(Clock::try_now(mono)) {
|
||||||
// task became ready
|
// task became ready
|
||||||
let nr = unsafe { self.0.pop_unchecked() };
|
let nr = unsafe { self.0.pop_unchecked() };
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ where
|
||||||
// dequeue. If the monotonic is fast enough it can happen that from the
|
// dequeue. If the monotonic is fast enough it can happen that from the
|
||||||
// read of now to the set of the compare, the time can overflow. This is to
|
// read of now to the set of the compare, the time can overflow. This is to
|
||||||
// guard against this.
|
// guard against this.
|
||||||
if instant <= Self::unwrapper(Clock::try_now(mono)) {
|
if instant <= unwrapper(Clock::try_now(mono)) {
|
||||||
let nr = unsafe { self.0.pop_unchecked() };
|
let nr = unsafe { self.0.pop_unchecked() };
|
||||||
|
|
||||||
Some((nr.task, nr.index))
|
Some((nr.task, nr.index))
|
||||||
|
@ -125,6 +125,7 @@ where
|
||||||
pub index: u8,
|
pub index: u8,
|
||||||
pub instant: Instant<Mono>,
|
pub instant: Instant<Mono>,
|
||||||
pub task: Task,
|
pub task: Task,
|
||||||
|
pub marker: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Mono, Task> Eq for NotReady<Mono, Task>
|
impl<Mono, Task> Eq for NotReady<Mono, Task>
|
||||||
|
|
Loading…
Reference in a new issue