Skip to content

Commit b6bd3af

Browse files
bors[bot]japaric
andauthored
Merge #140
140: extend singleton pool! support to ARMv7-A r=japaric a=japaric Co-authored-by: Jorge Aparicio <jorge.aparicio@ferrous-systems.com>
2 parents f9689ff + 646c565 commit b6bd3af

File tree

3 files changed

+16
-8
lines changed

3 files changed

+16
-8
lines changed

build.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ fn main() -> Result<(), Box<dyn Error>> {
1717
println!("cargo:rustc-cfg=armv8m_base");
1818
} else if target.starts_with("thumbv8m.main") {
1919
println!("cargo:rustc-cfg=armv8m_main");
20+
} else if target.starts_with("armv7-") {
21+
println!("cargo:rustc-cfg=armv7a");
2022
}
2123

2224
// built-in targets with no atomic / CAS support as of nightly-2019-12-17

src/pool/mod.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
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
//!
@@ -56,7 +57,7 @@
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`.
@@ -113,8 +114,9 @@
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>:
@@ -144,6 +146,10 @@
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))]
188194
unsafe impl<T> Sync for Pool<T> {}
189195

190196
unsafe 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
}

src/pool/singleton.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use as_slice::{AsMutSlice, AsSlice};
1515
use super::{Init, Node, Uninit};
1616

1717
/// Instantiates a pool as a global singleton
18-
#[cfg(any(armv7m, armv7r, armv8m_main, test))]
18+
#[cfg(any(armv7a, armv7r, armv7m, armv8m_main, test))]
1919
#[macro_export]
2020
macro_rules! pool {
2121
($(#[$($attr:tt)*])* $ident:ident: $ty:ty) => {

0 commit comments

Comments
 (0)