mirror of
https://github.com/rust-embedded/heapless.git
synced 2025-10-02 14:54:30 +00:00
rename RingBuffer to spsc::Queue
This commit is contained in:
parent
991e4146e1
commit
f83329cbf4
16
src/cfail.rs
16
src/cfail.rs
@ -5,8 +5,8 @@
|
|||||||
//! Collections of `Send`-able things are `Send`
|
//! Collections of `Send`-able things are `Send`
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! use heapless::{RingBuffer, Vec};
|
//! use heapless::Vec;
|
||||||
//! use heapless::ring_buffer::{Consumer, Producer};
|
//! use heapless::spsc::{Consumer, Queue, Producer};
|
||||||
//! use heapless::consts::*;
|
//! use heapless::consts::*;
|
||||||
//!
|
//!
|
||||||
//! struct IsSend;
|
//! struct IsSend;
|
||||||
@ -17,7 +17,7 @@
|
|||||||
//!
|
//!
|
||||||
//! is_send::<Consumer<IsSend, U4>>();
|
//! is_send::<Consumer<IsSend, U4>>();
|
||||||
//! is_send::<Producer<IsSend, U4>>();
|
//! is_send::<Producer<IsSend, U4>>();
|
||||||
//! is_send::<RingBuffer<IsSend, U4>>();
|
//! is_send::<Queue<IsSend, U4>>();
|
||||||
//! is_send::<Vec<IsSend, U4>>();
|
//! is_send::<Vec<IsSend, U4>>();
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
@ -49,13 +49,13 @@
|
|||||||
//!
|
//!
|
||||||
//! ``` compile_fail
|
//! ``` compile_fail
|
||||||
//! use std::marker::PhantomData;
|
//! use std::marker::PhantomData;
|
||||||
//! use heapless::RingBuffer;
|
//! use heapless::spsc::Queue;
|
||||||
//!
|
//!
|
||||||
//! type NotSend = PhantomData<*const ()>;
|
//! type NotSend = PhantomData<*const ()>;
|
||||||
//!
|
//!
|
||||||
//! fn is_send<T>() where T: Send {}
|
//! fn is_send<T>() where T: Send {}
|
||||||
//!
|
//!
|
||||||
//! is_send::<RingBuffer<NotSend, [NotSend; 4]>>();
|
//! is_send::<Queue<NotSend, [NotSend; 4]>>();
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! ``` compile_fail
|
//! ``` compile_fail
|
||||||
@ -71,12 +71,12 @@
|
|||||||
//!
|
//!
|
||||||
//! # Freeze
|
//! # Freeze
|
||||||
//!
|
//!
|
||||||
//! Splitting a `RingBuffer` should invalidate the original reference.
|
//! Splitting a `Queue` should invalidate the original reference.
|
||||||
//!
|
//!
|
||||||
//! ``` compile_fail
|
//! ``` compile_fail
|
||||||
//! use heapless::RingBuffer;
|
//! use heapless::spsc::Queue;
|
||||||
//!
|
//!
|
||||||
//! let mut rb: RingBuffer<u8, [u8; 4]> = RingBuffer::new();
|
//! let mut rb: Queue<u8, [u8; 4]> = Queue::new();
|
||||||
//!
|
//!
|
||||||
//! let (p, c) = rb.split();
|
//! let (p, c) = rb.split();
|
||||||
//! rb.enqueue(0).unwrap();
|
//! rb.enqueue(0).unwrap();
|
||||||
|
@ -78,7 +78,6 @@
|
|||||||
//! This way they can be used to initialize static memory at compile time.
|
//! This way they can be used to initialize static memory at compile time.
|
||||||
//!
|
//!
|
||||||
|
|
||||||
|
|
||||||
#![allow(warnings)]
|
#![allow(warnings)]
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
#![deny(warnings)]
|
#![deny(warnings)]
|
||||||
@ -102,7 +101,6 @@ pub use generic_array::ArrayLength;
|
|||||||
pub use indexmap::{FnvIndexMap, IndexMap};
|
pub use indexmap::{FnvIndexMap, IndexMap};
|
||||||
pub use indexset::{FnvIndexSet, IndexSet};
|
pub use indexset::{FnvIndexSet, IndexSet};
|
||||||
pub use linear_map::LinearMap;
|
pub use linear_map::LinearMap;
|
||||||
pub use ring_buffer::RingBuffer;
|
|
||||||
pub use string::String;
|
pub use string::String;
|
||||||
pub use vec::Vec;
|
pub use vec::Vec;
|
||||||
|
|
||||||
@ -114,7 +112,7 @@ mod string;
|
|||||||
mod vec;
|
mod vec;
|
||||||
|
|
||||||
pub mod binary_heap;
|
pub mod binary_heap;
|
||||||
pub mod ring_buffer;
|
pub mod spsc;
|
||||||
|
|
||||||
mod __core;
|
mod __core;
|
||||||
mod sealed;
|
mod sealed;
|
||||||
|
@ -8,7 +8,7 @@ pub unsafe trait Uxx: Into<usize> + Send {
|
|||||||
#[cfg(feature = "smaller-atomics")]
|
#[cfg(feature = "smaller-atomics")]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn load_acquire(x: *mut Self) -> Self {
|
fn load_acquire(x: *mut Self) -> Self {
|
||||||
unsafe { intrinsics::atomic_load_acq(x) }
|
unsafe { core::intrinsics::atomic_load_acq(x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "smaller-atomics"))]
|
#[cfg(not(feature = "smaller-atomics"))]
|
||||||
@ -18,7 +18,7 @@ pub unsafe trait Uxx: Into<usize> + Send {
|
|||||||
#[cfg(feature = "smaller-atomics")]
|
#[cfg(feature = "smaller-atomics")]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn load_relaxed(x: *mut Self) -> Self {
|
fn load_relaxed(x: *mut Self) -> Self {
|
||||||
unsafe { intrinsics::atomic_load_relaxed(x) }
|
unsafe { core::intrinsics::atomic_load_relaxed(x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "smaller-atomics"))]
|
#[cfg(not(feature = "smaller-atomics"))]
|
||||||
@ -28,7 +28,7 @@ pub unsafe trait Uxx: Into<usize> + Send {
|
|||||||
#[cfg(feature = "smaller-atomics")]
|
#[cfg(feature = "smaller-atomics")]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn store_release(x: *mut Self, val: Self) {
|
fn store_release(x: *mut Self, val: Self) {
|
||||||
unsafe { intrinsics::atomic_store_rel(x, val) }
|
unsafe { core::intrinsics::atomic_store_rel(x, val) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "smaller-atomics"))]
|
#[cfg(not(feature = "smaller-atomics"))]
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
//! Ring buffer
|
//! Ring buffer
|
||||||
|
|
||||||
use core::cell::UnsafeCell;
|
use core::cell::UnsafeCell;
|
||||||
#[cfg(feature = "smaller-atomics")]
|
|
||||||
use core::intrinsics;
|
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
|
|
||||||
use generic_array::{ArrayLength, GenericArray};
|
use generic_array::{ArrayLength, GenericArray};
|
||||||
|
|
||||||
pub use self::spsc::{Consumer, Producer};
|
pub use self::split::{Consumer, Producer};
|
||||||
use __core::mem::MaybeUninit;
|
use __core::mem::MaybeUninit;
|
||||||
use sealed;
|
use sealed;
|
||||||
|
|
||||||
mod spsc;
|
mod split;
|
||||||
|
|
||||||
// Atomic{U8,U16, Usize} with no CAS operations that works on targets that have "no atomic support"
|
// Atomic{U8,U16, Usize} with no CAS operations that works on targets that have "no atomic support"
|
||||||
// according to their specification
|
// according to their specification
|
||||||
@ -49,29 +47,29 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A statically allocated ring buffer with a capacity of `N` elements
|
/// A statically allocated single producer single consumer queue with a capacity of `N` elements
|
||||||
///
|
///
|
||||||
/// *IMPORTANT*: To get better performance use a capacity that is a power of 2 (e.g. `U16`, `U32`,
|
/// *IMPORTANT*: To get better performance use a capacity that is a power of 2 (e.g. `U16`, `U32`,
|
||||||
/// etc.).
|
/// etc.).
|
||||||
///
|
///
|
||||||
/// By default `RingBuffer` will use `usize` integers to hold the indices to its head and tail. For
|
/// By default `spsc::Queue` will use `usize` integers to hold the indices to its head and tail. For
|
||||||
/// small ring buffers `usize` may be overkill. However, `RingBuffer`'s index type is generic and
|
/// small queues `usize` indices may be overkill. However, `spsc::Queue`'s index type is generic and
|
||||||
/// can be changed to `u8` or `u16` to reduce its footprint. The easiest to construct a `RingBuffer`
|
/// can be changed to `u8` or `u16` to reduce its footprint. The easiest to construct a
|
||||||
/// with a smaller index type is to use the [`u8`] and [`u16`] constructors.
|
/// `spsc::Queue` with a smaller index type is to use the [`u8`] and [`u16`] constructors.
|
||||||
///
|
///
|
||||||
/// [`u8`]: struct.RingBuffer.html#method.u8
|
/// [`u8`]: struct.Queue.html#method.u8
|
||||||
/// [`u16`]: struct.RingBuffer.html#method.u16
|
/// [`u16`]: struct.Queue.html#method.u16
|
||||||
///
|
///
|
||||||
/// *IMPORTANT*: `RingBuffer<_, _, u8>` has a maximum capacity of 255 elements; `RingBuffer<_, _,
|
/// *IMPORTANT*: `spsc::Queue<_, _, u8>` has a maximum capacity of 255 elements; `spsc::Queue<_, _,
|
||||||
/// u16>` has a maximum capacity of 65535 elements.
|
/// u16>` has a maximum capacity of 65535 elements.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use heapless::RingBuffer;
|
/// use heapless::spsc::Queue;
|
||||||
/// use heapless::consts::*;
|
/// use heapless::consts::*;
|
||||||
///
|
///
|
||||||
/// let mut rb: RingBuffer<u8, U4> = RingBuffer::new();
|
/// let mut rb: Queue<u8, U4> = Queue::new();
|
||||||
///
|
///
|
||||||
/// assert!(rb.enqueue(0).is_ok());
|
/// assert!(rb.enqueue(0).is_ok());
|
||||||
/// assert!(rb.enqueue(1).is_ok());
|
/// assert!(rb.enqueue(1).is_ok());
|
||||||
@ -85,17 +83,17 @@ where
|
|||||||
/// ### Single producer single consumer mode
|
/// ### Single producer single consumer mode
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use heapless::RingBuffer;
|
/// use heapless::spsc::Queue;
|
||||||
/// use heapless::consts::*;
|
/// use heapless::consts::*;
|
||||||
///
|
///
|
||||||
/// // static mut RB: RingBuffer<Event, U4> = RingBuffer::new(); // requires feature `const-fn`
|
/// // static mut RB: Queue<Event, U4> = Queue::new(); // requires feature `const-fn`
|
||||||
///
|
///
|
||||||
/// static mut RB: Option<RingBuffer<Event, U4>> = None;
|
/// static mut RB: Option<Queue<Event, U4>> = None;
|
||||||
///
|
///
|
||||||
/// enum Event { A, B }
|
/// enum Event { A, B }
|
||||||
///
|
///
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
/// unsafe { RB = Some(RingBuffer::new()) };
|
/// unsafe { RB = Some(Queue::new()) };
|
||||||
/// // NOTE(unsafe) beware of aliasing the `consumer` end point
|
/// // NOTE(unsafe) beware of aliasing the `consumer` end point
|
||||||
/// let mut consumer = unsafe { RB.as_mut().unwrap().split().1 };
|
/// let mut consumer = unsafe { RB.as_mut().unwrap().split().1 };
|
||||||
///
|
///
|
||||||
@ -127,7 +125,7 @@ where
|
|||||||
/// // ..
|
/// // ..
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub struct RingBuffer<T, N, U = usize>
|
pub struct Queue<T, N, U = usize>
|
||||||
where
|
where
|
||||||
N: ArrayLength<T>,
|
N: ArrayLength<T>,
|
||||||
U: sealed::Uxx,
|
U: sealed::Uxx,
|
||||||
@ -141,17 +139,17 @@ where
|
|||||||
buffer: MaybeUninit<GenericArray<T, N>>,
|
buffer: MaybeUninit<GenericArray<T, N>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, N, U> RingBuffer<T, N, U>
|
impl<T, N, U> Queue<T, N, U>
|
||||||
where
|
where
|
||||||
N: ArrayLength<T>,
|
N: ArrayLength<T>,
|
||||||
U: sealed::Uxx,
|
U: sealed::Uxx,
|
||||||
{
|
{
|
||||||
/// Returns the maximum number of elements the ring buffer can hold
|
/// Returns the maximum number of elements the queue can hold
|
||||||
pub fn capacity(&self) -> U {
|
pub fn capacity(&self) -> U {
|
||||||
U::truncate(N::to_usize())
|
U::truncate(N::to_usize())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the ring buffer has a length of 0
|
/// Returns `true` if the queue has a length of 0
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.len_usize() == 0
|
self.len_usize() == 0
|
||||||
}
|
}
|
||||||
@ -183,7 +181,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, N, U> Drop for RingBuffer<T, N, U>
|
impl<T, N, U> Drop for Queue<T, N, U>
|
||||||
where
|
where
|
||||||
N: ArrayLength<T>,
|
N: ArrayLength<T>,
|
||||||
U: sealed::Uxx,
|
U: sealed::Uxx,
|
||||||
@ -197,7 +195,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, N, U> IntoIterator for &'a RingBuffer<T, N, U>
|
impl<'a, T, N, U> IntoIterator for &'a Queue<T, N, U>
|
||||||
where
|
where
|
||||||
N: ArrayLength<T>,
|
N: ArrayLength<T>,
|
||||||
U: sealed::Uxx,
|
U: sealed::Uxx,
|
||||||
@ -210,7 +208,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T, N, U> IntoIterator for &'a mut RingBuffer<T, N, U>
|
impl<'a, T, N, U> IntoIterator for &'a mut Queue<T, N, U>
|
||||||
where
|
where
|
||||||
N: ArrayLength<T>,
|
N: ArrayLength<T>,
|
||||||
U: sealed::Uxx,
|
U: sealed::Uxx,
|
||||||
@ -225,14 +223,14 @@ where
|
|||||||
|
|
||||||
macro_rules! impl_ {
|
macro_rules! impl_ {
|
||||||
($uxx:ident) => {
|
($uxx:ident) => {
|
||||||
impl<T, N> RingBuffer<T, N, $uxx>
|
impl<T, N> Queue<T, N, $uxx>
|
||||||
where
|
where
|
||||||
N: ArrayLength<T>,
|
N: ArrayLength<T>,
|
||||||
{
|
{
|
||||||
const_fn!(
|
const_fn!(
|
||||||
/// Creates an empty ring buffer with a fixed capacity of `N`
|
/// Creates an empty queue with a fixed capacity of `N`
|
||||||
pub const fn $uxx() -> Self {
|
pub const fn $uxx() -> Self {
|
||||||
RingBuffer {
|
Queue {
|
||||||
buffer: unsafe { MaybeUninit::uninitialized() },
|
buffer: unsafe { MaybeUninit::uninitialized() },
|
||||||
head: Atomic::new(0),
|
head: Atomic::new(0),
|
||||||
tail: Atomic::new(0),
|
tail: Atomic::new(0),
|
||||||
@ -310,14 +308,14 @@ macro_rules! impl_ {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, N> RingBuffer<T, N, usize>
|
impl<T, N> Queue<T, N, usize>
|
||||||
where
|
where
|
||||||
N: ArrayLength<T>,
|
N: ArrayLength<T>,
|
||||||
{
|
{
|
||||||
const_fn!(
|
const_fn!(
|
||||||
/// Alias for [`RingBuffer::usize`](struct.RingBuffer.html#method.usize)
|
/// Alias for [`spsc::Queue::usize`](struct.Queue.html#method.usize)
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
RingBuffer::usize()
|
Queue::usize()
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -328,26 +326,26 @@ impl_!(u8);
|
|||||||
impl_!(u16);
|
impl_!(u16);
|
||||||
impl_!(usize);
|
impl_!(usize);
|
||||||
|
|
||||||
/// An iterator over a ring buffer items
|
/// An iterator over the items of a queue
|
||||||
pub struct Iter<'a, T, N, U>
|
pub struct Iter<'a, T, N, U>
|
||||||
where
|
where
|
||||||
N: ArrayLength<T> + 'a,
|
N: ArrayLength<T> + 'a,
|
||||||
T: 'a,
|
T: 'a,
|
||||||
U: 'a + sealed::Uxx,
|
U: 'a + sealed::Uxx,
|
||||||
{
|
{
|
||||||
rb: &'a RingBuffer<T, N, U>,
|
rb: &'a Queue<T, N, U>,
|
||||||
index: usize,
|
index: usize,
|
||||||
len: usize,
|
len: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A mutable iterator over a ring buffer items
|
/// A mutable iterator over the items of a queue
|
||||||
pub struct IterMut<'a, T, N, U>
|
pub struct IterMut<'a, T, N, U>
|
||||||
where
|
where
|
||||||
N: ArrayLength<T> + 'a,
|
N: ArrayLength<T> + 'a,
|
||||||
T: 'a,
|
T: 'a,
|
||||||
U: 'a + sealed::Uxx,
|
U: 'a + sealed::Uxx,
|
||||||
{
|
{
|
||||||
rb: &'a mut RingBuffer<T, N, U>,
|
rb: &'a mut Queue<T, N, U>,
|
||||||
index: usize,
|
index: usize,
|
||||||
len: usize,
|
len: usize,
|
||||||
}
|
}
|
||||||
@ -398,12 +396,12 @@ iterator!(struct IterMut -> &'a mut T, *mut T, get_mut, as_mut_ptr, make_ref_mut
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use consts::*;
|
use consts::*;
|
||||||
use RingBuffer;
|
use spsc::Queue;
|
||||||
|
|
||||||
#[cfg(feature = "const-fn")]
|
#[cfg(feature = "const-fn")]
|
||||||
#[test]
|
#[test]
|
||||||
fn static_new() {
|
fn static_new() {
|
||||||
static mut _R: RingBuffer<i32, U4> = RingBuffer::new();
|
static mut _Q: Queue<i32, U4> = Queue::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -429,7 +427,7 @@ mod tests {
|
|||||||
static mut COUNT: i32 = 0;
|
static mut COUNT: i32 = 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut v: RingBuffer<Droppable, U4> = RingBuffer::new();
|
let mut v: Queue<Droppable, U4> = Queue::new();
|
||||||
v.enqueue(Droppable::new()).ok().unwrap();
|
v.enqueue(Droppable::new()).ok().unwrap();
|
||||||
v.enqueue(Droppable::new()).ok().unwrap();
|
v.enqueue(Droppable::new()).ok().unwrap();
|
||||||
v.dequeue().unwrap();
|
v.dequeue().unwrap();
|
||||||
@ -438,7 +436,7 @@ mod tests {
|
|||||||
assert_eq!(unsafe { COUNT }, 0);
|
assert_eq!(unsafe { COUNT }, 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut v: RingBuffer<Droppable, U4> = RingBuffer::new();
|
let mut v: Queue<Droppable, U4> = Queue::new();
|
||||||
v.enqueue(Droppable::new()).ok().unwrap();
|
v.enqueue(Droppable::new()).ok().unwrap();
|
||||||
v.enqueue(Droppable::new()).ok().unwrap();
|
v.enqueue(Droppable::new()).ok().unwrap();
|
||||||
}
|
}
|
||||||
@ -448,7 +446,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn full() {
|
fn full() {
|
||||||
let mut rb: RingBuffer<i32, U4> = RingBuffer::new();
|
let mut rb: Queue<i32, U4> = Queue::new();
|
||||||
|
|
||||||
rb.enqueue(0).unwrap();
|
rb.enqueue(0).unwrap();
|
||||||
rb.enqueue(1).unwrap();
|
rb.enqueue(1).unwrap();
|
||||||
@ -460,7 +458,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn iter() {
|
fn iter() {
|
||||||
let mut rb: RingBuffer<i32, U4> = RingBuffer::new();
|
let mut rb: Queue<i32, U4> = Queue::new();
|
||||||
|
|
||||||
rb.enqueue(0).unwrap();
|
rb.enqueue(0).unwrap();
|
||||||
rb.enqueue(1).unwrap();
|
rb.enqueue(1).unwrap();
|
||||||
@ -476,7 +474,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn iter_mut() {
|
fn iter_mut() {
|
||||||
let mut rb: RingBuffer<i32, U4> = RingBuffer::new();
|
let mut rb: Queue<i32, U4> = Queue::new();
|
||||||
|
|
||||||
rb.enqueue(0).unwrap();
|
rb.enqueue(0).unwrap();
|
||||||
rb.enqueue(1).unwrap();
|
rb.enqueue(1).unwrap();
|
||||||
@ -492,7 +490,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sanity() {
|
fn sanity() {
|
||||||
let mut rb: RingBuffer<i32, U4> = RingBuffer::new();
|
let mut rb: Queue<i32, U4> = Queue::new();
|
||||||
|
|
||||||
assert_eq!(rb.dequeue(), None);
|
assert_eq!(rb.dequeue(), None);
|
||||||
|
|
||||||
@ -506,7 +504,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "smaller-atomics")]
|
#[cfg(feature = "smaller-atomics")]
|
||||||
fn u8() {
|
fn u8() {
|
||||||
let mut rb: RingBuffer<u8, U256, _> = RingBuffer::u8();
|
let mut rb: Queue<u8, U256, _> = Queue::u8();
|
||||||
|
|
||||||
for _ in 0..255 {
|
for _ in 0..255 {
|
||||||
rb.enqueue(0).unwrap();
|
rb.enqueue(0).unwrap();
|
||||||
@ -517,7 +515,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn wrap_around() {
|
fn wrap_around() {
|
||||||
let mut rb: RingBuffer<i32, U3> = RingBuffer::new();
|
let mut rb: Queue<i32, U3> = Queue::new();
|
||||||
|
|
||||||
rb.enqueue(0).unwrap();
|
rb.enqueue(0).unwrap();
|
||||||
rb.enqueue(1).unwrap();
|
rb.enqueue(1).unwrap();
|
||||||
@ -533,7 +531,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ready_flag() {
|
fn ready_flag() {
|
||||||
let mut rb: RingBuffer<i32, U2> = RingBuffer::new();
|
let mut rb: Queue<i32, U2> = Queue::new();
|
||||||
let (mut p, mut c) = rb.split();
|
let (mut p, mut c) = rb.split();
|
||||||
assert_eq!(c.ready(), false);
|
assert_eq!(c.ready(), false);
|
||||||
assert_eq!(p.ready(), true);
|
assert_eq!(p.ready(), true);
|
@ -3,15 +3,15 @@ use core::ptr::{self, NonNull};
|
|||||||
|
|
||||||
use generic_array::ArrayLength;
|
use generic_array::ArrayLength;
|
||||||
|
|
||||||
use ring_buffer::RingBuffer;
|
|
||||||
use sealed;
|
use sealed;
|
||||||
|
use spsc::Queue;
|
||||||
|
|
||||||
impl<T, N, U> RingBuffer<T, N, U>
|
impl<T, N, U> Queue<T, N, U>
|
||||||
where
|
where
|
||||||
N: ArrayLength<T>,
|
N: ArrayLength<T>,
|
||||||
U: sealed::Uxx,
|
U: sealed::Uxx,
|
||||||
{
|
{
|
||||||
/// Splits a statically allocated ring buffer into producer and consumer end points
|
/// Splits a statically allocated queue into producer and consumer end points
|
||||||
pub fn split<'rb>(&'rb mut self) -> (Producer<'rb, T, N, U>, Consumer<'rb, T, N, U>) {
|
pub fn split<'rb>(&'rb mut self) -> (Producer<'rb, T, N, U>, Consumer<'rb, T, N, U>) {
|
||||||
(
|
(
|
||||||
Producer {
|
Producer {
|
||||||
@ -26,14 +26,14 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A ring buffer "consumer"; it can dequeue items from the ring buffer
|
/// A queue "consumer"; it can dequeue items from the queue
|
||||||
// NOTE the consumer semantically owns the `head` pointer of the ring buffer
|
// NOTE the consumer semantically owns the `head` pointer of the queue
|
||||||
pub struct Consumer<'a, T, N, U = usize>
|
pub struct Consumer<'a, T, N, U = usize>
|
||||||
where
|
where
|
||||||
N: ArrayLength<T>,
|
N: ArrayLength<T>,
|
||||||
U: sealed::Uxx,
|
U: sealed::Uxx,
|
||||||
{
|
{
|
||||||
rb: NonNull<RingBuffer<T, N, U>>,
|
rb: NonNull<Queue<T, N, U>>,
|
||||||
_marker: PhantomData<&'a ()>,
|
_marker: PhantomData<&'a ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,14 +44,14 @@ where
|
|||||||
U: sealed::Uxx,
|
U: sealed::Uxx,
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// A ring buffer "producer"; it can enqueue items into the ring buffer
|
/// A queue "producer"; it can enqueue items into the queue
|
||||||
// NOTE the producer semantically owns the `tail` pointer of the ring buffer
|
// NOTE the producer semantically owns the `tail` pointer of the queue
|
||||||
pub struct Producer<'a, T, N, U = usize>
|
pub struct Producer<'a, T, N, U = usize>
|
||||||
where
|
where
|
||||||
N: ArrayLength<T>,
|
N: ArrayLength<T>,
|
||||||
U: sealed::Uxx,
|
U: sealed::Uxx,
|
||||||
{
|
{
|
||||||
rb: NonNull<RingBuffer<T, N, U>>,
|
rb: NonNull<Queue<T, N, U>>,
|
||||||
_marker: PhantomData<&'a ()>,
|
_marker: PhantomData<&'a ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,11 +190,11 @@ impl_!(usize);
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use consts::*;
|
use consts::*;
|
||||||
use RingBuffer;
|
use spsc::Queue;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sanity() {
|
fn sanity() {
|
||||||
let mut rb: RingBuffer<i32, U2> = RingBuffer::new();
|
let mut rb: Queue<i32, U2> = Queue::new();
|
||||||
|
|
||||||
let (mut p, mut c) = rb.split();
|
let (mut p, mut c) = rb.split();
|
||||||
|
|
@ -8,13 +8,13 @@ use std::thread;
|
|||||||
|
|
||||||
use generic_array::typenum::Unsigned;
|
use generic_array::typenum::Unsigned;
|
||||||
use heapless::consts::*;
|
use heapless::consts::*;
|
||||||
use heapless::RingBuffer;
|
use heapless::spsc;
|
||||||
use scoped_threadpool::Pool;
|
use scoped_threadpool::Pool;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn once() {
|
fn once() {
|
||||||
static mut RB: Option<RingBuffer<i32, U4>> = None;
|
static mut RB: Option<spsc::Queue<i32, U4>> = None;
|
||||||
unsafe{ RB = Some(RingBuffer::new()) };
|
unsafe { RB = Some(spsc::Queue::new()) };
|
||||||
|
|
||||||
let rb = unsafe { RB.as_mut().unwrap() };
|
let rb = unsafe { RB.as_mut().unwrap() };
|
||||||
|
|
||||||
@ -35,8 +35,8 @@ fn once() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn twice() {
|
fn twice() {
|
||||||
static mut RB: Option<RingBuffer<i32, U4>> = None;
|
static mut RB: Option<spsc::Queue<i32, U4>> = None;
|
||||||
unsafe{ RB = Some(RingBuffer::new()) };
|
unsafe { RB = Some(spsc::Queue::new()) };
|
||||||
|
|
||||||
let rb = unsafe { RB.as_mut().unwrap() };
|
let rb = unsafe { RB.as_mut().unwrap() };
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ fn twice() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn scoped() {
|
fn scoped() {
|
||||||
let mut rb: RingBuffer<i32, U4> = RingBuffer::new();
|
let mut rb: spsc::Queue<i32, U4> = spsc::Queue::new();
|
||||||
|
|
||||||
rb.enqueue(0).unwrap();
|
rb.enqueue(0).unwrap();
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ fn scoped() {
|
|||||||
fn contention() {
|
fn contention() {
|
||||||
type N = U1024;
|
type N = U1024;
|
||||||
|
|
||||||
let mut rb: RingBuffer<u8, N> = RingBuffer::new();
|
let mut rb: spsc::Queue<u8, N> = spsc::Queue::new();
|
||||||
|
|
||||||
{
|
{
|
||||||
let (mut p, mut c) = rb.split();
|
let (mut p, mut c) = rb.split();
|
||||||
@ -127,7 +127,7 @@ fn contention() {
|
|||||||
fn unchecked() {
|
fn unchecked() {
|
||||||
type N = U1024;
|
type N = U1024;
|
||||||
|
|
||||||
let mut rb: RingBuffer<u8, N> = RingBuffer::new();
|
let mut rb: spsc::Queue<u8, N> = spsc::Queue::new();
|
||||||
|
|
||||||
for _ in 0..N::to_usize() / 2 {
|
for _ in 0..N::to_usize() / 2 {
|
||||||
rb.enqueue(1).unwrap();
|
rb.enqueue(1).unwrap();
|
||||||
@ -139,7 +139,9 @@ fn unchecked() {
|
|||||||
Pool::new(2).scoped(move |scope| {
|
Pool::new(2).scoped(move |scope| {
|
||||||
scope.execute(move || {
|
scope.execute(move || {
|
||||||
for _ in 0..N::to_usize() / 2 {
|
for _ in 0..N::to_usize() / 2 {
|
||||||
p.enqueue_unchecked(2);
|
unsafe {
|
||||||
|
p.enqueue_unchecked(2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -161,7 +163,7 @@ fn unchecked() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn len_properly_wraps() {
|
fn len_properly_wraps() {
|
||||||
type N = U3;
|
type N = U3;
|
||||||
let mut rb: RingBuffer<u8, N> = RingBuffer::new();
|
let mut rb: spsc::Queue<u8, N> = spsc::Queue::new();
|
||||||
|
|
||||||
rb.enqueue(1).unwrap();
|
rb.enqueue(1).unwrap();
|
||||||
assert_eq!(rb.len(), 1);
|
assert_eq!(rb.len(), 1);
|
||||||
@ -178,7 +180,7 @@ fn len_properly_wraps() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn iterator_properly_wraps() {
|
fn iterator_properly_wraps() {
|
||||||
type N = U3;
|
type N = U3;
|
||||||
let mut rb: RingBuffer<u8, N> = RingBuffer::new();
|
let mut rb: spsc::Queue<u8, N> = spsc::Queue::new();
|
||||||
|
|
||||||
rb.enqueue(1).unwrap();
|
rb.enqueue(1).unwrap();
|
||||||
rb.dequeue();
|
rb.dequeue();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user