Crates.io | portable-atomic |
lib.rs | portable-atomic |
version | 1.10.0 |
source | src |
created_at | 2022-02-24 03:15:21.449241 |
updated_at | 2024-11-23 21:10:54.331532 |
description | Portable atomic types including support for 128-bit atomics, atomic float, etc. |
homepage | |
repository | https://github.com/taiki-e/portable-atomic |
max_upload_size | |
id | 538233 |
size | 1,139,310 |
Portable atomic types including support for 128-bit atomics, atomic float, etc.
Atomic{I,U}{8,16,32,64}
) for all targets that can use atomic CAS. (i.e., all targets that can use std
, and most no-std targets)AtomicI128
and AtomicU128
.AtomicF32
and AtomicF64
. (optional, requires the float
feature)AtomicPtr::fetch_*
.fetch_{max,min}
, fetch_update
, as_ptr
, from_ptr
, AtomicBool::fetch_not
and stronger CAS failure ordering available on Rust 1.34+.fence
/compiler_fence
on MSP430 that cause LLVM error, etc.portable-atomic version of std::sync::Arc
is provided by the portable-atomic-util crate.
Add this to your Cargo.toml
:
[dependencies]
portable-atomic = "1"
The default features are mainly for users who use atomics larger than the pointer width. If you don't need them, disabling the default features may reduce code size and compile time slightly.
[dependencies]
portable-atomic = { version = "1", default-features = false }
If your crate supports no-std environment and requires atomic CAS, enabling the require-cas
feature will allow the portable-atomic
to display a helpful error message to users on targets requiring additional action on the user side to provide atomic CAS.
[dependencies]
portable-atomic = { version = "1.3", default-features = false, features = ["require-cas"] }
Native 128-bit atomic operations are available on x86_64 (Rust 1.59+), AArch64 (Rust 1.59+), riscv64 (Rust 1.59+), Arm64EC (Rust 1.84+), s390x (Rust 1.84+), and powerpc64 (nightly only), otherwise the fallback implementation is used.
On x86_64, even if cmpxchg16b
is not available at compile-time (note: cmpxchg16b
target feature is enabled by default only on Apple and Windows (except Windows 7) targets), run-time detection checks whether cmpxchg16b
is available. If cmpxchg16b
is not available at either compile-time or run-time detection, the fallback implementation is used. See also portable_atomic_no_outline_atomics
cfg.
They are usually implemented using inline assembly, and when using Miri or ThreadSanitizer that do not support inline assembly, core intrinsics are used instead of inline assembly if possible.
See the atomic128
module's readme for details.
fallback
(enabled by default)
Enable fallback implementations.
Disabling this allows only atomic types for which the platform natively supports atomic operations.
Note that most of fetch_*
operations of atomic floats are implemented using CAS loops, which can be slower than equivalent operations of atomic integers. (GPU targets have atomic instructions for float, so we plan to use these instructions for GPU targets in the future.)
std
Use std
.
require-cas
Emit compile error if atomic CAS is not available. See Usage section and #100 for more.
serde
Implement serde::{Serialize,Deserialize}
for atomic types.
Note:
critical-section
When this feature is enabled, this crate uses critical-section to provide atomic CAS for targets where
it is not natively available. When enabling it, you should provide a suitable critical section implementation
for the current target, see the critical-section documentation for details on how to do so.
critical-section
support is useful to get atomic CAS when the unsafe-assume-single-core
feature can't be used,
such as multi-core targets, unprivileged code running under some RTOS, or environments where disabling interrupts
needs extra care due to e.g. real-time requirements.
Note that with the critical-section
feature, critical sections are taken for all atomic operations, while with
unsafe-assume-single-core
feature some operations don't require disabling interrupts (loads and stores, but
additionally on MSP430 add
, sub
, and
, or
, xor
, not
). Therefore, for better performance, if
all the critical-section
implementation for your target does is disable interrupts, prefer using
unsafe-assume-single-core
feature instead.
Note:
The MSRV when this feature is enabled depends on the MSRV of critical-section.
It is usually not recommended to always enable this feature in dependencies of the library.
Enabling this feature will prevent the end user from having the chance to take advantage of other (potentially) efficient implementations (Implementations provided by unsafe-assume-single-core
feature, default implementations on MSP430 and AVR, implementation proposed in #60, etc. Other systems may also be supported in the future).
The recommended approach for libraries is to leave it up to the end user whether or not to enable this feature. (However, it may make sense to enable this feature by default for libraries specific to a platform where other implementations are known not to work.)
As an example, the end-user's Cargo.toml
that uses a crate that provides a critical-section implementation and a crate that depends on portable-atomic as an option would be expected to look like this:
[dependencies]
portable-atomic = { version = "1", default-features = false, features = ["critical-section"] }
crate-provides-critical-section-impl = "..."
crate-uses-portable-atomic-as-feature = { version = "...", features = ["portable-atomic"] }
unsafe-assume-single-core
Assume that the target is single-core.
When this feature is enabled, this crate provides atomic CAS for targets where atomic CAS is not available in the standard library by disabling interrupts.
This feature is unsafe
, and note the following safety requirements:
Enabling this feature for multi-core systems is always unsound.
This uses privileged instructions to disable interrupts, so it usually doesn't work on unprivileged mode. Enabling this feature in an environment where privileged instructions are not available, or if the instructions used are not sufficient to disable interrupts in the system, it is also usually considered unsound, although the details are system-dependent.
The following are known cases:
disable-fiq
feature together.s-mode
together, this generates code for supervisor-mode (S-mode). In particular, qemu-system-riscv*
uses OpenSBI as the default firmware.See also the interrupt
module's readme.
Consider using the critical-section
feature for systems that cannot use this feature.
It is very strongly discouraged to enable this feature in libraries that depend on portable-atomic
. The recommended approach for libraries is to leave it up to the end user whether or not to enable this feature. (However, it may make sense to enable this feature by default for libraries specific to a platform where it is guaranteed to always be sound, for example in a hardware abstraction layer targeting a single-core chip.)
Armv6-M (thumbv6m), pre-v6 Arm (e.g., thumbv4t, thumbv5te), RISC-V without A-extension, and Xtensa are currently supported.
Since all MSP430 and AVR are single-core, we always provide atomic CAS for them without this feature.
Enabling this feature for targets that have atomic CAS will result in a compile error.
Feel free to submit an issue if your target is not supported yet.
One of the ways to enable cfg is to set rustflags in the cargo config:
# .cargo/config.toml
[target.<target>]
rustflags = ["--cfg", "portable_atomic_no_outline_atomics"]
Or set environment variable:
RUSTFLAGS="--cfg portable_atomic_no_outline_atomics" cargo ...
--cfg portable_atomic_unsafe_assume_single_core
Since 1.4.0, this cfg is an alias of unsafe-assume-single-core
feature.
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 for more.
--cfg portable_atomic_no_outline_atomics
Disable dynamic dispatching by run-time CPU feature detection.
If dynamic dispatching by run-time CPU feature detection is enabled, it allows maintaining support for older CPUs while using features that are not supported on older CPUs, such as CMPXCHG16B (x86_64) and FEAT_LSE/FEAT_LSE2 (AArch64).
Note:
std
).--cfg portable_atomic_outline_atomics
. (When both cfg are enabled, *_no_*
cfg is preferred.)outline-atomics
target feature by default, so if you set this cfg, you may want to disable that as well. (portable-atomic's outline-atomics does not depend on the compiler-rt symbols, so even if you need to disable LLVM's outline-atomics, you may not need to disable portable-atomic's outline-atomics.)See also the atomic128
module's readme.
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.