From 5008a317ce8e508c390ed12bff281f307313376e Mon Sep 17 00:00:00 2001 From: Joy <51241057+maniwani@users.noreply.github.com> Date: Wed, 26 Oct 2022 11:43:18 -0700 Subject: [PATCH 1/3] Fix non-associativity of `Instant` math on `aarch64-apple-darwin` targets --- library/std/src/sys/unix/time.rs | 18 +++++++++++++++--- library/std/src/time/tests.rs | 8 ++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/library/std/src/sys/unix/time.rs b/library/std/src/sys/unix/time.rs index cca9c67670161..b65566740b50c 100644 --- a/library/std/src/sys/unix/time.rs +++ b/library/std/src/sys/unix/time.rs @@ -149,7 +149,11 @@ impl From for Timespec { } } -#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))] +#[cfg(any( + all(target_os = "macos", not(target_arch = "aarch64")), + target_os = "ios", + target_os = "watchos" +))] mod inner { use crate::sync::atomic::{AtomicU64, Ordering}; use crate::sys::cvt; @@ -265,7 +269,11 @@ mod inner { } } -#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "watchos")))] +#[cfg(not(any( + all(target_os = "macos", not(target_arch = "aarch64")), + target_os = "ios", + target_os = "watchos" +)))] mod inner { use crate::fmt; use crate::mem::MaybeUninit; @@ -281,7 +289,11 @@ mod inner { impl Instant { pub fn now() -> Instant { - Instant { t: Timespec::now(libc::CLOCK_MONOTONIC) } + #[cfg(target_os = "macos")] + const clock_id: clock_t = libc::CLOCK_UPTIME_RAW; + #[cfg(not(target_os = "macos"))] + const clock_id: clock_t = libc::CLOCK_MONOTONIC; + Instant { t: Timespec::now(clock_id) } } pub fn checked_sub_instant(&self, other: &Instant) -> Option { diff --git a/library/std/src/time/tests.rs b/library/std/src/time/tests.rs index 6229556c85fee..2e64ae59aff24 100644 --- a/library/std/src/time/tests.rs +++ b/library/std/src/time/tests.rs @@ -88,6 +88,14 @@ fn instant_math_is_associative() { // Changing the order of instant math shouldn't change the results, // especially when the expression reduces to X + identity. assert_eq!((now + offset) - now, (now - now) + offset); + + // On any platform, `Instant` should have the same resolution as `Duration` (e.g. 1 nanosecond) + // or better. Otherwise, math will be non-associative (see #91417). + let now = Instant::now(); + let provided_offset = Duration::from_nanos(1); + let later = now + provided_offset; + let measured_offset = later - now; + assert_eq!(measured_offset, provided_offset); } #[test] From 015ab659c2fcdf2f3a3fdaa6dc44455b9d0c2f3e Mon Sep 17 00:00:00 2001 From: Cameron <51241057+maniwani@users.noreply.github.com> Date: Sun, 13 Nov 2022 12:33:21 -0800 Subject: [PATCH 2/3] just use `libc::clockid_t` --- library/std/src/sys/unix/time.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/library/std/src/sys/unix/time.rs b/library/std/src/sys/unix/time.rs index b65566740b50c..c3fac44a42d2d 100644 --- a/library/std/src/sys/unix/time.rs +++ b/library/std/src/sys/unix/time.rs @@ -290,9 +290,9 @@ mod inner { impl Instant { pub fn now() -> Instant { #[cfg(target_os = "macos")] - const clock_id: clock_t = libc::CLOCK_UPTIME_RAW; + const clock_id: libc::clockid_t = libc::CLOCK_UPTIME_RAW; #[cfg(not(target_os = "macos"))] - const clock_id: clock_t = libc::CLOCK_MONOTONIC; + const clock_id: libc::clockid_t = libc::CLOCK_MONOTONIC; Instant { t: Timespec::now(clock_id) } } @@ -324,13 +324,8 @@ mod inner { } } - #[cfg(not(any(target_os = "dragonfly", target_os = "espidf", target_os = "horizon")))] - pub type clock_t = libc::c_int; - #[cfg(any(target_os = "dragonfly", target_os = "espidf", target_os = "horizon"))] - pub type clock_t = libc::c_ulong; - impl Timespec { - pub fn now(clock: clock_t) -> Timespec { + pub fn now(clock: libc::clockid_t) -> Timespec { // Try to use 64-bit time in preparation for Y2038. #[cfg(all(target_os = "linux", target_env = "gnu", target_pointer_width = "32"))] { From f4f515973ecc689029b64759ff43dbba0e207be2 Mon Sep 17 00:00:00 2001 From: Cameron <51241057+maniwani@users.noreply.github.com> Date: Mon, 14 Nov 2022 09:17:21 -0800 Subject: [PATCH 3/3] macos, aarch64, and not(miri) --- library/std/src/sys/unix/time.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/unix/time.rs b/library/std/src/sys/unix/time.rs index c3fac44a42d2d..ffcc507d2a763 100644 --- a/library/std/src/sys/unix/time.rs +++ b/library/std/src/sys/unix/time.rs @@ -150,7 +150,7 @@ impl From for Timespec { } #[cfg(any( - all(target_os = "macos", not(target_arch = "aarch64")), + all(target_os = "macos", any(not(target_arch = "aarch64"), miri)), target_os = "ios", target_os = "watchos" ))] @@ -270,7 +270,7 @@ mod inner { } #[cfg(not(any( - all(target_os = "macos", not(target_arch = "aarch64")), + all(target_os = "macos", any(not(target_arch = "aarch64"), miri)), target_os = "ios", target_os = "watchos" )))]