mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-27 14:04:56 +01:00
Move common data structures to rtic-common
This commit is contained in:
parent
cfd0914ef6
commit
6c48ebeeee
8 changed files with 53 additions and 11 deletions
|
@ -8,6 +8,7 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
heapless = "0.7"
|
heapless = "0.7"
|
||||||
critical-section = "1"
|
critical-section = "1"
|
||||||
|
rtic-common = { version = "1.0.0", path = "../rtic-common" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tokio = { version = "1", features = ["rt", "macros", "time"] }
|
tokio = { version = "1", features = ["rt", "macros", "time"] }
|
||||||
|
@ -15,4 +16,4 @@ tokio = { version = "1", features = ["rt", "macros", "time"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
testing = ["critical-section/std"]
|
testing = ["critical-section/std", "rtic-common/testing"]
|
||||||
|
|
|
@ -14,11 +14,8 @@ use core::{
|
||||||
task::{Poll, Waker},
|
task::{Poll, Waker},
|
||||||
};
|
};
|
||||||
use heapless::Deque;
|
use heapless::Deque;
|
||||||
use wait_queue::WaitQueue;
|
use rtic_common::wait_queue::{Link, WaitQueue};
|
||||||
use waker_registration::CriticalSectionWakerRegistration as WakerRegistration;
|
use rtic_common::waker_registration::CriticalSectionWakerRegistration as WakerRegistration;
|
||||||
|
|
||||||
mod wait_queue;
|
|
||||||
mod waker_registration;
|
|
||||||
|
|
||||||
/// An MPSC channel for use in no-alloc systems. `N` sets the size of the queue.
|
/// An MPSC channel for use in no-alloc systems. `N` sets the size of the queue.
|
||||||
///
|
///
|
||||||
|
@ -136,11 +133,11 @@ unsafe impl<'a, T, const N: usize> Send for Sender<'a, T, N> {}
|
||||||
/// This is needed to make the async closure in `send` accept that we "share"
|
/// This is needed to make the async closure in `send` accept that we "share"
|
||||||
/// the link possible between threads.
|
/// the link possible between threads.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct LinkPtr(*mut Option<wait_queue::Link<Waker>>);
|
struct LinkPtr(*mut Option<Link<Waker>>);
|
||||||
|
|
||||||
impl LinkPtr {
|
impl LinkPtr {
|
||||||
/// This will dereference the pointer stored within and give out an `&mut`.
|
/// This will dereference the pointer stored within and give out an `&mut`.
|
||||||
unsafe fn get(&mut self) -> &mut Option<wait_queue::Link<Waker>> {
|
unsafe fn get(&mut self) -> &mut Option<Link<Waker>> {
|
||||||
&mut *self.0
|
&mut *self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,10 +197,10 @@ impl<'a, T, const N: usize> Sender<'a, T, N> {
|
||||||
/// Send a value. If there is no place left in the queue this will wait until there is.
|
/// Send a value. If there is no place left in the queue this will wait until there is.
|
||||||
/// If the receiver does not exist this will return an error.
|
/// If the receiver does not exist this will return an error.
|
||||||
pub async fn send(&mut self, val: T) -> Result<(), NoReceiver<T>> {
|
pub async fn send(&mut self, val: T) -> Result<(), NoReceiver<T>> {
|
||||||
let mut link_ptr: Option<wait_queue::Link<Waker>> = None;
|
let mut link_ptr: Option<Link<Waker>> = None;
|
||||||
|
|
||||||
// Make this future `Drop`-safe, also shadow the original definition so we can't abuse it.
|
// Make this future `Drop`-safe, also shadow the original definition so we can't abuse it.
|
||||||
let mut link_ptr = LinkPtr(&mut link_ptr as *mut Option<wait_queue::Link<Waker>>);
|
let mut link_ptr = LinkPtr(&mut link_ptr as *mut Option<Link<Waker>>);
|
||||||
|
|
||||||
let mut link_ptr2 = link_ptr.clone();
|
let mut link_ptr2 = link_ptr.clone();
|
||||||
let dropper = OnDrop::new(|| {
|
let dropper = OnDrop::new(|| {
|
||||||
|
@ -236,7 +233,7 @@ impl<'a, T, const N: usize> Sender<'a, T, N> {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Place the link in the wait queue on first run.
|
// Place the link in the wait queue on first run.
|
||||||
let link_ref = link.insert(wait_queue::Link::new(cx.waker().clone()));
|
let link_ref = link.insert(Link::new(cx.waker().clone()));
|
||||||
|
|
||||||
// SAFETY: The address to the link is stable as it is hidden behind
|
// SAFETY: The address to the link is stable as it is hidden behind
|
||||||
// `link_ptr`, and `link_ptr` shadows the original making it unmovable.
|
// `link_ptr`, and `link_ptr` shadows the original making it unmovable.
|
||||||
|
|
2
rtic-common/.gitignore
vendored
Normal file
2
rtic-common/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Cargo.lock
|
||||||
|
target/
|
16
rtic-common/CHANGELOG.md
Normal file
16
rtic-common/CHANGELOG.md
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# Change Log
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
|
For each category, *Added*, *Changed*, *Fixed* add new entries at the top!
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
## [v1.0.0] - 2023-xx-xx
|
13
rtic-common/Cargo.toml
Normal file
13
rtic-common/Cargo.toml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
[package]
|
||||||
|
name = "rtic-common"
|
||||||
|
version = "1.0.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
critical-section = "1"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
testing = ["critical-section/std"]
|
8
rtic-common/src/lib.rs
Normal file
8
rtic-common/src/lib.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
//! Crate
|
||||||
|
|
||||||
|
#![no_std]
|
||||||
|
#![deny(missing_docs)]
|
||||||
|
//deny_warnings_placeholder_for_ci
|
||||||
|
|
||||||
|
pub mod wait_queue;
|
||||||
|
pub mod waker_registration;
|
|
@ -7,6 +7,7 @@ use core::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
|
||||||
use core::task::Waker;
|
use core::task::Waker;
|
||||||
use critical_section as cs;
|
use critical_section as cs;
|
||||||
|
|
||||||
|
/// A helper definition of a wait queue.
|
||||||
pub type WaitQueue = LinkedList<Waker>;
|
pub type WaitQueue = LinkedList<Waker>;
|
||||||
|
|
||||||
/// A FIFO linked list for a wait queue.
|
/// A FIFO linked list for a wait queue.
|
||||||
|
@ -119,10 +120,12 @@ impl<T: Clone> Link<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return true if this link has been poped from the list.
|
||||||
pub fn is_poped(&self) -> bool {
|
pub fn is_poped(&self) -> bool {
|
||||||
self.is_poped.load(Self::R)
|
self.is_poped.load(Self::R)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Remove this link from a linked list.
|
||||||
pub fn remove_from_list(&mut self, list: &LinkedList<T>) {
|
pub fn remove_from_list(&mut self, list: &LinkedList<T>) {
|
||||||
cs::with(|_| {
|
cs::with(|_| {
|
||||||
// Make sure all previous writes are visible
|
// Make sure all previous writes are visible
|
|
@ -1,3 +1,5 @@
|
||||||
|
//! Waker registration utility.
|
||||||
|
|
||||||
use core::cell::UnsafeCell;
|
use core::cell::UnsafeCell;
|
||||||
use core::task::Waker;
|
use core::task::Waker;
|
||||||
|
|
Loading…
Reference in a new issue