Skip to content

Commit

Permalink
Enable run-time detection by default on powerpc64 and aarch64 linux-u…
Browse files Browse the repository at this point in the history
…clibc
  • Loading branch information
taiki-e committed Oct 19, 2024
1 parent 33b6cb5 commit bdfea9d
Show file tree
Hide file tree
Showing 16 changed files with 406 additions and 111 deletions.
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

0 comments on commit bdfea9d

Please sign in to comment.