Skip to content

Commit 8f6dc81

Browse files
committed
Use portable-atomic instead of atomic-polyfill.
1 parent 9094278 commit 8f6dc81

File tree

6 files changed

+63
-58
lines changed

6 files changed

+63
-58
lines changed

.github/workflows/build.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ jobs:
8484
- nightly
8585
features:
8686
- ""
87-
- "cas"
87+
- "cas,portable-atomic/critical-section"
8888
- "serde"
8989
steps:
9090
- name: Checkout

CHANGELOG.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
3131
- [breaking-change] export `IndexMapKeys`, `IndexMapValues` and
3232
`IndexMapValuesMut` iterator types.
3333

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

3737
### Fixed
3838

Cargo.toml

+9-6
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,19 +26,22 @@ 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 = "1.0", optional = true }
3030

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

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

3740
[target.xtensa-esp32s2-none-elf.dependencies]
38-
atomic-polyfill = { version = "1.0.1" }
41+
portable-atomic = { version = "1.0", optional = true }
3942

4043
[target.'cfg(target_arch = "avr")'.dependencies]
41-
atomic-polyfill = { version = "1.0.1", optional = true }
44+
portable-atomic = { version = "1.0", optional = true }
4245

4346
[dependencies]
4447
hash32 = "0.3.0"

build.rs

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

3030
let is_avr = env::var("CARGO_CFG_TARGET_ARCH").as_deref() == Ok("avr");
3131

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

4955
_ => {
@@ -55,34 +61,27 @@ fn main() -> Result<(), Box<dyn Error>> {
5561
if is_avr {
5662
// lacks atomics
5763
} else {
58-
match &target[..] {
59-
"msp430-none-elf"
60-
// | "riscv32i-unknown-none-elf" // supported by atomic-polyfill
61-
// | "riscv32imc-unknown-none-elf" // supported by atomic-polyfill
62-
=> {}
63-
64-
_ => {
65-
println!("cargo:rustc-cfg=has_atomics");
66-
}
64+
println!("cargo:rustc-cfg=has_atomics");
6765
}
68-
};
6966

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

8483
"thumbv6m-none-eabi" => {
85-
println!("cargo:rustc-cfg=cas_atomic_polyfill");
84+
println!("cargo:rustc-cfg=use_portable_atomic_cas");
8685
}
8786
_ => {}
8887
}

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)