22//!
33//! NOTE: This module is not available on targets that do *not* support CAS operations, e.g. ARMv6-M
44//!
5- //! (\*) Currently, the implementation is only lock-free *and* `Sync` on ARMv7-M devices
5+ //! (\*) Currently, the implementation is only lock-free *and* `Sync` on ARMv7-{A,R,M} & ARMv8-M
6+ //! devices
67//!
78//! # Examples
89//!
5657//! The only counter measure against the ABA problem that this implementation currently takes is
5758//! relying on LL/SC (Link-local / Store-conditional) instructions being used to implement CAS loops
5859//! on the target architecture (see section on ['Soundness'](#soundness) for more information). For
59- //! this reason, `Pool` only implements `Sync` when compiling for ARMv7-M .
60+ //! this reason, `Pool` only implements `Sync` when compiling for some ARM cores .
6061//!
6162//! Also note that ARMv6-M architecture lacks the primitives for CAS loops so this module does *not*
6263//! exist for `thumbv6m-none-eabi`.
113114//! no longer is a valid free node. As a result the stack, and thus the allocator, is in a invalid
114115//! state.
115116//!
116- //! However, not all is lost because Cortex-M devices use LL/SC (Link-local / Store-conditional)
117- //! operations to implement CAS loops. Let's look at the actual disassembly of `pop`.
117+ //! However, not all is lost because ARM devices use LL/SC (Link-local / Store-conditional)
118+ //! operations to implement CAS loops. Let's look at the actual disassembly of `pop` for the ARM
119+ //! Cortex-M.
118120//!
119121//! ``` text
120122//! 08000130 <<heapless::pool::Pool<T>>::pop>:
144146//! always involves taking an exception. Thus the underlying LL/SC operations prevent the ABA
145147//! problem on Cortex-M.
146148//!
149+ //! In the case of multi-core systems if any other core successfully does a STREX op on the head
150+ //! while the current core is somewhere between LDREX and STREX then the current core will fail its
151+ //! STREX operation.
152+ //!
147153//! # References
148154//!
149155//! 1. [Cortex-M3 Devices Generic User Guide (DUI 0552A)][0], Section 2.2.7 "Synchronization
@@ -184,7 +190,7 @@ pub struct Pool<T> {
184190// NOTE: Here we lie about `Pool` implementing `Sync` on x86_64. This is not true but it lets us
185191// test the `pool!` and `singleton::Pool` abstractions. We just have to be careful not to use the
186192// pool in a multi-threaded context
187- #[ cfg( any( armv7m , armv7r, armv8m_main, test) ) ]
193+ #[ cfg( any( armv7a , armv7r, armv7m , armv8m_main, test) ) ]
188194unsafe impl < T > Sync for Pool < T > { }
189195
190196unsafe impl < T > Send for Pool < T > { }
@@ -301,7 +307,7 @@ impl<T> Pool<T> {
301307 Ordering :: Relaxed , // failure
302308 ) {
303309 Ok ( _) => break Some ( nn_head) ,
304- // head was changed by some interrupt handler
310+ // interrupt occurred or other core made a successful STREX op on the head
305311 Err ( _) => continue ,
306312 }
307313 } else {
@@ -325,7 +331,7 @@ impl<T> Pool<T> {
325331 Ordering :: Relaxed , // failure
326332 ) {
327333 Ok ( _) => return ,
328- // head changed
334+ // interrupt occurred or other core made a successful STREX op on the head
329335 Err ( p) => head = p,
330336 }
331337 }
0 commit comments