71: concurrency: small tweaks to the atomics section r=adamgreig a=japaric

r? @adamgreig

Co-authored-by: Jorge Aparicio <jorge@japaric.io>
This commit is contained in:
bors[bot]
2018-11-05 22:59:53 +00:00

View File

@@ -161,9 +161,9 @@ increment operation. These atomic operations are safe even across multiple
cores.
```rust
// New type for COUNTER
use core::sync::atomic;
static mut COUNTER: atomic::AtomicUsize = atomic::ATOMIC_USIZE_INIT;
use core::sync::atomic::{AtomicUsize, Ordering};
static COUNTER: AtomicUsize = AtomicUsize::new(0);
#[entry]
fn main() -> ! {
@@ -174,7 +174,7 @@ fn main() -> ! {
if state && !last_state {
last_state = state;
// Use `fetch_add` to atomically add 1 to COUNTER
unsafe { COUNTER.fetch_add(1, atomic::Ordering::Relaxed) };
COUNTER.fetch_add(1, Ordering::Relaxed);
}
}
}
@@ -182,22 +182,22 @@ fn main() -> ! {
#[interrupt]
fn timer() {
// Use `store` to write 0 directly to COUNTER
unsafe { COUNTER.store(0, atomic::Ordering::Relaxed) }
COUNTER.store(0, Ordering::Relaxed)
}
```
We still require `unsafe` blocks since `COUNTER` is a `static mut`, but we no
longer have the overhead of disabling all interrupts. When possible, this is a
better solution — but it may not be supported on your platform.
This time `COUNTER` is a safe `static` variable. Thanks to the `AtomicUsize`
type `COUNTER` can be safely modified from both the interrupt handler and the
main thread without disabling interrupts. When possible, this is a better
solution — but it may not be supported on your platform.
A note on [`Ordering`]: this affects how the compiler and hardware may reorder
instructions, and also has consequences on cache visibility. For simple atomic
operations like incrementing a counter, where we are not synchronising any
other tasks on the counter, `Relaxed` is sufficient, and will have the best
performance on typical embedded platforms. Stricter ordering will cause the
compiler to emit memory barriers around the atomic operations; depending on
what you're using atomics for you may or may not need this! The precise
details of the atomic model are complicated and best described elsewhere.
instructions, and also has consequences on cache visibility. Assuming that the
target is a single core platform `Relaxed` is sufficient and the most efficient
choice in this particular case. Stricter ordering will cause the compiler to
emit memory barriers around the atomic operations; depending on what you're
using atomics for you may or may not need this! The precise details of the
atomic model are complicated and best described elsewhere.
For more details on atomics and ordering, see the [nomicon].