mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-12-26 03:49:34 +01:00
Merge #464
464: const generics r=AfoHT a=burrbull Co-authored-by: Andrey Zgarbul <zgarbul.andrey@gmail.com> Co-authored-by: mriise <mark.riise26@gmail.com> Co-authored-by: Zgarbul Andrey <zgarbul.andrey@gmail.com>
This commit is contained in:
commit
78f556f942
12 changed files with 55 additions and 97 deletions
|
@ -44,9 +44,8 @@ cortex-m = "0.7.0"
|
||||||
cortex-m-rtic-macros = { path = "macros", version = "0.6.0-alpha.5" }
|
cortex-m-rtic-macros = { path = "macros", version = "0.6.0-alpha.5" }
|
||||||
rtic-monotonic = "0.1.0-alpha.2"
|
rtic-monotonic = "0.1.0-alpha.2"
|
||||||
rtic-core = "0.3.1"
|
rtic-core = "0.3.1"
|
||||||
heapless = "0.6.1"
|
heapless = "0.7.1"
|
||||||
bare-metal = "1.0.0"
|
bare-metal = "1.0.0"
|
||||||
generic-array = "0.14"
|
|
||||||
|
|
||||||
[dependencies.dwt-systick-monotonic]
|
[dependencies.dwt-systick-monotonic]
|
||||||
version = "0.1.0-alpha.3"
|
version = "0.1.0-alpha.3"
|
||||||
|
|
|
@ -78,8 +78,8 @@ mod app {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ready queue of the task dispatcher
|
// ready queue of the task dispatcher
|
||||||
// `U4` is a type-level integer that represents the capacity of this queue
|
// `5-1=4` represents the capacity of this queue
|
||||||
static mut RQ1: Queue<Ready<T1>, U4> = Queue::new();
|
static mut RQ1: Queue<Ready<T1>, 5> = Queue::new();
|
||||||
|
|
||||||
// interrupt handler chosen to dispatch tasks at priority `1`
|
// interrupt handler chosen to dispatch tasks at priority `1`
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -153,7 +153,7 @@ mod app {
|
||||||
// used to track how many more `bar` messages can be enqueued
|
// used to track how many more `bar` messages can be enqueued
|
||||||
// `U2` is the capacity of the `bar` task; a max of two instances can be queued
|
// `U2` is the capacity of the `bar` task; a max of two instances can be queued
|
||||||
// this queue is filled by the framework before `init` runs
|
// this queue is filled by the framework before `init` runs
|
||||||
static mut bar_FQ: Queue<(), U2> = Queue::new();
|
static mut bar_FQ: Queue<(), 3> = Queue::new();
|
||||||
|
|
||||||
// Priority ceiling for the consumer endpoint of `bar_FQ`
|
// Priority ceiling for the consumer endpoint of `bar_FQ`
|
||||||
const bar_FQ_CEILING: u8 = 2;
|
const bar_FQ_CEILING: u8 = 2;
|
||||||
|
@ -227,7 +227,7 @@ mod app {
|
||||||
|
|
||||||
// the free queue: used to track free slots in the `baz_INPUTS` array
|
// the free queue: used to track free slots in the `baz_INPUTS` array
|
||||||
// this queue is initialized with values `0` and `1` before `init` is executed
|
// this queue is initialized with values `0` and `1` before `init` is executed
|
||||||
static mut baz_FQ: Queue<u8, U2> = Queue::new();
|
static mut baz_FQ: Queue<u8, 3> = Queue::new();
|
||||||
|
|
||||||
// Priority ceiling for the consumer endpoint of `baz_FQ`
|
// Priority ceiling for the consumer endpoint of `baz_FQ`
|
||||||
const baz_FQ_CEILING: u8 = 2;
|
const baz_FQ_CEILING: u8 = 2;
|
||||||
|
|
|
@ -42,14 +42,16 @@ mod app {
|
||||||
|
|
||||||
#[task(binds = I2C0, priority = 2)]
|
#[task(binds = I2C0, priority = 2)]
|
||||||
fn i2c0(_: i2c0::Context) {
|
fn i2c0(_: i2c0::Context) {
|
||||||
// claim a memory block, leave it uninitialized and ..
|
// claim a memory block, initialize it and ..
|
||||||
let x = P::alloc().unwrap().freeze();
|
let x = P::alloc().unwrap().init([0u8; 128]);
|
||||||
|
|
||||||
// .. send it to the `foo` task
|
// .. send it to the `foo` task
|
||||||
foo::spawn(x).ok().unwrap();
|
foo::spawn(x).ok().unwrap();
|
||||||
|
|
||||||
// send another block to the task `bar`
|
// send another block to the task `bar`
|
||||||
bar::spawn(P::alloc().unwrap().freeze()).ok().unwrap();
|
bar::spawn(P::alloc().unwrap().init([0u8; 128]))
|
||||||
|
.ok()
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[task]
|
#[task]
|
||||||
|
|
|
@ -10,23 +10,19 @@ use panic_semihosting as _;
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = lm3s6965)]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use cortex_m_semihosting::{debug, hprintln};
|
||||||
use heapless::{
|
use heapless::spsc::{Consumer, Producer, Queue};
|
||||||
consts::*,
|
|
||||||
i,
|
|
||||||
spsc::{Consumer, Producer, Queue},
|
|
||||||
};
|
|
||||||
use lm3s6965::Interrupt;
|
use lm3s6965::Interrupt;
|
||||||
|
|
||||||
#[shared]
|
#[shared]
|
||||||
struct Shared {
|
struct Shared {
|
||||||
p: Producer<'static, u32, U4>,
|
p: Producer<'static, u32, 5>,
|
||||||
c: Consumer<'static, u32, U4>,
|
c: Consumer<'static, u32, 5>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[local]
|
#[local]
|
||||||
struct Local {}
|
struct Local {}
|
||||||
|
|
||||||
#[init(local = [q: Queue<u32, U4> = Queue(i::Queue::new())])]
|
#[init(local = [q: Queue<u32, 5> = Queue::new()])]
|
||||||
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
|
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
|
||||||
let (p, c) = cx.local.q.split();
|
let (p, c) = cx.local.q.split();
|
||||||
|
|
||||||
|
|
|
@ -11,23 +11,19 @@ use panic_semihosting as _;
|
||||||
mod app {
|
mod app {
|
||||||
|
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use cortex_m_semihosting::{debug, hprintln};
|
||||||
use heapless::{
|
use heapless::spsc::{Consumer, Producer, Queue};
|
||||||
consts::*,
|
|
||||||
i,
|
|
||||||
spsc::{Consumer, Producer, Queue},
|
|
||||||
};
|
|
||||||
use lm3s6965::Interrupt;
|
use lm3s6965::Interrupt;
|
||||||
|
|
||||||
#[shared]
|
#[shared]
|
||||||
struct Shared {
|
struct Shared {
|
||||||
p: Producer<'static, u32, U4>,
|
p: Producer<'static, u32, 5>,
|
||||||
c: Consumer<'static, u32, U4>,
|
c: Consumer<'static, u32, 5>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[local]
|
#[local]
|
||||||
struct Local {}
|
struct Local {}
|
||||||
|
|
||||||
#[init(local = [q: Queue<u32, U4> = Queue(i::Queue::new())])]
|
#[init(local = [q: Queue<u32, 5> = Queue::new()])]
|
||||||
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
|
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
|
||||||
let (p, c) = cx.local.q.split();
|
let (p, c) = cx.local.q.split();
|
||||||
|
|
||||||
|
|
|
@ -42,15 +42,13 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
||||||
let n = util::capacity_typenum(channel.capacity, true);
|
let n = util::capacity_literal(channel.capacity as usize + 1);
|
||||||
let rq = util::rq_ident(level);
|
let rq = util::rq_ident(level);
|
||||||
let rq = util::mark_internal_ident(&rq);
|
let rq = util::mark_internal_ident(&rq);
|
||||||
let (rq_ty, rq_expr) = {
|
let (rq_ty, rq_expr) = {
|
||||||
(
|
(
|
||||||
quote!(rtic::export::SCRQ<#t, #n>),
|
quote!(rtic::export::SCRQ<#t, #n>),
|
||||||
quote!(rtic::export::Queue(unsafe {
|
quote!(rtic::export::Queue::new()),
|
||||||
rtic::export::iQueue::u8_sc()
|
|
||||||
})),
|
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,8 @@ pub fn codegen(
|
||||||
let (_, _, _, input_ty) = util::regroup_inputs(inputs);
|
let (_, _, _, input_ty) = util::regroup_inputs(inputs);
|
||||||
|
|
||||||
let cap = task.args.capacity;
|
let cap = task.args.capacity;
|
||||||
let cap_lit = util::capacity_literal(cap);
|
let cap_lit = util::capacity_literal(cap as usize);
|
||||||
let cap_ty = util::capacity_typenum(cap, true);
|
let cap_lit_p1 = util::capacity_literal(cap as usize + 1);
|
||||||
|
|
||||||
// Create free queues and inputs / instants buffers
|
// Create free queues and inputs / instants buffers
|
||||||
let fq = util::fq_ident(name);
|
let fq = util::fq_ident(name);
|
||||||
|
@ -41,10 +41,8 @@ pub fn codegen(
|
||||||
|
|
||||||
let (fq_ty, fq_expr, mk_uninit): (_, _, Box<dyn Fn() -> Option<_>>) = {
|
let (fq_ty, fq_expr, mk_uninit): (_, _, Box<dyn Fn() -> Option<_>>) = {
|
||||||
(
|
(
|
||||||
quote!(rtic::export::SCFQ<#cap_ty>),
|
quote!(rtic::export::SCFQ<#cap_lit_p1>),
|
||||||
quote!(rtic::export::Queue(unsafe {
|
quote!(rtic::export::Queue::new()),
|
||||||
rtic::export::iQueue::u8_sc()
|
|
||||||
})),
|
|
||||||
Box::new(|| util::link_section_uninit()),
|
Box::new(|| util::link_section_uninit()),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
|
@ -62,12 +62,12 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
|
||||||
{
|
{
|
||||||
// For future use
|
// For future use
|
||||||
// let doc = &format!("Timer queue for {}", monotonic_name);
|
// let doc = &format!("Timer queue for {}", monotonic_name);
|
||||||
let cap = app
|
let cap: u8 = app
|
||||||
.software_tasks
|
.software_tasks
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(_name, task)| task.args.capacity)
|
.map(|(_name, task)| task.args.capacity)
|
||||||
.sum();
|
.sum();
|
||||||
let n = util::capacity_typenum(cap, false);
|
let n = util::capacity_literal(cap as usize);
|
||||||
let tq_ty =
|
let tq_ty =
|
||||||
quote!(core::mem::MaybeUninit<rtic::export::TimerQueue<#mono_type, #t, #n>>);
|
quote!(core::mem::MaybeUninit<rtic::export::TimerQueue<#mono_type, #t, #n>>);
|
||||||
|
|
||||||
|
|
|
@ -8,23 +8,10 @@ use syn::{Attribute, Ident, LitInt, PatType};
|
||||||
use crate::check::Extra;
|
use crate::check::Extra;
|
||||||
|
|
||||||
/// Turns `capacity` into an unsuffixed integer literal
|
/// Turns `capacity` into an unsuffixed integer literal
|
||||||
pub fn capacity_literal(capacity: u8) -> LitInt {
|
pub fn capacity_literal(capacity: usize) -> LitInt {
|
||||||
LitInt::new(&capacity.to_string(), Span::call_site())
|
LitInt::new(&capacity.to_string(), Span::call_site())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turns `capacity` into a type-level (`typenum`) integer
|
|
||||||
pub fn capacity_typenum(capacity: u8, round_up_to_power_of_two: bool) -> TokenStream2 {
|
|
||||||
let capacity = if round_up_to_power_of_two {
|
|
||||||
capacity.checked_next_power_of_two().expect("UNREACHABLE")
|
|
||||||
} else {
|
|
||||||
capacity
|
|
||||||
};
|
|
||||||
|
|
||||||
let ident = Ident::new(&format!("U{}", capacity), Span::call_site());
|
|
||||||
|
|
||||||
quote!(rtic::export::consts::#ident)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Identifier for the free queue
|
/// Identifier for the free queue
|
||||||
pub fn fq_ident(task: &Ident) -> Ident {
|
pub fn fq_ident(task: &Ident) -> Ident {
|
||||||
Ident::new(&format!("{}_FQ", task.to_string()), Span::call_site())
|
Ident::new(&format!("{}_FQ", task.to_string()), Span::call_site())
|
||||||
|
|
|
@ -13,13 +13,12 @@ pub use cortex_m::{
|
||||||
peripheral::{scb::SystemHandler, syst::SystClkSource, DWT, NVIC},
|
peripheral::{scb::SystemHandler, syst::SystClkSource, DWT, NVIC},
|
||||||
Peripherals,
|
Peripherals,
|
||||||
};
|
};
|
||||||
use heapless::spsc::SingleCore;
|
pub use heapless::spsc::Queue;
|
||||||
pub use heapless::{consts, i::Queue as iQueue, spsc::Queue};
|
pub use heapless::BinaryHeap;
|
||||||
pub use heapless::{i::BinaryHeap as iBinaryHeap, BinaryHeap};
|
|
||||||
pub use rtic_monotonic as monotonic;
|
pub use rtic_monotonic as monotonic;
|
||||||
|
|
||||||
pub type SCFQ<N> = Queue<u8, N, u8, SingleCore>;
|
pub type SCFQ<const N: usize> = Queue<u8, N>;
|
||||||
pub type SCRQ<T, N> = Queue<(T, u8), N, u8, SingleCore>;
|
pub type SCRQ<T, const N: usize> = Queue<(T, u8), N>;
|
||||||
|
|
||||||
#[cfg(armv7m)]
|
#[cfg(armv7m)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
|
@ -3,8 +3,6 @@ use core::marker::PhantomData;
|
||||||
use core::mem::MaybeUninit;
|
use core::mem::MaybeUninit;
|
||||||
use core::ops::{Deref, DerefMut};
|
use core::ops::{Deref, DerefMut};
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
pub use generic_array::ArrayLength;
|
|
||||||
use generic_array::GenericArray;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
struct LinkedIndex(u16);
|
struct LinkedIndex(u16);
|
||||||
|
@ -37,21 +35,19 @@ pub struct Node<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterator for the linked list.
|
/// Iterator for the linked list.
|
||||||
pub struct Iter<'a, T, Kind, N>
|
pub struct Iter<'a, T, Kind, const N: usize>
|
||||||
where
|
where
|
||||||
T: PartialEq + PartialOrd,
|
T: PartialEq + PartialOrd,
|
||||||
Kind: kind::Kind,
|
Kind: kind::Kind,
|
||||||
N: ArrayLength<Node<T>>,
|
|
||||||
{
|
{
|
||||||
list: &'a LinkedList<T, Kind, N>,
|
list: &'a LinkedList<T, Kind, N>,
|
||||||
index: LinkedIndex,
|
index: LinkedIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, Kind, N> Iterator for Iter<'a, T, Kind, N>
|
impl<'a, T, Kind, const N: usize> Iterator for Iter<'a, T, Kind, N>
|
||||||
where
|
where
|
||||||
T: PartialEq + PartialOrd,
|
T: PartialEq + PartialOrd,
|
||||||
Kind: kind::Kind,
|
Kind: kind::Kind,
|
||||||
N: ArrayLength<Node<T>>,
|
|
||||||
{
|
{
|
||||||
type Item = &'a T;
|
type Item = &'a T;
|
||||||
|
|
||||||
|
@ -66,11 +62,10 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Comes from [`LinkedList::find_mut`].
|
/// Comes from [`LinkedList::find_mut`].
|
||||||
pub struct FindMut<'a, T, Kind, N>
|
pub struct FindMut<'a, T, Kind, const N: usize>
|
||||||
where
|
where
|
||||||
T: PartialEq + PartialOrd,
|
T: PartialEq + PartialOrd,
|
||||||
Kind: kind::Kind,
|
Kind: kind::Kind,
|
||||||
N: ArrayLength<Node<T>>,
|
|
||||||
{
|
{
|
||||||
list: &'a mut LinkedList<T, Kind, N>,
|
list: &'a mut LinkedList<T, Kind, N>,
|
||||||
is_head: bool,
|
is_head: bool,
|
||||||
|
@ -79,11 +74,10 @@ where
|
||||||
maybe_changed: bool,
|
maybe_changed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, Kind, N> FindMut<'a, T, Kind, N>
|
impl<'a, T, Kind, const N: usize> FindMut<'a, T, Kind, N>
|
||||||
where
|
where
|
||||||
T: PartialEq + PartialOrd,
|
T: PartialEq + PartialOrd,
|
||||||
Kind: kind::Kind,
|
Kind: kind::Kind,
|
||||||
N: ArrayLength<Node<T>>,
|
|
||||||
{
|
{
|
||||||
fn pop_internal(&mut self) -> T {
|
fn pop_internal(&mut self) -> T {
|
||||||
if self.is_head {
|
if self.is_head {
|
||||||
|
@ -122,11 +116,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Kind, N> Drop for FindMut<'_, T, Kind, N>
|
impl<T, Kind, const N: usize> Drop for FindMut<'_, T, Kind, N>
|
||||||
where
|
where
|
||||||
T: PartialEq + PartialOrd,
|
T: PartialEq + PartialOrd,
|
||||||
Kind: kind::Kind,
|
Kind: kind::Kind,
|
||||||
N: ArrayLength<Node<T>>,
|
|
||||||
{
|
{
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
// Only resort the list if the element has changed
|
// Only resort the list if the element has changed
|
||||||
|
@ -137,11 +130,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Kind, N> Deref for FindMut<'_, T, Kind, N>
|
impl<T, Kind, const N: usize> Deref for FindMut<'_, T, Kind, N>
|
||||||
where
|
where
|
||||||
T: PartialEq + PartialOrd,
|
T: PartialEq + PartialOrd,
|
||||||
Kind: kind::Kind,
|
Kind: kind::Kind,
|
||||||
N: ArrayLength<Node<T>>,
|
|
||||||
{
|
{
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
|
@ -150,11 +142,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Kind, N> DerefMut for FindMut<'_, T, Kind, N>
|
impl<T, Kind, const N: usize> DerefMut for FindMut<'_, T, Kind, N>
|
||||||
where
|
where
|
||||||
T: PartialEq + PartialOrd,
|
T: PartialEq + PartialOrd,
|
||||||
Kind: kind::Kind,
|
Kind: kind::Kind,
|
||||||
N: ArrayLength<Node<T>>,
|
|
||||||
{
|
{
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
self.maybe_changed = true;
|
self.maybe_changed = true;
|
||||||
|
@ -162,11 +153,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Kind, N> fmt::Debug for FindMut<'_, T, Kind, N>
|
impl<T, Kind, const N: usize> fmt::Debug for FindMut<'_, T, Kind, N>
|
||||||
where
|
where
|
||||||
T: PartialEq + PartialOrd + core::fmt::Debug,
|
T: PartialEq + PartialOrd + core::fmt::Debug,
|
||||||
Kind: kind::Kind,
|
Kind: kind::Kind,
|
||||||
N: ArrayLength<Node<T>>,
|
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("FindMut")
|
f.debug_struct("FindMut")
|
||||||
|
@ -189,23 +179,21 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The linked list.
|
/// The linked list.
|
||||||
pub struct LinkedList<T, Kind, N>
|
pub struct LinkedList<T, Kind, const N: usize>
|
||||||
where
|
where
|
||||||
T: PartialEq + PartialOrd,
|
T: PartialEq + PartialOrd,
|
||||||
Kind: kind::Kind,
|
Kind: kind::Kind,
|
||||||
N: ArrayLength<Node<T>>,
|
|
||||||
{
|
{
|
||||||
list: MaybeUninit<GenericArray<Node<T>, N>>,
|
list: MaybeUninit<[Node<T>; N]>,
|
||||||
head: LinkedIndex,
|
head: LinkedIndex,
|
||||||
free: LinkedIndex,
|
free: LinkedIndex,
|
||||||
_kind: PhantomData<Kind>,
|
_kind: PhantomData<Kind>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Kind, N> LinkedList<T, Kind, N>
|
impl<T, Kind, const N: usize> LinkedList<T, Kind, N>
|
||||||
where
|
where
|
||||||
T: PartialEq + PartialOrd,
|
T: PartialEq + PartialOrd,
|
||||||
Kind: kind::Kind,
|
Kind: kind::Kind,
|
||||||
N: ArrayLength<Node<T>>,
|
|
||||||
{
|
{
|
||||||
/// Internal helper to not do pointer arithmetic all over the place.
|
/// Internal helper to not do pointer arithmetic all over the place.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -266,7 +254,7 @@ where
|
||||||
_kind: PhantomData,
|
_kind: PhantomData,
|
||||||
};
|
};
|
||||||
|
|
||||||
let len = N::U16;
|
let len = N as u16;
|
||||||
let mut free = 0;
|
let mut free = 0;
|
||||||
|
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
|
@ -451,11 +439,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Kind, N> Drop for LinkedList<T, Kind, N>
|
impl<T, Kind, const N: usize> Drop for LinkedList<T, Kind, N>
|
||||||
where
|
where
|
||||||
T: PartialEq + PartialOrd,
|
T: PartialEq + PartialOrd,
|
||||||
Kind: kind::Kind,
|
Kind: kind::Kind,
|
||||||
N: ArrayLength<Node<T>>,
|
|
||||||
{
|
{
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let mut index = self.head;
|
let mut index = self.head;
|
||||||
|
@ -471,11 +458,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, Kind, N> fmt::Debug for LinkedList<T, Kind, N>
|
impl<T, Kind, const N: usize> fmt::Debug for LinkedList<T, Kind, N>
|
||||||
where
|
where
|
||||||
T: PartialEq + PartialOrd + core::fmt::Debug,
|
T: PartialEq + PartialOrd + core::fmt::Debug,
|
||||||
Kind: kind::Kind,
|
Kind: kind::Kind,
|
||||||
N: ArrayLength<Node<T>>,
|
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_list().entries(self.iter()).finish()
|
f.debug_list().entries(self.iter()).finish()
|
||||||
|
@ -518,11 +504,10 @@ pub mod kind {
|
||||||
mod tests {
|
mod tests {
|
||||||
// Note this useful idiom: importing names from outer (for mod tests) scope.
|
// Note this useful idiom: importing names from outer (for mod tests) scope.
|
||||||
use super::*;
|
use super::*;
|
||||||
use generic_array::typenum::consts::*;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_peek() {
|
fn test_peek() {
|
||||||
let mut ll: LinkedList<u32, Max, U3> = LinkedList::new();
|
let mut ll: LinkedList<u32, Max, 3> = LinkedList::new();
|
||||||
|
|
||||||
ll.push(1).unwrap();
|
ll.push(1).unwrap();
|
||||||
assert_eq!(ll.peek().unwrap(), &1);
|
assert_eq!(ll.peek().unwrap(), &1);
|
||||||
|
@ -533,7 +518,7 @@ mod tests {
|
||||||
ll.push(3).unwrap();
|
ll.push(3).unwrap();
|
||||||
assert_eq!(ll.peek().unwrap(), &3);
|
assert_eq!(ll.peek().unwrap(), &3);
|
||||||
|
|
||||||
let mut ll: LinkedList<u32, Min, U3> = LinkedList::new();
|
let mut ll: LinkedList<u32, Min, 3> = LinkedList::new();
|
||||||
|
|
||||||
ll.push(2).unwrap();
|
ll.push(2).unwrap();
|
||||||
assert_eq!(ll.peek().unwrap(), &2);
|
assert_eq!(ll.peek().unwrap(), &2);
|
||||||
|
@ -547,7 +532,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_full() {
|
fn test_full() {
|
||||||
let mut ll: LinkedList<u32, Max, U3> = LinkedList::new();
|
let mut ll: LinkedList<u32, Max, 3> = LinkedList::new();
|
||||||
ll.push(1).unwrap();
|
ll.push(1).unwrap();
|
||||||
ll.push(2).unwrap();
|
ll.push(2).unwrap();
|
||||||
ll.push(3).unwrap();
|
ll.push(3).unwrap();
|
||||||
|
@ -557,14 +542,14 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_empty() {
|
fn test_empty() {
|
||||||
let ll: LinkedList<u32, Max, U3> = LinkedList::new();
|
let ll: LinkedList<u32, Max, 3> = LinkedList::new();
|
||||||
|
|
||||||
assert!(ll.is_empty())
|
assert!(ll.is_empty())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_zero_size() {
|
fn test_zero_size() {
|
||||||
let ll: LinkedList<u32, Max, U0> = LinkedList::new();
|
let ll: LinkedList<u32, Max, 0> = LinkedList::new();
|
||||||
|
|
||||||
assert!(ll.is_empty());
|
assert!(ll.is_empty());
|
||||||
assert!(ll.is_full());
|
assert!(ll.is_full());
|
||||||
|
@ -572,7 +557,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rejected_push() {
|
fn test_rejected_push() {
|
||||||
let mut ll: LinkedList<u32, Max, U3> = LinkedList::new();
|
let mut ll: LinkedList<u32, Max, 3> = LinkedList::new();
|
||||||
ll.push(1).unwrap();
|
ll.push(1).unwrap();
|
||||||
ll.push(2).unwrap();
|
ll.push(2).unwrap();
|
||||||
ll.push(3).unwrap();
|
ll.push(3).unwrap();
|
||||||
|
@ -585,7 +570,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_updating() {
|
fn test_updating() {
|
||||||
let mut ll: LinkedList<u32, Max, U3> = LinkedList::new();
|
let mut ll: LinkedList<u32, Max, 3> = LinkedList::new();
|
||||||
ll.push(1).unwrap();
|
ll.push(1).unwrap();
|
||||||
ll.push(2).unwrap();
|
ll.push(2).unwrap();
|
||||||
ll.push(3).unwrap();
|
ll.push(3).unwrap();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
linked_list::{ArrayLength, LinkedList, Min, Node},
|
linked_list::{LinkedList, Min},
|
||||||
time::{Clock, Instant},
|
time::{Clock, Instant},
|
||||||
Monotonic,
|
Monotonic,
|
||||||
};
|
};
|
||||||
|
@ -14,16 +14,14 @@ fn unwrapper<T, E>(val: Result<T, E>) -> T {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TimerQueue<Mono, Task, N>(pub LinkedList<NotReady<Mono, Task>, Min, N>)
|
pub struct TimerQueue<Mono, Task, const N: usize>(pub LinkedList<NotReady<Mono, Task>, Min, N>)
|
||||||
where
|
where
|
||||||
Mono: Monotonic,
|
Mono: Monotonic,
|
||||||
N: ArrayLength<Node<NotReady<Mono, Task>>>,
|
|
||||||
Task: Copy;
|
Task: Copy;
|
||||||
|
|
||||||
impl<Mono, Task, N> TimerQueue<Mono, Task, N>
|
impl<Mono, Task, const N: usize> TimerQueue<Mono, Task, N>
|
||||||
where
|
where
|
||||||
Mono: Monotonic,
|
Mono: Monotonic,
|
||||||
N: ArrayLength<Node<NotReady<Mono, Task>>>,
|
|
||||||
Task: Copy,
|
Task: Copy,
|
||||||
{
|
{
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
|
Loading…
Reference in a new issue