mirror of
https://github.com/rust-embedded/heapless.git
synced 2025-10-03 07:14:45 +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");
|
println!("cargo:rustc-cfg=armv8m_base");
|
||||||
} else if target.starts_with("thumbv8m.main") {
|
} else if target.starts_with("thumbv8m.main") {
|
||||||
println!("cargo:rustc-cfg=armv8m_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
|
// 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
|
//! 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
|
//! # Examples
|
||||||
//!
|
//!
|
||||||
@ -56,7 +57,7 @@
|
|||||||
//! The only counter measure against the ABA problem that this implementation currently takes is
|
//! 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
|
//! 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
|
//! 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*
|
//! Also note that ARMv6-M architecture lacks the primitives for CAS loops so this module does *not*
|
||||||
//! exist for `thumbv6m-none-eabi`.
|
//! 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
|
//! no longer is a valid free node. As a result the stack, and thus the allocator, is in a invalid
|
||||||
//! state.
|
//! state.
|
||||||
//!
|
//!
|
||||||
//! However, not all is lost because Cortex-M devices use LL/SC (Link-local / Store-conditional)
|
//! 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`.
|
//! operations to implement CAS loops. Let's look at the actual disassembly of `pop` for the ARM
|
||||||
|
//! Cortex-M.
|
||||||
//!
|
//!
|
||||||
//! ``` text
|
//! ``` text
|
||||||
//! 08000130 <<heapless::pool::Pool<T>>::pop>:
|
//! 08000130 <<heapless::pool::Pool<T>>::pop>:
|
||||||
@ -144,6 +146,10 @@
|
|||||||
//! always involves taking an exception. Thus the underlying LL/SC operations prevent the ABA
|
//! always involves taking an exception. Thus the underlying LL/SC operations prevent the ABA
|
||||||
//! problem on Cortex-M.
|
//! 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
|
//! # References
|
||||||
//!
|
//!
|
||||||
//! 1. [Cortex-M3 Devices Generic User Guide (DUI 0552A)][0], Section 2.2.7 "Synchronization
|
//! 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
|
// 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
|
// test the `pool!` and `singleton::Pool` abstractions. We just have to be careful not to use the
|
||||||
// pool in a multi-threaded context
|
// 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> Sync for Pool<T> {}
|
||||||
|
|
||||||
unsafe impl<T> Send for Pool<T> {}
|
unsafe impl<T> Send for Pool<T> {}
|
||||||
@ -301,7 +307,7 @@ impl<T> Pool<T> {
|
|||||||
Ordering::Relaxed, // failure
|
Ordering::Relaxed, // failure
|
||||||
) {
|
) {
|
||||||
Ok(_) => break Some(nn_head),
|
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,
|
Err(_) => continue,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -325,7 +331,7 @@ impl<T> Pool<T> {
|
|||||||
Ordering::Relaxed, // failure
|
Ordering::Relaxed, // failure
|
||||||
) {
|
) {
|
||||||
Ok(_) => return,
|
Ok(_) => return,
|
||||||
// head changed
|
// interrupt occurred or other core made a successful STREX op on the head
|
||||||
Err(p) => head = p,
|
Err(p) => head = p,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ use as_slice::{AsMutSlice, AsSlice};
|
|||||||
use super::{Init, Node, Uninit};
|
use super::{Init, Node, Uninit};
|
||||||
|
|
||||||
/// Instantiates a pool as a global singleton
|
/// 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_export]
|
||||||
macro_rules! pool {
|
macro_rules! pool {
|
||||||
($(#[$($attr:tt)*])* $ident:ident: $ty:ty) => {
|
($(#[$($attr:tt)*])* $ident:ident: $ty:ty) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user