Skip to content

Commit 02a41ef

Browse files
committed
Remove uses of autocfg
Detect platforms that do not support AtomicU64 by using the same way. AFAIK, this is more robust than the current way that uses autocfg. See also rust-lang/futures-rs#2294.
1 parent 7e6c097 commit 02a41ef

File tree

10 files changed

+144
-89
lines changed

10 files changed

+144
-89
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ jobs:
2323
name: test
2424
env:
2525
RUST_VERSION: ${{ matrix.rust }}
26-
TARGET: ${{ matrix.target }}
26+
RUST_TARGET: ${{ matrix.target }}
2727
strategy:
28+
fail-fast: false
2829
matrix:
2930
include:
3031
- rust: 1.36.0
@@ -63,6 +64,7 @@ jobs:
6364
env:
6465
RUST_VERSION: ${{ matrix.rust }}
6566
strategy:
67+
fail-fast: false
6668
matrix:
6769
rust:
6870
- 1.36.0

ci/no_atomic.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,31 @@ for target in $(rustc --print target-list); do
2626
done
2727
echo "];" >>"$file"
2828

29+
{
30+
# Only crossbeam-utils actually uses this const.
31+
echo "#[allow(dead_code)]"
32+
echo "const NO_ATOMIC_64: &[&str] = &["
33+
} >>"$file"
34+
for target in $(rustc --print target-list); do
35+
res=$(rustc --print target-spec-json -Z unstable-options --target "$target" \
36+
| jq -r "select(.\"max-atomic-width\" == 32)")
37+
[[ -z "$res" ]] || echo " \"$target\"," >>"$file"
38+
done
39+
# It is not clear exactly what `"max-atomic-width" == null` means, but they
40+
# actually seem to have the same max-atomic-width as the target-pointer-width.
41+
# The targets currently included in this group are "mipsel-sony-psp",
42+
# "thumbv4t-none-eabi", "thumbv6m-none-eabi", all of which are
43+
# `"target-pointer-width" == "32"`, so assuming them `"max-atomic-width" == 32`
44+
# for now.
45+
for target in $(rustc --print target-list); do
46+
res=$(rustc --print target-spec-json -Z unstable-options --target "$target" \
47+
| jq -r "select(.\"max-atomic-width\" == null)")
48+
[[ -z "$res" ]] || echo " \"$target\"," >>"$file"
49+
done
50+
echo "];" >>"$file"
51+
52+
# There is no `"max-atomic-width" == 16` or `"max-atomic-width" == 8` targets.
53+
2954
# `"max-atomic-width" == 0` means that atomic is not supported at all.
3055
{
3156
# Only crossbeam-utils actually uses this const.

ci/test.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ set -ex
55

66
export RUSTFLAGS="-D warnings"
77

8-
if [[ -n "$TARGET" ]]; then
9-
# If TARGET is specified, use cross for testing.
8+
if [[ -n "$RUST_TARGET" ]]; then
9+
# If RUST_TARGET is specified, use cross for testing.
1010
cargo install cross
11-
cross test --all --target "$TARGET" --exclude benchmarks -- --test-threads=1
11+
cross test --all --target "$RUST_TARGET" --exclude benchmarks -- --test-threads=1
1212

1313
# For now, the non-host target only runs tests.
1414
exit 0

crossbeam-utils/Cargo.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,5 @@ lazy_static = { version = "1.4.0", optional = true }
4242
[target.'cfg(crossbeam_loom)'.dependencies]
4343
loom = { version = "0.5", optional = true }
4444

45-
[build-dependencies]
46-
autocfg = "1.0.0"
47-
4845
[dev-dependencies]
4946
rand = "0.8"

crossbeam-utils/build.rs

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
use std::env;
44

5-
use autocfg::AutoCfg;
6-
75
include!("no_atomic.rs");
86

97
// The rustc-cfg strings below are *not* public API. Please let us know by
@@ -31,25 +29,12 @@ fn main() {
3129
}
3230
if NO_ATOMIC.contains(&&*target) {
3331
println!("cargo:rustc-cfg=crossbeam_no_atomic");
32+
println!("cargo:rustc-cfg=crossbeam_no_atomic_64");
33+
} else if NO_ATOMIC_64.contains(&&*target) {
34+
println!("cargo:rustc-cfg=crossbeam_no_atomic_64");
35+
} else {
36+
// Otherwise, assuming `"max-atomic-width" == 64`.
3437
}
3538

36-
let cfg = match AutoCfg::new() {
37-
Ok(cfg) => cfg,
38-
Err(e) => {
39-
println!(
40-
"cargo:warning={}: unable to determine rustc version: {}",
41-
env!("CARGO_PKG_NAME"),
42-
e
43-
);
44-
return;
45-
}
46-
};
47-
48-
cfg.emit_type_cfg("core::sync::atomic::AtomicU8", "has_atomic_u8");
49-
cfg.emit_type_cfg("core::sync::atomic::AtomicU16", "has_atomic_u16");
50-
cfg.emit_type_cfg("core::sync::atomic::AtomicU32", "has_atomic_u32");
51-
cfg.emit_type_cfg("core::sync::atomic::AtomicU64", "has_atomic_u64");
52-
cfg.emit_type_cfg("core::sync::atomic::AtomicU128", "has_atomic_u128");
53-
5439
println!("cargo:rerun-if-changed=no_atomic.rs");
5540
}

crossbeam-utils/src/atomic/atomic_cell.rs

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -497,33 +497,25 @@ macro_rules! impl_arithmetic {
497497
};
498498
}
499499

500-
#[cfg(has_atomic_u8)]
501500
impl_arithmetic!(u8, atomic::AtomicU8, "let a = AtomicCell::new(7u8);");
502-
#[cfg(all(has_atomic_u8, not(crossbeam_loom)))]
503501
impl_arithmetic!(i8, atomic::AtomicI8, "let a = AtomicCell::new(7i8);");
504-
#[cfg(has_atomic_u16)]
505502
impl_arithmetic!(u16, atomic::AtomicU16, "let a = AtomicCell::new(7u16);");
506-
#[cfg(all(has_atomic_u16, not(crossbeam_loom)))]
507503
impl_arithmetic!(i16, atomic::AtomicI16, "let a = AtomicCell::new(7i16);");
508-
#[cfg(has_atomic_u32)]
509504
impl_arithmetic!(u32, atomic::AtomicU32, "let a = AtomicCell::new(7u32);");
510-
#[cfg(all(has_atomic_u32, not(crossbeam_loom)))]
511505
impl_arithmetic!(i32, atomic::AtomicI32, "let a = AtomicCell::new(7i32);");
512-
#[cfg(has_atomic_u64)]
506+
#[cfg(not(crossbeam_no_atomic_64))]
513507
impl_arithmetic!(u64, atomic::AtomicU64, "let a = AtomicCell::new(7u64);");
514-
#[cfg(all(has_atomic_u64, not(crossbeam_loom)))]
508+
#[cfg(not(crossbeam_no_atomic_64))]
515509
impl_arithmetic!(i64, atomic::AtomicI64, "let a = AtomicCell::new(7i64);");
516-
#[cfg(all(has_atomic_u128, not(crossbeam_loom)))]
517-
impl_arithmetic!(u128, atomic::AtomicU128, "let a = AtomicCell::new(7u128);");
518-
#[cfg(all(has_atomic_u128, not(crossbeam_loom)))]
519-
impl_arithmetic!(i128, atomic::AtomicI128, "let a = AtomicCell::new(7i128);");
510+
// TODO: AtomicU128 is unstable
511+
// impl_arithmetic!(u128, atomic::AtomicU128, "let a = AtomicCell::new(7u128);");
512+
// impl_arithmetic!(i128, atomic::AtomicI128, "let a = AtomicCell::new(7i128);");
520513

521514
impl_arithmetic!(
522515
usize,
523516
atomic::AtomicUsize,
524517
"let a = AtomicCell::new(7usize);"
525518
);
526-
#[cfg(not(crossbeam_loom))]
527519
impl_arithmetic!(
528520
isize,
529521
atomic::AtomicIsize,
@@ -809,16 +801,13 @@ macro_rules! atomic {
809801
atomic!(@check, $t, AtomicUnit, $a, $atomic_op);
810802
atomic!(@check, $t, atomic::AtomicUsize, $a, $atomic_op);
811803

812-
#[cfg(has_atomic_u8)]
813804
atomic!(@check, $t, atomic::AtomicU8, $a, $atomic_op);
814-
#[cfg(has_atomic_u16)]
815805
atomic!(@check, $t, atomic::AtomicU16, $a, $atomic_op);
816-
#[cfg(has_atomic_u32)]
817806
atomic!(@check, $t, atomic::AtomicU32, $a, $atomic_op);
818-
#[cfg(has_atomic_u64)]
807+
#[cfg(not(crossbeam_no_atomic_64))]
819808
atomic!(@check, $t, atomic::AtomicU64, $a, $atomic_op);
820-
#[cfg(has_atomic_u128)]
821-
atomic!(@check, $t, atomic::AtomicU128, $a, $atomic_op);
809+
// TODO: AtomicU128 is unstable
810+
// atomic!(@check, $t, atomic::AtomicU128, $a, $atomic_op);
822811

823812
#[cfg(crossbeam_loom)]
824813
unimplemented!("loom does not support non-atomic atomic ops");
@@ -831,17 +820,15 @@ macro_rules! atomic {
831820
/// Returns `true` if operations on `AtomicCell<T>` are lock-free.
832821
const fn atomic_is_lock_free<T>() -> bool {
833822
// HACK(taiki-e): This is equivalent to `atomic! { T, _a, true, false }`, but can be used in const fn even in Rust 1.36.
834-
let is_lock_free = can_transmute::<T, AtomicUnit>() | can_transmute::<T, atomic::AtomicUsize>();
835-
#[cfg(has_atomic_u8)]
836-
let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU8>();
837-
#[cfg(has_atomic_u16)]
838-
let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU16>();
839-
#[cfg(has_atomic_u32)]
840-
let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU32>();
841-
#[cfg(has_atomic_u64)]
823+
let is_lock_free = can_transmute::<T, AtomicUnit>()
824+
| can_transmute::<T, atomic::AtomicUsize>()
825+
| can_transmute::<T, atomic::AtomicU8>()
826+
| can_transmute::<T, atomic::AtomicU16>()
827+
| can_transmute::<T, atomic::AtomicU32>();
828+
#[cfg(not(crossbeam_no_atomic_64))]
842829
let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU64>();
843-
#[cfg(has_atomic_u128)]
844-
let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU128>();
830+
// TODO: AtomicU128 is unstable
831+
// let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU128>();
845832
is_lock_free
846833
}
847834

crossbeam-utils/src/atomic/consume.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,21 +68,15 @@ macro_rules! impl_atomic {
6868
impl_atomic!(AtomicBool, bool);
6969
impl_atomic!(AtomicUsize, usize);
7070
impl_atomic!(AtomicIsize, isize);
71-
#[cfg(has_atomic_u8)]
7271
impl_atomic!(AtomicU8, u8);
73-
#[cfg(has_atomic_u8)]
7472
impl_atomic!(AtomicI8, i8);
75-
#[cfg(has_atomic_u16)]
7673
impl_atomic!(AtomicU16, u16);
77-
#[cfg(has_atomic_u16)]
7874
impl_atomic!(AtomicI16, i16);
79-
#[cfg(has_atomic_u32)]
8075
impl_atomic!(AtomicU32, u32);
81-
#[cfg(has_atomic_u32)]
8276
impl_atomic!(AtomicI32, i32);
83-
#[cfg(has_atomic_u64)]
77+
#[cfg(not(crossbeam_no_atomic_64))]
8478
impl_atomic!(AtomicU64, u64);
85-
#[cfg(has_atomic_u64)]
79+
#[cfg(not(crossbeam_no_atomic_64))]
8680
impl_atomic!(AtomicI64, i64);
8781

8882
#[cfg(not(crossbeam_no_atomic))]

crossbeam-utils/src/lib.rs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ mod primitive {
4646
pub(crate) mod atomic {
4747
pub(crate) use loom::sync::atomic::spin_loop_hint;
4848
pub(crate) use loom::sync::atomic::{
49-
AtomicBool, AtomicU16, AtomicU32, AtomicU64, AtomicU8, AtomicUsize,
49+
AtomicBool, AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicU16,
50+
AtomicU32, AtomicU64, AtomicU8, AtomicUsize,
5051
};
5152

5253
// FIXME: loom does not support compiler_fence at the moment.
@@ -70,19 +71,12 @@ mod primitive {
7071
#[allow(deprecated)]
7172
pub(crate) use core::sync::atomic::spin_loop_hint;
7273
#[cfg(not(crossbeam_no_atomic))]
73-
pub(crate) use core::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize};
74-
#[cfg(not(crossbeam_no_atomic))]
75-
#[cfg(has_atomic_u16)]
76-
pub(crate) use core::sync::atomic::{AtomicI16, AtomicU16};
77-
#[cfg(not(crossbeam_no_atomic))]
78-
#[cfg(has_atomic_u32)]
79-
pub(crate) use core::sync::atomic::{AtomicI32, AtomicU32};
80-
#[cfg(not(crossbeam_no_atomic))]
81-
#[cfg(has_atomic_u64)]
74+
pub(crate) use core::sync::atomic::{
75+
AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32,
76+
AtomicU8, AtomicUsize,
77+
};
78+
#[cfg(not(crossbeam_no_atomic_64))]
8279
pub(crate) use core::sync::atomic::{AtomicI64, AtomicU64};
83-
#[cfg(not(crossbeam_no_atomic))]
84-
#[cfg(has_atomic_u8)]
85-
pub(crate) use core::sync::atomic::{AtomicI8, AtomicU8};
8680
}
8781

8882
#[cfg(feature = "std")]

crossbeam-utils/tests/atomic_cell.rs

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::mem;
12
use std::sync::atomic::AtomicUsize;
23
use std::sync::atomic::Ordering::SeqCst;
34

@@ -8,18 +9,47 @@ fn is_lock_free() {
89
struct UsizeWrap(usize);
910
struct U8Wrap(bool);
1011
struct I16Wrap(i16);
11-
12-
assert_eq!(AtomicCell::<usize>::is_lock_free(), true);
13-
assert_eq!(AtomicCell::<isize>::is_lock_free(), true);
14-
assert_eq!(AtomicCell::<UsizeWrap>::is_lock_free(), true);
15-
16-
assert_eq!(AtomicCell::<u8>::is_lock_free(), cfg!(has_atomic_u8));
17-
assert_eq!(AtomicCell::<bool>::is_lock_free(), cfg!(has_atomic_u8));
18-
assert_eq!(AtomicCell::<U8Wrap>::is_lock_free(), cfg!(has_atomic_u8));
19-
20-
assert_eq!(AtomicCell::<I16Wrap>::is_lock_free(), cfg!(has_atomic_u16));
21-
22-
assert_eq!(AtomicCell::<u128>::is_lock_free(), cfg!(has_atomic_u128));
12+
#[repr(align(8))]
13+
struct U64Align8(u64);
14+
15+
assert!(AtomicCell::<usize>::is_lock_free());
16+
assert!(AtomicCell::<isize>::is_lock_free());
17+
assert!(AtomicCell::<UsizeWrap>::is_lock_free());
18+
19+
assert!(AtomicCell::<()>::is_lock_free());
20+
21+
assert!(AtomicCell::<u8>::is_lock_free());
22+
assert!(AtomicCell::<i8>::is_lock_free());
23+
assert!(AtomicCell::<bool>::is_lock_free());
24+
assert!(AtomicCell::<U8Wrap>::is_lock_free());
25+
26+
assert!(AtomicCell::<u16>::is_lock_free());
27+
assert!(AtomicCell::<i16>::is_lock_free());
28+
assert!(AtomicCell::<I16Wrap>::is_lock_free());
29+
30+
assert!(AtomicCell::<u32>::is_lock_free());
31+
assert!(AtomicCell::<i32>::is_lock_free());
32+
33+
// Sizes of both types must be equal, and the alignment of `u64` must be greater or equal than
34+
// that of `AtomicU64`. In i686-unknown-linux-gnu, the alignment of `u64` is `4` and alignment
35+
// of `AtomicU64` is `8`, so `AtomicCell<u64>` is not lock-free.
36+
assert_eq!(
37+
AtomicCell::<u64>::is_lock_free(),
38+
cfg!(not(crossbeam_no_atomic_64))
39+
&& cfg!(any(
40+
target_pointer_width = "64",
41+
target_pointer_width = "128"
42+
))
43+
);
44+
assert_eq!(mem::size_of::<U64Align8>(), 8);
45+
assert_eq!(mem::align_of::<U64Align8>(), 8);
46+
assert_eq!(
47+
AtomicCell::<U64Align8>::is_lock_free(),
48+
cfg!(not(crossbeam_no_atomic_64))
49+
);
50+
51+
// AtomicU128 is unstable
52+
assert!(!AtomicCell::<u128>::is_lock_free());
2353
}
2454

2555
#[test]

no_atomic.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,47 @@ const NO_ATOMIC_CAS: &[&str] = &[
1010
"thumbv6m-none-eabi",
1111
];
1212
#[allow(dead_code)]
13+
const NO_ATOMIC_64: &[&str] = &[
14+
"arm-linux-androideabi",
15+
"armebv7r-none-eabi",
16+
"armebv7r-none-eabihf",
17+
"armv4t-unknown-linux-gnueabi",
18+
"armv5te-unknown-linux-gnueabi",
19+
"armv5te-unknown-linux-musleabi",
20+
"armv5te-unknown-linux-uclibceabi",
21+
"armv7r-none-eabi",
22+
"armv7r-none-eabihf",
23+
"hexagon-unknown-linux-musl",
24+
"mips-unknown-linux-gnu",
25+
"mips-unknown-linux-musl",
26+
"mips-unknown-linux-uclibc",
27+
"mipsel-unknown-linux-gnu",
28+
"mipsel-unknown-linux-musl",
29+
"mipsel-unknown-linux-uclibc",
30+
"mipsel-unknown-none",
31+
"mipsisa32r6-unknown-linux-gnu",
32+
"mipsisa32r6el-unknown-linux-gnu",
33+
"powerpc-unknown-linux-gnu",
34+
"powerpc-unknown-linux-gnuspe",
35+
"powerpc-unknown-linux-musl",
36+
"powerpc-unknown-netbsd",
37+
"powerpc-unknown-openbsd",
38+
"powerpc-wrs-vxworks",
39+
"powerpc-wrs-vxworks-spe",
40+
"riscv32gc-unknown-linux-gnu",
41+
"riscv32gc-unknown-linux-musl",
42+
"riscv32imac-unknown-none-elf",
43+
"thumbv7em-none-eabi",
44+
"thumbv7em-none-eabihf",
45+
"thumbv7m-none-eabi",
46+
"thumbv8m.base-none-eabi",
47+
"thumbv8m.main-none-eabi",
48+
"thumbv8m.main-none-eabihf",
49+
"mipsel-sony-psp",
50+
"thumbv4t-none-eabi",
51+
"thumbv6m-none-eabi",
52+
];
53+
#[allow(dead_code)]
1354
const NO_ATOMIC: &[&str] = &[
1455
"avr-unknown-gnu-atmega328",
1556
"msp430-none-elf",

0 commit comments

Comments
 (0)