2
2
//!
3
3
//! NOTE: This module is not available on targets that do *not* support CAS operations, e.g. ARMv6-M
4
4
//!
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
6
7
//!
7
8
//! # Examples
8
9
//!
56
57
//! The only counter measure against the ABA problem that this implementation currently takes is
57
58
//! relying on LL/SC (Link-local / Store-conditional) instructions being used to implement CAS loops
58
59
//! 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 .
60
61
//!
61
62
//! Also note that ARMv6-M architecture lacks the primitives for CAS loops so this module does *not*
62
63
//! exist for `thumbv6m-none-eabi`.
113
114
//! no longer is a valid free node. As a result the stack, and thus the allocator, is in a invalid
114
115
//! state.
115
116
//!
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.
118
120
//!
119
121
//! ``` text
120
122
//! 08000130 <<heapless::pool::Pool<T>>::pop>:
144
146
//! always involves taking an exception. Thus the underlying LL/SC operations prevent the ABA
145
147
//! problem on Cortex-M.
146
148
//!
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
+ //!
147
153
//! # References
148
154
//!
149
155
//! 1. [Cortex-M3 Devices Generic User Guide (DUI 0552A)][0], Section 2.2.7 "Synchronization
@@ -184,7 +190,7 @@ pub struct Pool<T> {
184
190
// NOTE: Here we lie about `Pool` implementing `Sync` on x86_64. This is not true but it lets us
185
191
// test the `pool!` and `singleton::Pool` abstractions. We just have to be careful not to use the
186
192
// pool in a multi-threaded context
187
- #[ cfg( any( armv7m , armv7r, armv8m_main, test) ) ]
193
+ #[ cfg( any( armv7a , armv7r, armv7m , armv8m_main, test) ) ]
188
194
unsafe impl < T > Sync for Pool < T > { }
189
195
190
196
unsafe impl < T > Send for Pool < T > { }
@@ -301,7 +307,7 @@ impl<T> Pool<T> {
301
307
Ordering :: Relaxed , // failure
302
308
) {
303
309
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
305
311
Err ( _) => continue ,
306
312
}
307
313
} else {
@@ -325,7 +331,7 @@ impl<T> Pool<T> {
325
331
Ordering :: Relaxed , // failure
326
332
) {
327
333
Ok ( _) => return ,
328
- // head changed
334
+ // interrupt occurred or other core made a successful STREX op on the head
329
335
Err ( p) => head = p,
330
336
}
331
337
}
0 commit comments