Movatterモバイル変換


[0]ホーム

URL:


Docs.rs

Crateportable_atomic

Source
Expand description

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

portable-atomic version ofstd::sync::Arc is provided by theportable-atomic-util crate.

§Usage

Add this to yourCargo.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 therequire-cas feature will allow theportable-atomic to display ahelpful 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"] }

§128-bit atomics support

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 ifcmpxchg16b 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 whethercmpxchg16b is available. Ifcmpxchg16b is not available at either compile-time or run-time detection, the fallback implementation is used. See alsoportable_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 theatomic128 module’s readme 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.

  • float
    ProvideAtomicF{32,64}.

    • When unstable--cfg portable_atomic_unstable_f16 is also enabled,AtomicF16 forunstablef16 is also provided.
    • When unstable--cfg portable_atomic_unstable_f128 is also enabled,AtomicF128 forunstablef128 is also provided.

    Note:

    • Most offetch_* operations of atomic floats are implemented using CAS loops, which can be slower than equivalent operations of atomic integers. (AArch64 with FEAT_LSFE and GPU targets have atomic instructions for float,so we plan to use these instructions for them in the future.)
    • Unstable cfgs are outside of the normal semver guarantees and minor or patch versions of portable-atomic may make breaking changes to them at any time.
  • std
    Usestd.

  • require-cas
    Emit compile error if atomic CAS is not available. SeeUsage section and#100 for more.

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

    Note:

    • The MSRV when this feature is enabled depends on the MSRV ofserde.
  • critical-section
    When this feature is enabled, this crate usescritical-section to provide atomic CAS for targets whereit is not natively available. When enabling it, you should provide a suitable critical section implementationfor the current target, see thecritical-section documentation for details on how to do so.

    critical-section support is useful to get atomic CAS when theunsafe-assume-single-core feature can’t be used,such as multi-core targets, unprivileged code running under some RTOS, or environments where disabling interruptsneeds extra care due to e.g. real-time requirements.

    Note that with thecritical-section feature, critical sections are taken for all atomic operations, while withunsafe-assume-single-core feature some operations don’t require disabling interrupts (loads and stores, butadditionally on MSP430add,sub,and,or,xor,not). Therefore, for better performance, ifall thecritical-section implementation for your target does is disable interrupts, prefer usingunsafe-assume-single-core feature instead.

    Note:

    • The MSRV when this feature is enabled depends on the MSRV ofcritical-section.

    • It is usuallynot 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 byunsafe-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’sCargo.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 isunsafe, and note the following safety requirements:

    • Enabling this feature for multi-core systems is alwaysunsound.

    • 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 consideredunsound, although the details are system-dependent.

      The following are known cases:

      • On pre-v6 Arm, this disables only IRQs by default. For many systems (e.g., GBA) this is enough. If the system need to disable both IRQs and FIQs, you need to enable thedisable-fiq feature together.
      • On RISC-V without A-extension, this generates code for machine-mode (M-mode) by default. If you enable thes-mode together, this generates code for supervisor-mode (S-mode). In particular,qemu-system-riscv* usesOpenSBI as the default firmware.

      See also theinterrupt module’s readme.

    Consider using thecritical-section feature for systems that cannot use this feature.

    It isvery strongly discouraged to enable this feature in libraries that depend onportable-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.

§Optional cfg

One of the ways to enable cfg is to setrustflags 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 ofunsafe-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:

    • Dynamic detection is currently only supported in x86_64, AArch64, Arm, RISC-V, Arm64EC, and powerpc64, otherwise it works the same as when this cfg is set.
    • 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 exceptstd).
    • On some targets, run-time detection is disabled by default mainly for compatibility with incomplete build environments or support for it is experimental, and can be enabled by--cfg portable_atomic_outline_atomics. (When both cfg are enabled,*_no_* cfg is preferred.)
    • Some AArch64 targets enable LLVM’soutline-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 theatomic128 module’s readme.

§Related Projects

Re-exports§

pub use core::sync::atomic::Ordering;
pub use core::sync::atomic::compiler_fence;
pub use core::sync::atomic::fence;

Modules§

hint
Re-export of thecore::hint module.

Macros§

cfg_has_atomic_8
cfg_has_atomic_16
cfg_has_atomic_32
cfg_has_atomic_64
cfg_has_atomic_128
cfg_has_atomic_cas
cfg_has_atomic_ptr
cfg_no_atomic_8
cfg_no_atomic_16
cfg_no_atomic_32
cfg_no_atomic_64
cfg_no_atomic_128
cfg_no_atomic_cas
cfg_no_atomic_ptr

Structs§

AtomicBool
A boolean type which can be safely shared between threads.
AtomicF16float andportable_atomic_unstable_f16
A floating point type which can be safely shared between threads.
AtomicF32float
A floating point type which can be safely shared between threads.
AtomicF64float
A floating point type which can be safely shared between threads.
AtomicF128float andportable_atomic_unstable_f128
A floating point type which can be safely shared between threads.
AtomicI8
An integer type which can be safely shared between threads.
AtomicI16
An integer type which can be safely shared between threads.
AtomicI32
An integer type which can be safely shared between threads.
AtomicI64
An integer type which can be safely shared between threads.
AtomicI128
An integer type which can be safely shared between threads.
AtomicIsize
An integer type which can be safely shared between threads.
AtomicPtr
A raw pointer type which can be safely shared between threads.
AtomicU8
An integer type which can be safely shared between threads.
AtomicU16
An integer type which can be safely shared between threads.
AtomicU32
An integer type which can be safely shared between threads.
AtomicU64
An integer type which can be safely shared between threads.
AtomicU128
An integer type which can be safely shared between threads.
AtomicUsize
An integer type which can be safely shared between threads.

[8]ページ先頭

©2009-2025 Movatter.jp