Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/.cspell/project-dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ csrrci
csrsi
cxchg
cxchgweak
dlfcn
dlsym
DWCAS
ecall
Expand Down Expand Up @@ -128,6 +129,7 @@ revidr
rsbegin
rsend
rsil
RTLD
sbcs
selgr
seqlock
Expand Down
19 changes: 14 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -324,22 +324,29 @@ jobs:
- run: tools/test.sh -vv ${TARGET:-} ${DOCTEST_XCOMPILE:-} ${BUILD_STD:-} ${RELEASE:-}
# We test doctest only once with the default build conditions because doctest is slow. Both api-test
# and src/tests have extended copies of doctest, so this will not reduce test coverage.
# portable_atomic_no_outline_atomics only affects x86_64, AArch64, Arm, powerpc64, and RISC-V Linux.
# outline-atomics is disabled by default on AArch64/powerpc64 musl with static linking
# powerpc64le- (little-endian) is skipped because it is pwr8 by default
# RISC-V Linux is skipped because outline-atomics is currently disabled by default on riscv.
- run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-}
env:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} --cfg portable_atomic_no_outline_atomics
RUSTFLAGS: ${{ env.RUSTFLAGS }} --cfg portable_atomic_no_outline_atomics
# outline-atomics is disabled by default on AArch64 musl with static linking
if: (matrix.target == '' && !contains(matrix.rust, 'i686') || startsWith(matrix.target, 'x86_64')) || startsWith(matrix.target, 'aarch64') && !(contains(matrix.target, '-musl') && matrix.flags == '') || startsWith(matrix.target, 'armv5te') || matrix.target == 'arm-linux-androideabi'
if: (matrix.target == '' && !contains(matrix.rust, 'i686') || startsWith(matrix.target, 'x86_64')) || (startsWith(matrix.target, 'aarch64') || startsWith(matrix.target, 'powerpc64-')) && !(contains(matrix.target, '-musl') && matrix.flags == '') || startsWith(matrix.target, 'armv5te') || matrix.target == 'arm-linux-androideabi'
- run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-}
env:
# Note: detect_false cfg is intended to make it easy for portable-atomic developers to
# test cases such as has_cmpxchg16b == false, has_lse == false,
# __kuser_helper_version < 5, etc., and is not a public API.
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} --cfg portable_atomic_test_outline_atomics_detect_false
RUSTFLAGS: ${{ env.RUSTFLAGS }} --cfg portable_atomic_test_outline_atomics_detect_false
# outline-atomics is disabled by default on AArch64 musl with static linking
# powerpc64 is skipped because tested below.
if: (matrix.target == '' && !contains(matrix.rust, 'i686') || startsWith(matrix.target, 'x86_64')) || startsWith(matrix.target, 'aarch64') && !(contains(matrix.target, '-musl') && matrix.flags == '') || startsWith(matrix.target, 'armv5te') || matrix.target == 'arm-linux-androideabi'
# outline-atomics is disabled by default on AArch64 musl with static linking, powerpc64, and RISC-V
- run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-}
env:
QEMU_CPU: power7 # no quadword-atomics
if: startsWith(matrix.target, 'powerpc64-')
# portable_atomic_outline_atomics only affects AArch64 non-glibc-Linux/illumos, powerpc64, and RISC-V Linux.
# powerpc64le- (little-endian) is skipped because it is pwr8 by default
- run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} --exclude api-test
env:
Expand All @@ -353,7 +360,8 @@ jobs:
# __kuser_helper_version < 5, etc., and is not a public API.
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} --cfg portable_atomic_outline_atomics --cfg portable_atomic_test_outline_atomics_detect_false
RUSTFLAGS: ${{ env.RUSTFLAGS }} --cfg portable_atomic_outline_atomics --cfg portable_atomic_test_outline_atomics_detect_false
if: startsWith(matrix.target, 'aarch64') && contains(matrix.target, '-musl') && matrix.flags == '' || startsWith(matrix.target, 'powerpc64-') || startsWith(matrix.target, 'riscv')
# powerpc64 and RISC-V are skipped because tested below.
if: startsWith(matrix.target, 'aarch64') && contains(matrix.target, '-musl') && matrix.flags == ''
- run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} --exclude api-test
env:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} --cfg portable_atomic_outline_atomics
Expand Down Expand Up @@ -483,6 +491,7 @@ jobs:
sync_files: runner-to-vm
run: |
set -CeEuxo pipefail
export CI=true
export RUSTFLAGS="${RUSTFLAGS} --cfg qemu"
# AArch64 FreeBSD/NetBSD/OpenBSD are tier 3 targets, so install Rust from package manager instead of rustup.
case "$(uname -s)" in
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,10 @@ RUSTFLAGS="--cfg portable_atomic_no_outline_atomics" cargo ...
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 enabled in Rust 1.59+ for x86_64 and AArch64, Rust 1.82+ for RISC-V (disabled by default), nightly only for powerpc64 (disabled by default) and Arm64EC, otherwise it works the same as when this cfg is set.
- Dynamic detection is currently only enabled in Rust 1.59+ for x86_64 and AArch64, Rust 1.82+ for RISC-V (disabled by default), nightly only for powerpc64 and Arm64EC, 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 except `std`).
- On some targets, run-time detection is disabled by default mainly for compatibility with older versions of operating systems or incomplete build environments, and can be enabled by `--cfg portable_atomic_outline_atomics`. (When both cfg are enabled, `*_no_*` cfg is preferred.)
- On some targets, run-time detection is disabled by default mainly for incomplete build environments, and can be enabled by `--cfg portable_atomic_outline_atomics`. (When both cfg are enabled, `*_no_*` cfg is preferred.)
- Some AArch64 targets enable LLVM's `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](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/atomic128/README.md).
Expand Down
10 changes: 4 additions & 6 deletions src/cfgs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,22 +299,21 @@ mod atomic_64_macros {
all(
feature = "fallback",
not(portable_atomic_no_outline_atomics),
portable_atomic_outline_atomics, // TODO(powerpc64): currently disabled by default
any(
all(
target_os = "linux",
any(
target_env = "gnu",
all(
any(target_env = "musl", target_env = "ohos"),
any(target_env = "musl", target_env = "ohos", target_env = "uclibc"),
not(target_feature = "crt-static"),
),
portable_atomic_outline_atomics,
),
),
target_os = "android",
target_os = "freebsd",
all(target_os = "openbsd", portable_atomic_outline_atomics),
all(target_os = "openbsd", not(target_feature = "crt-static")),
),
not(any(miri, portable_atomic_sanitize_thread)),
),
Expand Down Expand Up @@ -406,22 +405,21 @@ mod atomic_128_macros {
all(
feature = "fallback",
not(portable_atomic_no_outline_atomics),
portable_atomic_outline_atomics, // TODO(powerpc64): currently disabled by default
any(
all(
target_os = "linux",
any(
target_env = "gnu",
all(
any(target_env = "musl", target_env = "ohos"),
any(target_env = "musl", target_env = "ohos", target_env = "uclibc"),
not(target_feature = "crt-static"),
),
portable_atomic_outline_atomics,
),
),
target_os = "android",
target_os = "freebsd",
all(target_os = "openbsd", portable_atomic_outline_atomics),
all(target_os = "openbsd", not(target_feature = "crt-static")),
),
not(any(miri, portable_atomic_sanitize_thread)),
),
Expand Down
2 changes: 1 addition & 1 deletion src/imp/atomic128/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Here is the table of targets that support 128-bit atomics and the instructions u
| x86_64 | cmpxchg16b or vmovdqa | cmpxchg16b or vmovdqa | cmpxchg16b | cmpxchg16b | cmpxchg16b target feature required. vmovdqa requires Intel, AMD, or Zhaoxin CPU with AVX. <br> Both compile-time and run-time detection are supported for cmpxchg16b. vmovdqa is currently run-time detection only. <br> Requires rustc 1.59+ |
| aarch64/arm64ec | ldxp/stxp or casp or ldp/ldiapp | ldxp/stxp or casp or stp/stilp/swpp | ldxp/stxp or casp | ldxp/stxp or casp/swpp/ldclrp/ldsetp | casp requires lse target feature, ldp/stp requires lse2 target feature, ldiapp/stilp requires lse2 and rcpc3 target features, swpp/ldclrp/ldsetp requires lse128 target feature. <br> Both compile-time and run-time detection are supported. <br> Requires rustc 1.59+ (aarch64) / nightly (arm64ec) |
| riscv64 | amocas.q | amocas.q | amocas.q | amocas.q | Experimental because LLVM marking the corresponding target feature as experimental. Requires experimental-zacas target feature. Both compile-time and run-time detection are supported (run-time detection is currently disabled by default). <br> Requires rustc 1.82+ (LLVM 19+) |
| powerpc64 | lq | stq | lqarx/stqcx. | lqarx/stqcx. | Requires target-cpu pwr8+ (powerpc64le is pwr8 by default). Both compile-time and run-time detection are supported (run-time detection is currently disabled by default). <br> Requires nightly |
| powerpc64 | lq | stq | lqarx/stqcx. | lqarx/stqcx. | Requires target-cpu pwr8+ (powerpc64le is pwr8 by default). Both compile-time and run-time detection are supported. <br> Requires nightly |
| s390x | lpq | stpq | cdsg | cdsg | Requires nightly |

On compiler versions or platforms where these are not supported, the fallback implementation is used.
Expand Down
25 changes: 14 additions & 11 deletions src/imp/atomic128/aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,10 @@ include!("macros.rs");
target_os = "linux",
any(
target_env = "gnu",
all(any(target_env = "musl", target_env = "ohos"), not(target_feature = "crt-static")),
all(
any(target_env = "musl", target_env = "ohos", target_env = "uclibc"),
not(target_feature = "crt-static"),
),
portable_atomic_outline_atomics,
),
),
Expand Down Expand Up @@ -177,7 +180,7 @@ macro_rules! debug_assert_lse {
any(
target_env = "gnu",
all(
any(target_env = "musl", target_env = "ohos"),
any(target_env = "musl", target_env = "ohos", target_env = "uclibc"),
not(target_feature = "crt-static"),
),
portable_atomic_outline_atomics,
Expand Down Expand Up @@ -214,7 +217,7 @@ macro_rules! debug_assert_lse2 {
any(
target_env = "gnu",
all(
any(target_env = "musl", target_env = "ohos"),
any(target_env = "musl", target_env = "ohos", target_env = "uclibc"),
not(target_feature = "crt-static"),
),
portable_atomic_outline_atomics,
Expand Down Expand Up @@ -255,7 +258,7 @@ macro_rules! debug_assert_lse128 {
any(
target_env = "gnu",
all(
any(target_env = "musl", target_env = "ohos"),
any(target_env = "musl", target_env = "ohos", target_env = "uclibc"),
not(target_feature = "crt-static"),
),
portable_atomic_outline_atomics,
Expand Down Expand Up @@ -296,7 +299,7 @@ macro_rules! debug_assert_rcpc3 {
any(
target_env = "gnu",
all(
any(target_env = "musl", target_env = "ohos"),
any(target_env = "musl", target_env = "ohos", target_env = "uclibc"),
not(target_feature = "crt-static"),
),
portable_atomic_outline_atomics,
Expand Down Expand Up @@ -509,7 +512,7 @@ unsafe fn atomic_load(src: *mut u128, order: Ordering) -> u128 {
any(
target_env = "gnu",
all(
any(target_env = "musl", target_env = "ohos"),
any(target_env = "musl", target_env = "ohos", target_env = "uclibc"),
not(target_feature = "crt-static"),
),
portable_atomic_outline_atomics,
Expand Down Expand Up @@ -606,7 +609,7 @@ unsafe fn atomic_load(src: *mut u128, order: Ordering) -> u128 {
any(
target_env = "gnu",
all(
any(target_env = "musl", target_env = "ohos"),
any(target_env = "musl", target_env = "ohos", target_env = "uclibc"),
not(target_feature = "crt-static"),
),
portable_atomic_outline_atomics,
Expand Down Expand Up @@ -932,7 +935,7 @@ unsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) {
any(
target_env = "gnu",
all(
any(target_env = "musl", target_env = "ohos"),
any(target_env = "musl", target_env = "ohos", target_env = "uclibc"),
not(target_feature = "crt-static"),
),
portable_atomic_outline_atomics,
Expand Down Expand Up @@ -1037,7 +1040,7 @@ unsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) {
any(
target_env = "gnu",
all(
any(target_env = "musl", target_env = "ohos"),
any(target_env = "musl", target_env = "ohos", target_env = "uclibc"),
not(target_feature = "crt-static"),
),
portable_atomic_outline_atomics,
Expand Down Expand Up @@ -1263,7 +1266,7 @@ unsafe fn atomic_compare_exchange(
any(
target_env = "gnu",
all(
any(target_env = "musl", target_env = "ohos"),
any(target_env = "musl", target_env = "ohos", target_env = "uclibc"),
not(target_feature = "crt-static"),
),
portable_atomic_outline_atomics,
Expand Down Expand Up @@ -1402,7 +1405,7 @@ unsafe fn atomic_compare_exchange(
any(
target_env = "gnu",
all(
any(target_env = "musl", target_env = "ohos"),
any(target_env = "musl", target_env = "ohos", target_env = "uclibc"),
not(target_feature = "crt-static"),
),
portable_atomic_outline_atomics,
Expand Down
5 changes: 2 additions & 3 deletions src/imp/atomic128/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,21 @@ pub(super) mod aarch64;
all(
feature = "fallback",
not(portable_atomic_no_outline_atomics),
any(test, portable_atomic_outline_atomics), // TODO(powerpc64): currently disabled by default
any(
all(
target_os = "linux",
any(
target_env = "gnu",
all(
any(target_env = "musl", target_env = "ohos"),
any(target_env = "musl", target_env = "ohos", target_env = "uclibc"),
not(target_feature = "crt-static"),
),
portable_atomic_outline_atomics,
),
),
target_os = "android",
target_os = "freebsd",
all(target_os = "openbsd", portable_atomic_outline_atomics),
all(target_os = "openbsd", not(target_feature = "crt-static")),
),
not(any(miri, portable_atomic_sanitize_thread)),
),
Expand Down
8 changes: 5 additions & 3 deletions src/imp/atomic128/powerpc64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ mod fallback;
// On musl with static linking, it seems that getauxval is not always available.
// See detect/auxv.rs for more.
#[cfg(not(portable_atomic_no_outline_atomics))]
#[cfg(any(test, portable_atomic_outline_atomics))] // TODO(powerpc64): currently disabled by default
#[cfg(any(
test,
not(any(
Expand All @@ -54,13 +53,16 @@ mod fallback;
target_os = "linux",
any(
target_env = "gnu",
all(any(target_env = "musl", target_env = "ohos"), not(target_feature = "crt-static")),
all(
any(target_env = "musl", target_env = "ohos", target_env = "uclibc"),
not(target_feature = "crt-static"),
),
portable_atomic_outline_atomics,
),
),
target_os = "android",
target_os = "freebsd",
all(target_os = "openbsd", portable_atomic_outline_atomics),
all(target_os = "openbsd", not(target_feature = "crt-static")),
))]
#[path = "../detect/auxv.rs"]
mod detect;
Expand Down
Loading