#atomic

no-std portable-atomic

Portable atomic types including support for 128-bit atomics, atomic float, etc

17 releases

new 0.3.13 Aug 15, 2022
0.3.12 Aug 13, 2022
0.3.7 Jul 31, 2022
0.3.4 Jun 25, 2022
0.1.3 Feb 28, 2022

#377 in Concurrency

Download history 35/week @ 2022-04-25 45/week @ 2022-05-02 10/week @ 2022-05-09 90/week @ 2022-05-16 23/week @ 2022-05-23 50/week @ 2022-05-30 36/week @ 2022-06-06 39/week @ 2022-06-13 60/week @ 2022-06-20 11/week @ 2022-06-27 26/week @ 2022-07-04 62/week @ 2022-07-11 3102/week @ 2022-07-18 14791/week @ 2022-07-25 20198/week @ 2022-08-01 22377/week @ 2022-08-08

60,481 downloads per month
Used in 14 crates (6 directly)

Apache-2.0 OR MIT

525KB
10K SLoC

portable-atomic

crates.io docs.rs license rustc build status build status

Portable atomic types including support for 128-bit atomics, atomic float, etc.

  • Provide all atomic integer types (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)
  • Provide AtomicI128 and AtomicU128.
  • Provide AtomicF32 and AtomicF64. (optional)
  • Provide atomic load/store for targets where atomic is not available at all in the standard library. (RISC-V without A-extension, MSP430, AVR)
  • Provide atomic CAS for targets where atomic CAS is not available in the standard library. (thumbv6m, pre-v6 ARM, RISC-V without A-extension, MSP430, AVR) (optional and single-core only for ARM and RISC-V, always enabled for MSP430 and AVR)
  • Provide equivalents on the target that the standard library's atomic-related APIs cause LLVM errors. (fence/compiler_fence on MSP430)
  • Provide stable equivalents of the standard library atomic types' unstable APIs, such as AtomicPtr::fetch_*, AtomicBool::fetch_not.
  • Make features that require newer compilers, such as fetch_max, fetch_min, fetch_update, and stronger CAS failure ordering available on Rust 1.34+.

128-bit atomics support

Native 128-bit atomic operations are available on x86_64 (Rust 1.59+), aarch64 (Rust 1.59+), powerpc64 (le or pwr8+, nightly only), and s390x (nightly only), otherwise the fallback implementation is used.

On x86_64, when the outline-atomics optional feature is not enabled and cmpxchg16b target feature is not enabled at compile-time, this uses the fallback implementation. cmpxchg16b target feature is enabled by default only on macOS.

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 this list for details.

Optional features

  • fallback *(enabled by default)*
    Enable fallback implementations.

    Disabling this allows only atomic types for which the platform natively supports atomic operations.

  • outline-atomics
    Enable run-time CPU feature detection.

    This allows maintaining support for older CPUs while using features that are not supported on older CPUs, such as CMPXCHG16B (x86_64) and FEAT_LSE (aarch64).

    Note:

    • Dynamic detection is currently only enabled in Rust 1.61+ for aarch64, in 1.58+ (AVX) or nightly (CMPXCHG16B) for x86_64, and in nightly for other platforms, otherwise it works the same as the default.
    • If the required target features are enabled at compile-time, the atomic operations are inlined.
    • This is compatible with no-std (as with all features except std).

    See also this list.

  • float
    Provide AtomicF{32,64}. Note that most of fetch_* operations of atomic floats are implemented using CAS loops, which can be slower than equivalent operations of atomic integers.

  • std
    Use std.

  • serde
    Implement serde::{Serialize,Deserialize} for atomic types.

    Note:

    • The MSRV when this feature enables depends on the MSRV of serde.

Optional cfg

  • --cfg portable_atomic_unsafe_assume_single_core
    Assume that the target is single-core. When this cfg is enabled, this crate provides atomic CAS for targets where atomic CAS is not available in the standard library by disabling interrupts.

    This cfg is unsafe, and note the following safety requirements:

    • Enabling this cfg 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 cfg in an environment where privileged instructions are not available is also usually considered unsound, although the details are system-dependent.
    • On pre-v6 ARM, this currently disables only IRQs. Enabling this cfg in an environment where FIQs must also be disabled is also considered unsound.

    This is intentionally not an optional feature. (If this is an optional feature, dependencies can implicitly enable the feature, resulting in the use of unsound code without the end-user being aware of it.)

    Enabling this cfg for targets that have atomic CAS will result in a compile error.

    ARMv6-M (thumbv6m), pre-v6 ARM (e.g., thumbv4t), RISC-V without A-extension are currently supported. See #33 for support of multi-core systems.

    Since all MSP430 and AVR are single-core, we always provide atomic CAS for them without this cfg.

    Feel free to submit an issue if your target is not supported yet.

Related Projects

License

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.

Dependencies