rtic/src/node.rs

151 lines
2.5 KiB
Rust
Raw Normal View History

2018-04-19 18:38:12 +02:00
use core::cmp::Ordering;
2018-04-20 06:48:59 +02:00
use core::{mem, ptr};
2018-04-19 18:38:12 +02:00
2018-04-29 08:45:31 +02:00
use instant::Instant;
2018-04-19 18:38:12 +02:00
2018-04-29 08:45:31 +02:00
#[doc(hidden)]
2018-04-20 06:48:59 +02:00
#[repr(C)]
pub struct Node<T>
2018-04-20 03:46:04 +02:00
where
2018-04-20 06:48:59 +02:00
T: 'static,
2018-04-20 03:46:04 +02:00
{
2018-04-20 06:48:59 +02:00
baseline: Instant,
payload: T,
2018-04-20 03:46:04 +02:00
}
2018-04-20 06:48:59 +02:00
impl<T> Eq for Node<T> {}
impl<T> Ord for Node<T> {
fn cmp(&self, rhs: &Self) -> Ordering {
self.baseline.cmp(&rhs.baseline)
2018-04-20 03:46:04 +02:00
}
}
2018-04-20 06:48:59 +02:00
impl<T> PartialEq for Node<T> {
fn eq(&self, rhs: &Self) -> bool {
self.baseline.eq(&rhs.baseline)
}
2018-04-19 18:38:12 +02:00
}
2018-04-20 06:48:59 +02:00
impl<T> PartialOrd for Node<T> {
fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
Some(self.cmp(rhs))
2018-04-19 18:38:12 +02:00
}
}
2018-04-29 08:45:31 +02:00
#[doc(hidden)]
2018-04-20 06:48:59 +02:00
pub struct Slot<T>
where
T: 'static,
{
node: &'static mut Node<T>,
}
2018-04-19 18:38:12 +02:00
2018-04-20 06:48:59 +02:00
impl<T> Slot<T> {
pub fn write(self, bl: Instant, data: T) -> Payload<T> {
self.node.baseline = bl;
unsafe { ptr::write(&mut self.node.payload, data) }
Payload { node: self.node }
2018-04-19 18:38:12 +02:00
}
}
2018-04-29 08:45:31 +02:00
impl<T> Into<Slot<T>> for &'static mut Node<T> {
fn into(self) -> Slot<T> {
Slot { node: self }
2018-04-19 18:38:12 +02:00
}
}
2018-04-29 08:45:31 +02:00
#[doc(hidden)]
2018-04-19 18:38:12 +02:00
pub struct Payload<T>
where
T: 'static,
{
node: &'static mut Node<T>,
}
impl<T> Payload<T> {
2018-04-20 06:48:59 +02:00
pub fn read(self) -> (Instant, T, Slot<T>) {
let data = unsafe { ptr::read(&self.node.payload) };
(self.node.baseline, data, Slot { node: self.node })
}
pub fn tag<A>(self, tag: A) -> TaggedPayload<A>
where
A: Copy,
{
TaggedPayload {
tag,
payload: unsafe { mem::transmute(self) },
2018-04-19 18:38:12 +02:00
}
}
2018-04-20 06:48:59 +02:00
}
2018-04-29 08:45:31 +02:00
#[doc(hidden)]
2018-04-20 06:48:59 +02:00
pub struct TaggedPayload<A>
where
A: Copy,
{
tag: A,
payload: Payload<!>,
}
impl<A> TaggedPayload<A>
where
A: Copy,
{
pub unsafe fn coerce<T>(self) -> Payload<T> {
mem::transmute(self.payload)
}
2018-04-19 18:38:12 +02:00
2018-04-20 06:48:59 +02:00
pub fn baseline(&self) -> Instant {
self.payload.node.baseline
2018-04-19 18:38:12 +02:00
}
2018-04-20 06:48:59 +02:00
pub fn tag(&self) -> A {
self.tag
}
2018-04-19 18:38:12 +02:00
2018-04-20 06:48:59 +02:00
pub fn retag<B>(self, tag: B) -> TaggedPayload<B>
where
B: Copy,
{
TaggedPayload {
tag,
payload: self.payload,
2018-04-19 18:38:12 +02:00
}
}
}
2018-04-20 06:48:59 +02:00
impl<T> Eq for TaggedPayload<T>
2018-04-19 18:38:12 +02:00
where
2018-04-20 06:48:59 +02:00
T: Copy,
2018-04-19 18:38:12 +02:00
{
}
2018-04-20 06:48:59 +02:00
impl<T> Ord for TaggedPayload<T>
where
T: Copy,
{
fn cmp(&self, rhs: &Self) -> Ordering {
self.payload.node.cmp(&rhs.payload.node)
2018-04-19 18:38:12 +02:00
}
2018-04-20 06:48:59 +02:00
}
2018-04-19 18:38:12 +02:00
2018-04-20 06:48:59 +02:00
impl<T> PartialEq for TaggedPayload<T>
where
T: Copy,
{
fn eq(&self, rhs: &Self) -> bool {
self.payload.node.eq(&rhs.payload.node)
2018-04-19 18:38:12 +02:00
}
}
2018-04-20 06:48:59 +02:00
impl<T> PartialOrd for TaggedPayload<T>
2018-04-19 18:38:12 +02:00
where
2018-04-20 06:48:59 +02:00
T: Copy,
2018-04-19 18:38:12 +02:00
{
2018-04-20 06:48:59 +02:00
fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
Some(self.cmp(rhs))
}
2018-04-19 18:38:12 +02:00
}