Skip to content

Commit 5361c79

Browse files
authored
Merge pull request #2337 from badboy/use-target_has_atomic-when-available
Use `target_has_atomic` on Rust 1.60+ to enable atomic (de)serialization
2 parents 3aec2a9 + 126730e commit 5361c79

File tree

4 files changed

+103
-21
lines changed

4 files changed

+103
-21
lines changed

serde/build.rs

+17-13
Original file line numberDiff line numberDiff line change
@@ -95,19 +95,23 @@ fn main() {
9595
// Whitelist of archs that support std::sync::atomic module. Ideally we
9696
// would use #[cfg(target_has_atomic = "...")] but it is not stable yet.
9797
// Instead this is based on rustc's compiler/rustc_target/src/spec/*.rs.
98-
let has_atomic64 = target.starts_with("x86_64")
99-
|| target.starts_with("i686")
100-
|| target.starts_with("aarch64")
101-
|| target.starts_with("powerpc64")
102-
|| target.starts_with("sparc64")
103-
|| target.starts_with("mips64el")
104-
|| target.starts_with("riscv64");
105-
let has_atomic32 = has_atomic64 || emscripten;
106-
if minor < 34 || !has_atomic64 {
107-
println!("cargo:rustc-cfg=no_std_atomic64");
108-
}
109-
if minor < 34 || !has_atomic32 {
110-
println!("cargo:rustc-cfg=no_std_atomic");
98+
if minor >= 60 {
99+
println!("cargo:rustc-cfg=use_target_has_atomic");
100+
} else {
101+
let has_atomic64 = target.starts_with("x86_64")
102+
|| target.starts_with("i686")
103+
|| target.starts_with("aarch64")
104+
|| target.starts_with("powerpc64")
105+
|| target.starts_with("sparc64")
106+
|| target.starts_with("mips64el")
107+
|| target.starts_with("riscv64");
108+
let has_atomic32 = has_atomic64 || emscripten;
109+
if minor < 34 || !has_atomic64 {
110+
println!("cargo:rustc-cfg=no_std_atomic64");
111+
}
112+
if minor < 34 || !has_atomic32 {
113+
println!("cargo:rustc-cfg=no_std_atomic");
114+
}
111115
}
112116
}
113117

serde/src/de/impls.rs

+35-3
Original file line numberDiff line numberDiff line change
@@ -2660,7 +2660,7 @@ where
26602660
}
26612661
}
26622662

2663-
#[cfg(all(feature = "std", not(no_std_atomic)))]
2663+
#[cfg(all(feature = "std", not(use_target_has_atomic), not(no_std_atomic)))]
26642664
macro_rules! atomic_impl {
26652665
($($ty:ident)*) => {
26662666
$(
@@ -2676,18 +2676,50 @@ macro_rules! atomic_impl {
26762676
};
26772677
}
26782678

2679-
#[cfg(all(feature = "std", not(no_std_atomic)))]
2679+
#[cfg(all(feature = "std", use_target_has_atomic))]
2680+
macro_rules! atomic_impl {
2681+
( $( $ty:ident $size:expr ),* ) => {
2682+
$(
2683+
#[cfg(target_has_atomic = $size)]
2684+
impl<'de> Deserialize<'de> for $ty {
2685+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
2686+
where
2687+
D: Deserializer<'de>,
2688+
{
2689+
Deserialize::deserialize(deserializer).map(Self::new)
2690+
}
2691+
}
2692+
)*
2693+
};
2694+
}
2695+
2696+
#[cfg(all(feature = "std", not(use_target_has_atomic), not(no_std_atomic)))]
26802697
atomic_impl! {
26812698
AtomicBool
26822699
AtomicI8 AtomicI16 AtomicI32 AtomicIsize
26832700
AtomicU8 AtomicU16 AtomicU32 AtomicUsize
26842701
}
26852702

2686-
#[cfg(all(feature = "std", not(no_std_atomic64)))]
2703+
#[cfg(all(feature = "std", not(use_target_has_atomic), not(no_std_atomic64)))]
26872704
atomic_impl! {
26882705
AtomicI64 AtomicU64
26892706
}
26902707

2708+
#[cfg(all(feature = "std", use_target_has_atomic))]
2709+
atomic_impl! {
2710+
AtomicBool "8",
2711+
AtomicI8 "8",
2712+
AtomicI16 "16",
2713+
AtomicI32 "32",
2714+
AtomicI64 "64",
2715+
AtomicIsize "ptr",
2716+
AtomicU8 "8",
2717+
AtomicU16 "16",
2718+
AtomicU32 "32",
2719+
AtomicU64 "64",
2720+
AtomicUsize "ptr"
2721+
}
2722+
26912723
#[cfg(feature = "std")]
26922724
struct FromStrVisitor<T> {
26932725
expecting: &'static str,

serde/src/lib.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -236,14 +236,27 @@ mod lib {
236236
#[cfg(not(no_range_inclusive))]
237237
pub use self::core::ops::RangeInclusive;
238238

239-
#[cfg(all(feature = "std", not(no_std_atomic)))]
239+
#[cfg(all(feature = "std", not(use_target_has_atomic), not(no_std_atomic)))]
240240
pub use std::sync::atomic::{
241241
AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8,
242242
AtomicUsize, Ordering,
243243
};
244-
#[cfg(all(feature = "std", not(no_std_atomic64)))]
244+
#[cfg(all(feature = "std", not(use_target_has_atomic), not(no_std_atomic64)))]
245245
pub use std::sync::atomic::{AtomicI64, AtomicU64};
246246

247+
#[cfg(all(feature = "std", use_target_has_atomic))]
248+
pub use std::sync::atomic::Ordering;
249+
#[cfg(all(feature = "std", use_target_has_atomic, target_has_atomic = "8"))]
250+
pub use std::sync::atomic::{AtomicBool, AtomicI8, AtomicU8};
251+
#[cfg(all(feature = "std", use_target_has_atomic, target_has_atomic = "16"))]
252+
pub use std::sync::atomic::{AtomicI16, AtomicU16};
253+
#[cfg(all(feature = "std", use_target_has_atomic, target_has_atomic = "32"))]
254+
pub use std::sync::atomic::{AtomicI32, AtomicU32};
255+
#[cfg(all(feature = "std", use_target_has_atomic, target_has_atomic = "64"))]
256+
pub use std::sync::atomic::{AtomicI64, AtomicU64};
257+
#[cfg(all(feature = "std", use_target_has_atomic, target_has_atomic = "ptr"))]
258+
pub use std::sync::atomic::{AtomicUsize, AtomicIsize};
259+
247260
#[cfg(any(feature = "std", not(no_core_duration)))]
248261
pub use self::core::time::Duration;
249262
}

serde/src/ser/impls.rs

+36-3
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,7 @@ where
945945

946946
////////////////////////////////////////////////////////////////////////////////
947947

948-
#[cfg(all(feature = "std", not(no_std_atomic)))]
948+
#[cfg(all(feature = "std", not(use_target_has_atomic), not(no_std_atomic)))]
949949
macro_rules! atomic_impl {
950950
($($ty:ident)*) => {
951951
$(
@@ -962,14 +962,47 @@ macro_rules! atomic_impl {
962962
}
963963
}
964964

965-
#[cfg(all(feature = "std", not(no_std_atomic)))]
965+
#[cfg(all(feature = "std", use_target_has_atomic))]
966+
macro_rules! atomic_impl {
967+
( $( $ty:ident $size:expr ),* ) => {
968+
$(
969+
#[cfg(target_has_atomic = $size)]
970+
impl Serialize for $ty {
971+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
972+
where
973+
S: Serializer,
974+
{
975+
// Matches the atomic ordering used in libcore for the Debug impl
976+
self.load(Ordering::Relaxed).serialize(serializer)
977+
}
978+
}
979+
)*
980+
}
981+
}
982+
983+
#[cfg(all(feature = "std", not(use_target_has_atomic), not(no_std_atomic)))]
966984
atomic_impl! {
967985
AtomicBool
968986
AtomicI8 AtomicI16 AtomicI32 AtomicIsize
969987
AtomicU8 AtomicU16 AtomicU32 AtomicUsize
970988
}
971989

972-
#[cfg(all(feature = "std", not(no_std_atomic64)))]
990+
#[cfg(all(feature = "std", not(use_target_has_atomic), not(no_std_atomic64)))]
973991
atomic_impl! {
974992
AtomicI64 AtomicU64
975993
}
994+
995+
#[cfg(all(feature = "std", use_target_has_atomic))]
996+
atomic_impl! {
997+
AtomicBool "8",
998+
AtomicI8 "8",
999+
AtomicI16 "16",
1000+
AtomicI32 "32",
1001+
AtomicI64 "64",
1002+
AtomicIsize "ptr",
1003+
AtomicU8 "8",
1004+
AtomicU16 "16",
1005+
AtomicU32 "32",
1006+
AtomicU64 "64",
1007+
AtomicUsize "ptr"
1008+
}

0 commit comments

Comments
 (0)