Skip to content

Commit

Permalink
Implement cfg portable_atomic_critical_section
Browse files Browse the repository at this point in the history
  • Loading branch information
BjornTheProgrammer committed Aug 4, 2024
1 parent 0b9d502 commit 6c2a301
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 53 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ RUSTFLAGS="--cfg portable_atomic_no_outline_atomics" cargo ...

Originally, we were providing these as cfgs instead of features, but based on a strong request from the embedded ecosystem, we have agreed to provide them as features as well. See [#94](https://github.com/taiki-e/portable-atomic/pull/94) for more.

- <a name="optional-cfg-portable-atomic"></a>**`--cfg portable_atomic_critical_section`**<br>
Since 1.7.1, this cfg is an alias of [`critical-section` feature](#optional-features-critical-section).

- <a name="optional-cfg-no-outline-atomics"></a>**`--cfg portable_atomic_no_outline_atomics`**<br>
Disable dynamic dispatching by run-time CPU feature detection.

Expand Down
4 changes: 3 additions & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ fn main() {

#[cfg(feature = "unsafe-assume-single-core")]
println!("cargo:rustc-cfg=portable_atomic_unsafe_assume_single_core");
#[cfg(feature = "critical-section")]
println!("cargo:rustc-cfg=portable_atomic_critical_section");
#[cfg(feature = "s-mode")]
println!("cargo:rustc-cfg=portable_atomic_s_mode");
#[cfg(feature = "force-amo")]
Expand Down Expand Up @@ -53,7 +55,7 @@ fn main() {
// Custom cfgs set by build script. Not public API.
// grep -E 'cargo:rustc-cfg=' build.rs | grep -v '=//' | sed -E 's/^.*cargo:rustc-cfg=//; s/(=\\)?".*$//' | LC_ALL=C sort -u | tr '\n' ','
println!(
"cargo:rustc-check-cfg=cfg(portable_atomic_disable_fiq,portable_atomic_force_amo,portable_atomic_ll_sc_rmw,portable_atomic_llvm_15,portable_atomic_llvm_16,portable_atomic_llvm_18,portable_atomic_new_atomic_intrinsics,portable_atomic_no_asm,portable_atomic_no_asm_maybe_uninit,portable_atomic_no_atomic_64,portable_atomic_no_atomic_cas,portable_atomic_no_atomic_load_store,portable_atomic_no_atomic_min_max,portable_atomic_no_cfg_target_has_atomic,portable_atomic_no_cmpxchg16b_intrinsic,portable_atomic_no_cmpxchg16b_target_feature,portable_atomic_no_const_raw_ptr_deref,portable_atomic_no_const_transmute,portable_atomic_no_core_unwind_safe,portable_atomic_no_stronger_failure_ordering,portable_atomic_no_track_caller,portable_atomic_no_unsafe_op_in_unsafe_fn,portable_atomic_s_mode,portable_atomic_sanitize_thread,portable_atomic_target_feature,portable_atomic_unsafe_assume_single_core,portable_atomic_unstable_asm,portable_atomic_unstable_asm_experimental_arch,portable_atomic_unstable_cfg_target_has_atomic,portable_atomic_unstable_isa_attribute)"
"cargo:rustc-check-cfg=cfg(portable_atomic_disable_fiq,portable_atomic_force_amo,portable_atomic_ll_sc_rmw,portable_atomic_llvm_15,portable_atomic_llvm_16,portable_atomic_llvm_18,portable_atomic_new_atomic_intrinsics,portable_atomic_no_asm,portable_atomic_no_asm_maybe_uninit,portable_atomic_no_atomic_64,portable_atomic_no_atomic_cas,portable_atomic_no_atomic_load_store,portable_atomic_no_atomic_min_max,portable_atomic_no_cfg_target_has_atomic,portable_atomic_no_cmpxchg16b_intrinsic,portable_atomic_no_cmpxchg16b_target_feature,portable_atomic_no_const_raw_ptr_deref,portable_atomic_no_const_transmute,portable_atomic_no_core_unwind_safe,portable_atomic_no_stronger_failure_ordering,portable_atomic_no_track_caller,portable_atomic_no_unsafe_op_in_unsafe_fn,portable_atomic_s_mode,portable_atomic_sanitize_thread,portable_atomic_target_feature,portable_atomic_unsafe_assume_single_core,portable_atomic_unstable_asm,portable_atomic_unstable_asm_experimental_arch,portable_atomic_unstable_cfg_target_has_atomic,portable_atomic_unstable_isa_attribute,portable_atomic_critical_section)"
);
// TODO: handle multi-line target_feature_fallback
// grep -E 'target_feature_fallback\("' build.rs | sed -E 's/^.*target_feature_fallback\(//; s/",.*$/"/' | LC_ALL=C sort -u | tr '\n' ','
Expand Down
32 changes: 16 additions & 16 deletions src/cfgs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
target_arch = "msp430",
target_arch = "riscv32",
target_arch = "riscv64",
feature = "critical-section",
portable_atomic_critical_section,
)),
)))]
#[macro_use]
Expand Down Expand Up @@ -42,7 +42,7 @@ mod atomic_8_16_macros {
target_arch = "msp430",
target_arch = "riscv32",
target_arch = "riscv64",
feature = "critical-section",
portable_atomic_critical_section,
)),
))]
#[macro_use]
Expand Down Expand Up @@ -78,7 +78,7 @@ mod atomic_8_16_macros {
target_arch = "msp430",
target_arch = "riscv32",
target_arch = "riscv64",
feature = "critical-section",
portable_atomic_critical_section,
)),
)),
))]
Expand All @@ -104,7 +104,7 @@ mod atomic_32_macros {
target_arch = "msp430",
target_arch = "riscv32",
target_arch = "riscv64",
feature = "critical-section",
portable_atomic_critical_section,
)),
)),
)))]
Expand All @@ -130,7 +130,7 @@ mod atomic_32_macros {
any(
not(portable_atomic_no_atomic_cas),
portable_atomic_unsafe_assume_single_core,
feature = "critical-section",
portable_atomic_critical_section,
target_arch = "avr",
target_arch = "msp430",
),
Expand All @@ -147,7 +147,7 @@ mod atomic_32_macros {
any(
target_has_atomic = "ptr",
portable_atomic_unsafe_assume_single_core,
feature = "critical-section",
portable_atomic_critical_section,
target_arch = "avr",
target_arch = "msp430",
),
Expand Down Expand Up @@ -177,7 +177,7 @@ mod atomic_64_macros {
any(
not(portable_atomic_no_atomic_cas),
portable_atomic_unsafe_assume_single_core,
feature = "critical-section",
portable_atomic_critical_section,
target_arch = "avr",
target_arch = "msp430",
),
Expand All @@ -194,7 +194,7 @@ mod atomic_64_macros {
any(
target_has_atomic = "ptr",
portable_atomic_unsafe_assume_single_core,
feature = "critical-section",
portable_atomic_critical_section,
target_arch = "avr",
target_arch = "msp430",
),
Expand Down Expand Up @@ -278,7 +278,7 @@ mod atomic_64_macros {
cfg(any(
not(portable_atomic_no_atomic_cas),
portable_atomic_unsafe_assume_single_core,
feature = "critical-section",
portable_atomic_critical_section,
target_arch = "avr",
target_arch = "msp430",
))
Expand All @@ -288,7 +288,7 @@ mod atomic_64_macros {
cfg(any(
target_has_atomic = "ptr",
portable_atomic_unsafe_assume_single_core,
feature = "critical-section",
portable_atomic_critical_section,
target_arch = "avr",
target_arch = "msp430",
))
Expand Down Expand Up @@ -367,7 +367,7 @@ mod atomic_128_macros {
cfg(not(any(
not(portable_atomic_no_atomic_cas),
portable_atomic_unsafe_assume_single_core,
feature = "critical-section",
portable_atomic_critical_section,
target_arch = "avr",
target_arch = "msp430",
)))
Expand All @@ -377,7 +377,7 @@ mod atomic_128_macros {
cfg(not(any(
target_has_atomic = "ptr",
portable_atomic_unsafe_assume_single_core,
feature = "critical-section",
portable_atomic_critical_section,
target_arch = "avr",
target_arch = "msp430",
)))
Expand All @@ -401,7 +401,7 @@ mod atomic_128_macros {
cfg(any(
not(portable_atomic_no_atomic_cas),
portable_atomic_unsafe_assume_single_core,
feature = "critical-section",
portable_atomic_critical_section,
target_arch = "avr",
target_arch = "msp430",
))
Expand All @@ -411,7 +411,7 @@ mod atomic_128_macros {
cfg(any(
target_has_atomic = "ptr",
portable_atomic_unsafe_assume_single_core,
feature = "critical-section",
portable_atomic_critical_section,
target_arch = "avr",
target_arch = "msp430",
))
Expand All @@ -434,7 +434,7 @@ mod atomic_cas_macros {
cfg(not(any(
not(portable_atomic_no_atomic_cas),
portable_atomic_unsafe_assume_single_core,
feature = "critical-section",
portable_atomic_critical_section,
target_arch = "avr",
target_arch = "msp430",
)))
Expand All @@ -444,7 +444,7 @@ mod atomic_cas_macros {
cfg(not(any(
target_has_atomic = "ptr",
portable_atomic_unsafe_assume_single_core,
feature = "critical-section",
portable_atomic_critical_section,
target_arch = "avr",
target_arch = "msp430",
)))
Expand Down
38 changes: 19 additions & 19 deletions src/imp/interrupt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@
// CAS together with atomic load/store. The load/store will not be
// called while interrupts are disabled, and since the load/store is
// atomic, it is not affected by interrupts even if interrupts are enabled.
#[cfg(not(any(target_arch = "avr", feature = "critical-section")))]
#[cfg(not(any(target_arch = "avr", portable_atomic_critical_section)))]
use arch::atomic;

#[cfg(not(feature = "critical-section"))]
#[cfg(not(portable_atomic_critical_section))]
#[cfg_attr(
all(
target_arch = "arm",
Expand All @@ -66,16 +66,16 @@ mod arch;
use core::{cell::UnsafeCell, sync::atomic::Ordering};

// Critical section implementations might use locks internally.
#[cfg(feature = "critical-section")]
#[cfg(portable_atomic_critical_section)]
const IS_ALWAYS_LOCK_FREE: bool = false;

// Consider atomic operations based on disabling interrupts on single-core
// systems are lock-free. (We consider the pre-v6 ARM Linux's atomic operations
// provided in a similar way by the Linux kernel to be lock-free.)
#[cfg(not(feature = "critical-section"))]
#[cfg(not(portable_atomic_critical_section))]
const IS_ALWAYS_LOCK_FREE: bool = true;

#[cfg(feature = "critical-section")]
#[cfg(portable_atomic_critical_section)]
#[inline]
fn with<F, R>(f: F) -> R
where
Expand All @@ -84,7 +84,7 @@ where
critical_section::with(|_| f())
}

#[cfg(not(feature = "critical-section"))]
#[cfg(not(portable_atomic_critical_section))]
#[inline]
fn with<F, R>(f: F) -> R
where
Expand Down Expand Up @@ -143,11 +143,11 @@ impl<T> AtomicPtr<T> {
#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]
pub(crate) fn load(&self, order: Ordering) -> *mut T {
crate::utils::assert_load_ordering(order);
#[cfg(not(any(target_arch = "avr", feature = "critical-section")))]
#[cfg(not(any(target_arch = "avr", portable_atomic_critical_section)))]
{
self.as_native().load(order)
}
#[cfg(any(target_arch = "avr", feature = "critical-section"))]
#[cfg(any(target_arch = "avr", portable_atomic_critical_section))]
// SAFETY: any data races are prevented by disabling interrupts (see
// module-level comments) and the raw pointer is valid because we got it
// from a reference.
Expand All @@ -158,11 +158,11 @@ impl<T> AtomicPtr<T> {
#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]
pub(crate) fn store(&self, ptr: *mut T, order: Ordering) {
crate::utils::assert_store_ordering(order);
#[cfg(not(any(target_arch = "avr", feature = "critical-section")))]
#[cfg(not(any(target_arch = "avr", portable_atomic_critical_section)))]
{
self.as_native().store(ptr, order);
}
#[cfg(any(target_arch = "avr", feature = "critical-section"))]
#[cfg(any(target_arch = "avr", portable_atomic_critical_section))]
// SAFETY: any data races are prevented by disabling interrupts (see
// module-level comments) and the raw pointer is valid because we got it
// from a reference.
Expand Down Expand Up @@ -228,7 +228,7 @@ impl<T> AtomicPtr<T> {
self.p.get()
}

#[cfg(not(any(target_arch = "avr", feature = "critical-section")))]
#[cfg(not(any(target_arch = "avr", portable_atomic_critical_section)))]
#[inline]
fn as_native(&self) -> &atomic::AtomicPtr<T> {
// SAFETY: AtomicPtr and atomic::AtomicPtr have the same layout and
Expand Down Expand Up @@ -288,11 +288,11 @@ macro_rules! atomic_int {
#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]
pub(crate) fn load(&self, order: Ordering) -> $int_type {
crate::utils::assert_load_ordering(order);
#[cfg(not(any(target_arch = "avr", feature = "critical-section")))]
#[cfg(not(any(target_arch = "avr", portable_atomic_critical_section)))]
{
self.as_native().load(order)
}
#[cfg(any(target_arch = "avr", feature = "critical-section"))]
#[cfg(any(target_arch = "avr", portable_atomic_critical_section))]
// SAFETY: any data races are prevented by disabling interrupts (see
// module-level comments) and the raw pointer is valid because we got it
// from a reference.
Expand All @@ -303,18 +303,18 @@ macro_rules! atomic_int {
#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]
pub(crate) fn store(&self, val: $int_type, order: Ordering) {
crate::utils::assert_store_ordering(order);
#[cfg(not(any(target_arch = "avr", feature = "critical-section")))]
#[cfg(not(any(target_arch = "avr", portable_atomic_critical_section)))]
{
self.as_native().store(val, order);
}
#[cfg(any(target_arch = "avr", feature = "critical-section"))]
#[cfg(any(target_arch = "avr", portable_atomic_critical_section))]
// SAFETY: any data races are prevented by disabling interrupts (see
// module-level comments) and the raw pointer is valid because we got it
// from a reference.
with(|| unsafe { self.v.get().write(val) });
}

#[cfg(not(any(target_arch = "avr", feature = "critical-section")))]
#[cfg(not(any(target_arch = "avr", portable_atomic_critical_section)))]
#[inline]
fn as_native(&self) -> &atomic::$atomic_type {
// SAFETY: $atomic_type and atomic::$atomic_type have the same layout and
Expand All @@ -323,17 +323,17 @@ macro_rules! atomic_int {
}
}

#[cfg(not(all(target_arch = "msp430", not(feature = "critical-section"))))]
#[cfg(not(all(target_arch = "msp430", not(portable_atomic_critical_section))))]
impl_default_no_fetch_ops!($atomic_type, $int_type);
impl_default_bit_opts!($atomic_type, $int_type);
#[cfg(not(all(target_arch = "msp430", not(feature = "critical-section"))))]
#[cfg(not(all(target_arch = "msp430", not(portable_atomic_critical_section))))]
impl $atomic_type {
#[inline]
pub(crate) fn not(&self, order: Ordering) {
self.fetch_not(order);
}
}
#[cfg(all(target_arch = "msp430", not(feature = "critical-section")))]
#[cfg(all(target_arch = "msp430", not(portable_atomic_critical_section)))]
impl $atomic_type {
#[inline]
pub(crate) fn add(&self, val: $int_type, order: Ordering) {
Expand Down
Loading

0 comments on commit 6c2a301

Please sign in to comment.