diff --git a/src/lib.rs b/src/lib.rs index 17f6056dc3..3646e31c6a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,28 +43,84 @@ //! //! List of currently implemented data structures: #![cfg_attr( - any(arm_llsc, target_pointer_width = "32", target_pointer_width = "64"), - doc = "- [`Arc`](pool::arc::Arc) -- like `std::sync::Arc` but backed by a lock-free memory pool rather than `#[global_allocator]`" + any( + arm_llsc, + all( + target_pointer_width = "32", + any(target_has_atomic = "64", feature = "portable-atomic") + ), + all( + target_pointer_width = "64", + any( + all(target_has_atomic = "128", feature = "nightly"), + feature = "portable-atomic" + ) + ) + ), + doc = "- [Arc][pool::arc::Arc] -- like `std::sync::Arc` but backed by a lock-free memory pool rather than [global_allocator]" +)] +#![cfg_attr( + any( + arm_llsc, + all( + target_pointer_width = "32", + any(target_has_atomic = "64", feature = "portable-atomic") + ), + all( + target_pointer_width = "64", + any( + all(target_has_atomic = "128", feature = "nightly"), + feature = "portable-atomic" + ) + ) + ), + doc = "- [Box][pool::boxed::Box] -- like `std::boxed::Box` but backed by a lock-free memory pool rather than [global_allocator]" )] #![cfg_attr( - any(arm_llsc, target_pointer_width = "32", target_pointer_width = "64"), - doc = "- [`Box`](pool::boxed::Box) -- like `std::boxed::Box` but backed by a lock-free memory pool rather than `#[global_allocator]`" + any( + arm_llsc, + all( + target_pointer_width = "32", + any(target_has_atomic = "64", feature = "portable-atomic") + ), + all( + target_pointer_width = "64", + any( + all(target_has_atomic = "128", feature = "nightly"), + feature = "portable-atomic" + ) + ) + ), + doc = "- [Arc][pool::arc::Arc] -- like `std::sync::Arc` but backed by a lock-free memory pool rather than [global_allocator]" )] -//! - [`BinaryHeap`] -- priority queue -//! - [`Deque`] -- double-ended queue -//! - [`HistoryBuffer`] -- similar to a write-only ring buffer -//! - [`IndexMap`] -- hash table -//! - [`IndexSet`] -- hash set -//! - [`LinearMap`] #![cfg_attr( - any(arm_llsc, target_pointer_width = "32", target_pointer_width = "64"), - doc = "- [`Object`](pool::object::Object) -- objects managed by an object pool" + any( + arm_llsc, + all( + target_pointer_width = "32", + any(target_has_atomic = "64", feature = "portable-atomic") + ), + all( + target_pointer_width = "64", + any( + all(target_has_atomic = "128", feature = "nightly"), + feature = "portable-atomic" + ) + ) + ), + doc = "- [Object](pool::object::Object) -- objects managed by an object pool" )] -//! - [`sorted_linked_list::SortedLinkedList`] -//! - [`String`] -//! - [`Vec`] +//! - [BinaryHeap] -- priority queue +//! - [Deque] -- double-ended queue +//! - [HistoryBuffer] -- similar to a write-only ring buffer +//! - [IndexMap] -- hash table +//! - [IndexSet] -- hash set +//! - [LinearMap] +//! - [sorted_linked_list::SortedLinkedList] +//! - [String] +//! - [Vec] //! - [`mpmc::Q*`](mpmc) -- multiple producer multiple consumer lock-free queue -//! - [`spsc::Queue`] -- single producer single consumer lock-free queue +//! - [spsc] and [spsc::Queue] -- single producer single consumer lock-free queue //! //! # Minimum Supported Rust Version (MSRV) //! diff --git a/src/spsc.rs b/src/spsc.rs index 5807f5387b..242992181d 100644 --- a/src/spsc.rs +++ b/src/spsc.rs @@ -1,8 +1,8 @@ -//! A fixed capacity Single Producer Single Consumer (SPSC) queue. +//! # A fixed capacity Single Producer Single Consumer (SPSC) queue. //! //! Implementation based on //! -//! # Portability +//! ## Portability //! //! This module requires CAS atomic instructions which are not available on all architectures //! (e.g. ARMv6-M (`thumbv6m-none-eabi`) and MSP430 (`msp430-none-elf`)). These atomics can be @@ -10,9 +10,9 @@ //! enabled with the `cas` feature and is enabled by default for `thumbv6m-none-eabi` and `riscv32` //! targets. //! -//! # Examples +//! ## Examples //! -//! - `Queue` can be used as a plain queue +//! - [Queue] can be used as a plain queue //! //! ``` //! use heapless::spsc::Queue; @@ -27,12 +27,16 @@ //! assert_eq!(rb.dequeue(), Some(0)); //! ``` //! -//! - `Queue` can be `split` and then be used in Single Producer Single Consumer mode. +//! - [Queue] can be [Queue::split] and then be used in Single Producer Single Consumer mode. //! //! "no alloc" applications can create a `&'static mut` reference to a `Queue` -- using a static //! variable -- and then `split` it: this consumes the static reference. The resulting `Consumer` //! and `Producer` can then be moved into different execution contexts (threads, interrupt handlers, -//! etc.) +//! etc.). +//! +//! Alternatively, you can also create the Queue statically in the global scope by wrapping it with +//! a [static_cell](https://docs.rs/static_cell/latest/static_cell/) +//! //! //! ``` //! use heapless::spsc::{Producer, Queue}; @@ -43,6 +47,8 @@ //! } //! //! fn main() { +//! // Alternatively, use something like `static_cell` to create the `Queue` in the global +//! // scope. //! let queue: &'static mut Queue = { //! static mut Q: Queue = Queue::new(); //! unsafe { &mut Q }