diff --git a/CHANGELOG.md b/CHANGELOG.md index 246d823604..447932d681 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added +- Added `mpmc` and `spsc` features. - Added `bytes::Buf` and `bytes::BufMut` implementations for `Vec`. - Added `format` macro. - Added `String::from_utf16`. @@ -98,6 +99,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - The `MpMcQueueView` type has been renamed to `QueueView`. - The `MpMcQueueInner` type has been renamed to `QueueInner`. - Remove `Q*` type aliases for `MpMcQueue`, and rename it to just `Queue` +- The `HistoryBuffer` type has been renamed to `HistoryBuf`. +- The `HistoryBufferView` type has been renamed to `HistoryBufView`. +- The `OwnedHistBufStorage` type has been renamed to `OwnedHistoryBufStorage`. +- The `ViewHistBufStorage` type has been renamed to `ViewHistoryBufStorage`. +- The `MpMcQueue` type has been renamed to `Queue`. +- The `MpMcQueueView` type has been renamed to `QueueView`. +- The `MpMcQueueInner` type has been renamed to `QueueInner`. - Changed `Queue::split` to be `const`. ### Fixed @@ -443,7 +451,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - The `pool!` macro now accepts attributes. -- `mpmc::Q*` a family of fixed capacity multiple-producer multiple-consumer +- `mpmc::Q*` a family of fixed capacity multi-producer multi-consumer lock-free queues. ### Changed diff --git a/Cargo.toml b/Cargo.toml index b259387798..8c7fbd7961 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,40 +15,53 @@ repository = "https://github.com/rust-embedded/heapless" version = "0.9.0" [features] +default = ["mpmc", "spsc"] + +# Enable interoperability with `alloc` types. +alloc = [] + bytes = ["dep:bytes"] +# Enable the `mpmc` module. +mpmc = ["portable-atomic?/require-cas"] +# Enable larger sizes for `mpmc::Queue`. +mpmc_large = [] + +# Enable the `spsc` module. +spsc = [] + # Enable polyfilling of atomics via `portable-atomic`. # `portable-atomic` polyfills some functionality by default, but to get full atomics you must # enable one of its features to tell it how to do it. See `portable-atomic` documentation for details. portable-atomic = ["dep:portable-atomic"] # Enable polyfilling of atomics via portable-atomic, using critical section for locking -portable-atomic-critical-section = ["dep:portable-atomic", "portable-atomic", "portable-atomic?/critical-section"] +portable-atomic-critical-section = [ + "dep:portable-atomic", + "portable-atomic", + "portable-atomic?/critical-section", +] # Enable polyfilling of atomics via portable-atomic, using disabling interrupts for locking. # WARNING: this is only sound for single-core bare-metal privileged-mode targets! -portable-atomic-unsafe-assume-single-core = ["dep:portable-atomic", "portable-atomic", "portable-atomic?/unsafe-assume-single-core"] +portable-atomic-unsafe-assume-single-core = [ + "dep:portable-atomic", + "portable-atomic", + "portable-atomic?/unsafe-assume-single-core", +] -# implement serde traits. +# Implement `serde` traits. serde = ["dep:serde"] - -# implement ufmt traits. +# Implement `ufmt` traits. ufmt = ["dep:ufmt", "dep:ufmt-write"] - -# Implement `defmt::Format`. +# Implement `defmt` traits. defmt = ["dep:defmt"] -# Enable larger MPMC sizes. -mpmc_large = [] - -# Implement some alloc Vec interoperability -alloc = [] - nightly = [] [dependencies] bytes = { version = "1", default-features = false, optional = true } -portable-atomic = { version = "1.0", optional = true } +portable-atomic = { version = "1.3", optional = true } hash32 = "0.3.0" serde = { version = "1", optional = true, default-features = false } ufmt = { version = "0.2", optional = true } @@ -65,13 +78,13 @@ static_assertions = "1.1.0" [package.metadata.docs.rs] features = [ + "alloc", "bytes", + "mpmc_large", "ufmt", "serde", "defmt", - "mpmc_large", "portable-atomic-critical-section", - "alloc", ] # for the pool module targets = ["i686-unknown-linux-gnu"] diff --git a/src/lib.rs b/src/lib.rs index 80c57dfd8b..e6d8d11eea 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -117,11 +117,11 @@ //! - [`IndexMap`]: A hash table. //! - [`IndexSet`]: A hash set. //! - [`LinearMap`]: A linear map. +//! - [`mpmc::Queue`](mpmc): A lock-free multi-producer, multi-consumer queue. +//! - [`spsc::Queue`](spsc): A lock-free single-producer, single-consumer queue. //! - [`SortedLinkedList`](sorted_linked_list::SortedLinkedList): A sorted linked list. //! - [`String`]: A string. //! - [`Vec`]: A vector. -//! - [`mpmc::MpMcQueue`](mpmc): A lock-free multiple-producer, multiple-consumer queue. -//! - [`spsc::Queue`](spsc): A lock-free single-producer, single-consumer queue. //! //! # Minimum Supported Rust Version (MSRV) //! @@ -199,12 +199,15 @@ pub mod binary_heap; mod bytes; #[cfg(feature = "defmt")] mod defmt; -#[cfg(any( - // assume we have all atomics available if we're using portable-atomic - feature = "portable-atomic", - // target has native atomic CAS (mpmc_large requires usize, otherwise just u8) - all(feature = "mpmc_large", target_has_atomic = "ptr"), - all(not(feature = "mpmc_large"), target_has_atomic = "8") +#[cfg(all( + feature = "mpmc", + any( + // Assume all atomics are available if we're using `portable-atomic`. + feature = "portable-atomic", + // Target has native atomic CAS (`mpmc_large` requires `usize`, otherwise just `u8`). + all(feature = "mpmc_large", target_has_atomic = "ptr"), + all(not(feature = "mpmc_large"), target_has_atomic = "8"), + ) ))] pub mod mpmc; #[cfg(any( @@ -223,14 +226,17 @@ pub mod mpmc; ))] pub mod pool; pub mod sorted_linked_list; -#[cfg(any( - // assume we have all atomics available if we're using portable-atomic - feature = "portable-atomic", - // target has native atomic CAS. Note this is too restrictive, spsc requires load/store only, not CAS. - // This should be `cfg(target_has_atomic_load_store)`, but that's not stable yet. - target_has_atomic = "ptr", - // or the current target is in a list in build.rs of targets known to have load/store but no CAS. - has_atomic_load_store +#[cfg(all( + feature = "spsc", + any( + // Assume all atomics are available if we're using `portable-atomic`. + feature = "portable-atomic", + // Target has native atomic CAS. This is too restrictive since `spsc` only requires + // load/store, but `cfg(target_has_atomic_load_store = "ptr")` is not stable yet. + target_has_atomic = "ptr", + // The current target is in a list in `build.rs` known to have load/store but no CAS. + has_atomic_load_store, + ) ))] pub mod spsc; diff --git a/src/mpmc.rs b/src/mpmc.rs index f676c7c93a..daaa32f83b 100644 --- a/src/mpmc.rs +++ b/src/mpmc.rs @@ -1,4 +1,4 @@ -//! A fixed capacity multiple-producer, multiple-consumer (MPMC) lock-free queue. +//! A lock-free multi-producer, multi-consumer (MPMC) queue with fixed capacity. //! //! **Note:** This module requires atomic compare-and-swap (CAS) instructions. On //! targets where they're not natively available, they are emulated by the diff --git a/src/spsc.rs b/src/spsc.rs index eb206456a8..2257fb752a 100644 --- a/src/spsc.rs +++ b/src/spsc.rs @@ -1,6 +1,6 @@ -//! A fixed capacity single-producer, single-consumer (SPSC) lock-free queue. +//! A lock-free single-producer, single-consumer (SPSC) queue with fixed capacity. //! -//! *Note:* This module requires atomic load and store instructions. On +//! **Note:** This module requires atomic load and store instructions. On //! targets where they're not natively available, they are emulated by the //! [`portable-atomic`](https://crates.io/crates/portable-atomic) crate. //!