Move common data structures to rtic-common

This commit is contained in:
Emil Fresk 2023-01-29 20:16:23 +01:00 committed by Henrik Tjäder
parent 58692a35e8
commit e65e532c2a
8 changed files with 53 additions and 11 deletions

View file

@ -8,6 +8,7 @@ edition = "2021"
[dependencies]
heapless = "0.7"
critical-section = "1"
rtic-common = { version = "1.0.0", path = "../rtic-common" }
[dev-dependencies]
tokio = { version = "1", features = ["rt", "macros", "time"] }
@ -15,4 +16,4 @@ tokio = { version = "1", features = ["rt", "macros", "time"] }
[features]
default = []
testing = ["critical-section/std"]
testing = ["critical-section/std", "rtic-common/testing"]

View file

@ -14,11 +14,8 @@ use core::{
task::{Poll, Waker},
};
use heapless::Deque;
use wait_queue::WaitQueue;
use waker_registration::CriticalSectionWakerRegistration as WakerRegistration;
mod wait_queue;
mod waker_registration;
use rtic_common::wait_queue::{Link, WaitQueue};
use rtic_common::waker_registration::CriticalSectionWakerRegistration as WakerRegistration;
/// 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"
/// the link possible between threads.
#[derive(Clone)]
struct LinkPtr(*mut Option<wait_queue::Link<Waker>>);
struct LinkPtr(*mut Option<Link<Waker>>);
impl LinkPtr {
/// 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
}
}
@ -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.
/// If the receiver does not exist this will return an error.
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.
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 dropper = OnDrop::new(|| {
@ -236,7 +233,7 @@ impl<'a, T, const N: usize> Sender<'a, T, N> {
}
} else {
// 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
// `link_ptr`, and `link_ptr` shadows the original making it unmovable.

2
rtic-common/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
Cargo.lock
target/

16
rtic-common/CHANGELOG.md Normal file
View 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
View 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
View file

@ -0,0 +1,8 @@
//! Crate
#![no_std]
#![deny(missing_docs)]
//deny_warnings_placeholder_for_ci
pub mod wait_queue;
pub mod waker_registration;

View file

@ -7,6 +7,7 @@ use core::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
use core::task::Waker;
use critical_section as cs;
/// A helper definition of a wait queue.
pub type WaitQueue = LinkedList<Waker>;
/// 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 {
self.is_poped.load(Self::R)
}
/// Remove this link from a linked list.
pub fn remove_from_list(&mut self, list: &LinkedList<T>) {
cs::with(|_| {
// Make sure all previous writes are visible

View file

@ -1,3 +1,5 @@
//! Waker registration utility.
use core::cell::UnsafeCell;
use core::task::Waker;