mirror of
https://github.com/rust-embedded/heapless.git
synced 2025-10-02 14:54:30 +00:00
Merge #140
140: extend singleton pool! support to ARMv7-A r=japaric a=japaric Co-authored-by: Jorge Aparicio <jorge.aparicio@ferrous-systems.com>
This commit is contained in:
commit
b6bd3af38d
2
build.rs
2
build.rs
@ -17,6 +17,8 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
println!("cargo:rustc-cfg=armv8m_base");
|
||||
} else if target.starts_with("thumbv8m.main") {
|
||||
println!("cargo:rustc-cfg=armv8m_main");
|
||||
} else if target.starts_with("armv7-") {
|
||||
println!("cargo:rustc-cfg=armv7a");
|
||||
}
|
||||
|
||||
// built-in targets with no atomic / CAS support as of nightly-2019-12-17
|
||||
|
@ -2,7 +2,8 @@
|
||||
//!
|
||||
//! NOTE: This module is not available on targets that do *not* support CAS operations, e.g. ARMv6-M
|
||||
//!
|
||||
//! (\*) Currently, the implementation is only lock-free *and* `Sync` on ARMv7-M devices
|
||||
//! (\*) Currently, the implementation is only lock-free *and* `Sync` on ARMv7-{A,R,M} & ARMv8-M
|
||||
//! devices
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
@ -56,7 +57,7 @@
|
||||
//! The only counter measure against the ABA problem that this implementation currently takes is
|
||||
//! relying on LL/SC (Link-local / Store-conditional) instructions being used to implement CAS loops
|
||||
//! on the target architecture (see section on ['Soundness'](#soundness) for more information). For
|
||||
//! this reason, `Pool` only implements `Sync` when compiling for ARMv7-M.
|
||||
//! this reason, `Pool` only implements `Sync` when compiling for some ARM cores.
|
||||
//!
|
||||
//! Also note that ARMv6-M architecture lacks the primitives for CAS loops so this module does *not*
|
||||
//! exist for `thumbv6m-none-eabi`.
|
||||
@ -113,8 +114,9 @@
|
||||
//! no longer is a valid free node. As a result the stack, and thus the allocator, is in a invalid
|
||||
//! state.
|
||||
//!
|
||||
//! However, not all is lost because Cortex-M devices use LL/SC (Link-local / Store-conditional)
|
||||
//! operations to implement CAS loops. Let's look at the actual disassembly of `pop`.
|
||||
//! However, not all is lost because ARM devices use LL/SC (Link-local / Store-conditional)
|
||||
//! operations to implement CAS loops. Let's look at the actual disassembly of `pop` for the ARM
|
||||
//! Cortex-M.
|
||||
//!
|
||||
//! ``` text
|
||||
//! 08000130 <<heapless::pool::Pool<T>>::pop>:
|
||||
@ -144,6 +146,10 @@
|
||||
//! always involves taking an exception. Thus the underlying LL/SC operations prevent the ABA
|
||||
//! problem on Cortex-M.
|
||||
//!
|
||||
//! In the case of multi-core systems if any other core successfully does a STREX op on the head
|
||||
//! while the current core is somewhere between LDREX and STREX then the current core will fail its
|
||||
//! STREX operation.
|
||||
//!
|
||||
//! # References
|
||||
//!
|
||||
//! 1. [Cortex-M3 Devices Generic User Guide (DUI 0552A)][0], Section 2.2.7 "Synchronization
|
||||
@ -184,7 +190,7 @@ pub struct Pool<T> {
|
||||
// NOTE: Here we lie about `Pool` implementing `Sync` on x86_64. This is not true but it lets us
|
||||
// test the `pool!` and `singleton::Pool` abstractions. We just have to be careful not to use the
|
||||
// pool in a multi-threaded context
|
||||
#[cfg(any(armv7m, armv7r, armv8m_main, test))]
|
||||
#[cfg(any(armv7a, armv7r, armv7m, armv8m_main, test))]
|
||||
unsafe impl<T> Sync for Pool<T> {}
|
||||
|
||||
unsafe impl<T> Send for Pool<T> {}
|
||||
@ -301,7 +307,7 @@ impl<T> Pool<T> {
|
||||
Ordering::Relaxed, // failure
|
||||
) {
|
||||
Ok(_) => break Some(nn_head),
|
||||
// head was changed by some interrupt handler
|
||||
// interrupt occurred or other core made a successful STREX op on the head
|
||||
Err(_) => continue,
|
||||
}
|
||||
} else {
|
||||
@ -325,7 +331,7 @@ impl<T> Pool<T> {
|
||||
Ordering::Relaxed, // failure
|
||||
) {
|
||||
Ok(_) => return,
|
||||
// head changed
|
||||
// interrupt occurred or other core made a successful STREX op on the head
|
||||
Err(p) => head = p,
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use as_slice::{AsMutSlice, AsSlice};
|
||||
use super::{Init, Node, Uninit};
|
||||
|
||||
/// Instantiates a pool as a global singleton
|
||||
#[cfg(any(armv7m, armv7r, armv8m_main, test))]
|
||||
#[cfg(any(armv7a, armv7r, armv7m, armv8m_main, test))]
|
||||
#[macro_export]
|
||||
macro_rules! pool {
|
||||
($(#[$($attr:tt)*])* $ident:ident: $ty:ty) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user