Skip to content

Commit 9f0d39d

Browse files
committed
Use portable-atomic instead of atomic-polyfill.
1 parent 2bf9286 commit 9f0d39d

File tree

6 files changed

+66
-56
lines changed

6 files changed

+66
-56
lines changed

.github/workflows/build.yml

+4
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ jobs:
126126
target: ${{ matrix.target }}
127127
override: true
128128

129+
- name: Export variables
130+
run: |
131+
echo RUSTFLAGS="--cfg=portable_atomic_unsafe_assume_single_core" >> $GITHUB_ENV
132+
129133
- name: cargo check
130134
uses: actions-rs/cargo@v1
131135
with:

CHANGELOG.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
2323
- [breaking-change] changed the target support of memory pool API to only support 32-bit x86 and a
2424
subset of ARM targets. See the module level documentation of the `pool` module for details
2525

26-
- [breaking-change] this crate now depends on `atomic-polyfill` v1.0.1, meaning that targets that
27-
require a polyfill need a `critical-section` **v1.x.x** implementation.
26+
- [breaking-change] this crate now uses `portable-atomic` v0.3 instead of `atomic-polyfill` for emulating
27+
CAS instructions on targets where they're not natively available.
2828

2929
### Fixed
3030

Cargo.toml

+8-5
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ version = "0.8.0"
1616

1717
[features]
1818
default = ["cas"]
19-
cas = ["atomic-polyfill"]
19+
cas = ["portable-atomic"]
2020
ufmt-impl = ["ufmt-write"]
2121
# only for tests
2222
__trybuild = []
@@ -26,16 +26,19 @@ mpmc_large = []
2626
defmt-impl = ["defmt"]
2727

2828
[target.thumbv6m-none-eabi.dependencies]
29-
atomic-polyfill = { version = "1.0.1", optional = true }
29+
portable-atomic = { version = "0.3.18", optional = true }
3030

3131
[target.riscv32i-unknown-none-elf.dependencies]
32-
atomic-polyfill = { version = "1.0.1" }
32+
portable-atomic = { version = "0.3.18" }
3333

3434
[target.riscv32imc-unknown-none-elf.dependencies]
35-
atomic-polyfill = { version = "1.0.1" }
35+
portable-atomic = { version = "0.3.18" }
36+
37+
[target.msp430-none-elf.dependencies]
38+
portable-atomic = { version = "0.3.18" }
3639

3740
[target.'cfg(target_arch = "avr")'.dependencies]
38-
atomic-polyfill = { version = "1.0.1", optional = true }
41+
portable-atomic = { version = "0.3.18", optional = true }
3942

4043
[dependencies]
4144
hash32 = "0.3.0"

build.rs

+24-24
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,14 @@ fn main() -> Result<(), Box<dyn Error>> {
3131

3232
let is_avr = env::var("CARGO_CFG_TARGET_ARCH").as_deref() == Ok("avr");
3333

34+
// Set some cfg's depending on the target.
35+
// - has_atomics: atomic load/store is available (either natively or through portable-atomic)
36+
// - has_cas: atomic CAS is available (either natively or through portable-atomic)
37+
// - use_portable_atomic: Use portable-atomic for all atomics (load/store and CAS).
38+
// - use_portable_atomic_cas: Use portable-atomic for CAS atomic operations. Load/store can keep using core::sync:atomic.
39+
3440
// built-in targets with no atomic / CAS support as of nightly-2022-01-13
35-
// AND not supported by the atomic-polyfill crate
41+
// AND not supported by the portable-atomic crate
3642
// see the `no-atomics.sh` / `no-cas.sh` script sitting next to this file
3743
if is_avr {
3844
// lacks cas
@@ -41,11 +47,11 @@ fn main() -> Result<(), Box<dyn Error>> {
4147
"avr-unknown-gnu-atmega328"
4248
| "bpfeb-unknown-none"
4349
| "bpfel-unknown-none"
44-
| "msp430-none-elf"
45-
// | "riscv32i-unknown-none-elf" // supported by atomic-polyfill
46-
// | "riscv32imc-unknown-none-elf" // supported by atomic-polyfill
47-
| "thumbv4t-none-eabi"
48-
// | "thumbv6m-none-eabi" // supported by atomic-polyfill
50+
// | "msp430-none-elf" // supported by portable-atomic
51+
// | "riscv32i-unknown-none-elf" // supported by portable-atomic
52+
// | "riscv32imc-unknown-none-elf" // supported by portable-atomic
53+
// | "thumbv4t-none-eabi" // supported by portable-atomic
54+
// | "thumbv6m-none-eabi" // supported by portable-atomic
4955
=> {}
5056

5157
_ => {
@@ -57,32 +63,26 @@ fn main() -> Result<(), Box<dyn Error>> {
5763
if is_avr {
5864
// lacks atomics
5965
} else {
60-
match &target[..] {
61-
"msp430-none-elf"
62-
// | "riscv32i-unknown-none-elf" // supported by atomic-polyfill
63-
// | "riscv32imc-unknown-none-elf" // supported by atomic-polyfill
64-
=> {}
65-
66-
_ => {
67-
println!("cargo:rustc-cfg=has_atomics");
68-
}
66+
println!("cargo:rustc-cfg=has_atomics");
6967
}
70-
};
7168

72-
// Let the code know if it should use atomic-polyfill or not, and what aspects
73-
// of polyfill it requires
69+
// Let the code know if it should use portable-atomic or not, for either
70+
// only CAS, or for all atomics.
7471
if is_avr {
75-
println!("cargo:rustc-cfg=full_atomic_polyfill");
76-
println!("cargo:rustc-cfg=cas_atomic_polyfill");
72+
println!("cargo:rustc-cfg=use_portable_atomic");
73+
println!("cargo:rustc-cfg=use_portable_atomic_cas");
7774
} else {
7875
match &target[..] {
79-
"riscv32i-unknown-none-elf" | "riscv32imc-unknown-none-elf" => {
80-
println!("cargo:rustc-cfg=full_atomic_polyfill");
81-
println!("cargo:rustc-cfg=cas_atomic_polyfill");
76+
"riscv32i-unknown-none-elf"
77+
| "riscv32imc-unknown-none-elf"
78+
| "thumbv4t-none-eabi"
79+
| "msp430-none-elf" => {
80+
println!("cargo:rustc-cfg=use_portable_atomic");
81+
println!("cargo:rustc-cfg=use_portable_atomic_cas");
8282
}
8383

8484
"thumbv6m-none-eabi" => {
85-
println!("cargo:rustc-cfg=cas_atomic_polyfill");
85+
println!("cargo:rustc-cfg=use_portable_atomic_cas");
8686
}
8787
_ => {}
8888
}

src/mpmc.rs

+15-19
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
//! A fixed capacity Multiple-Producer Multiple-Consumer (MPMC) lock-free queue
22
//!
3-
//! NOTE: This module is not available on targets that do *not* support CAS operations and are not
4-
//! emulated by the [`atomic_polyfill`](https://crates.io/crates/atomic-polyfill) crate (e.g.,
5-
//! MSP430).
3+
//! NOTE: This module requires atomic CAS operations. On targets where they're not natively available,
4+
//! they are emulated by the [`portable-atomic`](https://crates.io/crates/portable-atomic) crate.
65
//!
76
//! # Example
87
//!
@@ -77,10 +76,9 @@
7776
//!
7877
//! This module requires CAS atomic instructions which are not available on all architectures
7978
//! (e.g. ARMv6-M (`thumbv6m-none-eabi`) and MSP430 (`msp430-none-elf`)). These atomics can be
80-
//! emulated however with [`atomic_polyfill`](https://crates.io/crates/atomic-polyfill), which is
79+
//! emulated however with [`portable-atomic`](https://crates.io/crates/portable-atomic), which is
8180
//! enabled with the `cas` feature and is enabled by default for `thumbv6m-none-eabi` and `riscv32`
82-
//! targets. MSP430 is currently not supported by
83-
//! [`atomic_polyfill`](https://crates.io/crates/atomic-polyfill).
81+
//! targets.
8482
//!
8583
//! # References
8684
//!
@@ -90,19 +88,17 @@
9088
9189
use core::{cell::UnsafeCell, mem::MaybeUninit};
9290

93-
#[cfg(all(feature = "mpmc_large", not(cas_atomic_polyfill)))]
94-
type AtomicTargetSize = core::sync::atomic::AtomicUsize;
95-
#[cfg(all(feature = "mpmc_large", cas_atomic_polyfill))]
96-
type AtomicTargetSize = atomic_polyfill::AtomicUsize;
97-
#[cfg(all(not(feature = "mpmc_large"), not(cas_atomic_polyfill)))]
98-
type AtomicTargetSize = core::sync::atomic::AtomicU8;
99-
#[cfg(all(not(feature = "mpmc_large"), cas_atomic_polyfill))]
100-
type AtomicTargetSize = atomic_polyfill::AtomicU8;
101-
102-
#[cfg(not(cas_atomic_polyfill))]
103-
type Ordering = core::sync::atomic::Ordering;
104-
#[cfg(cas_atomic_polyfill)]
105-
type Ordering = atomic_polyfill::Ordering;
91+
#[cfg(not(use_portable_atomic_cas))]
92+
use core::sync::atomic;
93+
#[cfg(use_portable_atomic_cas)]
94+
use portable_atomic as atomic;
95+
96+
use atomic::Ordering;
97+
98+
#[cfg(feature = "mpmc_large")]
99+
type AtomicTargetSize = atomic::AtomicUsize;
100+
#[cfg(not(feature = "mpmc_large"))]
101+
type AtomicTargetSize = atomic::AtomicU8;
106102

107103
#[cfg(feature = "mpmc_large")]
108104
type IntSize = usize;

src/spsc.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@
22
//!
33
//! Implementation based on <https://www.codeproject.com/Articles/43510/Lock-Free-Single-Producer-Single-Consumer-Circular>
44
//!
5-
//! NOTE: This module is not available on targets that do *not* support atomic loads and are not
6-
//! supported by [`atomic_polyfill`](https://crates.io/crates/atomic-polyfill). (e.g., MSP430).
5+
//! # Portability
6+
//!
7+
//! This module requires CAS atomic instructions which are not available on all architectures
8+
//! (e.g. ARMv6-M (`thumbv6m-none-eabi`) and MSP430 (`msp430-none-elf`)). These atomics can be
9+
//! emulated however with [`portable-atomic`](https://crates.io/crates/portable-atomic), which is
10+
//! enabled with the `cas` feature and is enabled by default for `thumbv6m-none-eabi` and `riscv32`
11+
//! targets.
712
//!
813
//! # Examples
914
//!
@@ -91,10 +96,12 @@
9196
9297
use core::{cell::UnsafeCell, fmt, hash, mem::MaybeUninit, ptr};
9398

94-
#[cfg(full_atomic_polyfill)]
95-
use atomic_polyfill::{AtomicUsize, Ordering};
96-
#[cfg(not(full_atomic_polyfill))]
97-
use core::sync::atomic::{AtomicUsize, Ordering};
99+
#[cfg(not(use_portable_atomic))]
100+
use core::sync::atomic;
101+
#[cfg(use_portable_atomic)]
102+
use portable_atomic as atomic;
103+
104+
use atomic::{AtomicUsize, Ordering};
98105

99106
/// A statically allocated single producer single consumer queue with a capacity of `N - 1` elements
100107
///

0 commit comments

Comments
 (0)