Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

time: use clock_gettime on macos #116238

Merged
merged 3 commits into from
Oct 24, 2023
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
time: use clock_gettime on macos
Replace `gettimeofday` with `clock_gettime(CLOCK_REALTIME)` on:

```
all(target_os = "macos", not(target_arch = "aarch64")),
    target_os = "ios",
    target_os = "watchos",
    target_os = "tvos"
))]
```

`gettimeofday` was first used in
time-rs/time@cc367ed
which predated the introduction of `clock_gettime` support in macOS
10.12 Sierra which became the minimum supported version in
58bbca9.
tamird committed Sep 28, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
commit b21eb4f046284040b8e91aff0fd1e7c5125864d1
84 changes: 35 additions & 49 deletions library/std/src/sys/unix/time.rs
Original file line number Diff line number Diff line change
@@ -40,6 +40,10 @@ impl SystemTime {
SystemTime { t: Timespec::new(tv_sec, tv_nsec) }
}

pub fn now() -> SystemTime {
SystemTime { t: Timespec::now(libc::CLOCK_REALTIME) }
}

pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
self.t.sub_timespec(&other.t)
}
@@ -79,6 +83,36 @@ impl Timespec {
Timespec { tv_sec, tv_nsec: unsafe { Nanoseconds(tv_nsec as u32) } }
}

pub fn now(clock: libc::clockid_t) -> Timespec {
use crate::mem::MaybeUninit;
use crate::sys::cvt;

// Try to use 64-bit time in preparation for Y2038.
#[cfg(all(
target_os = "linux",
target_env = "gnu",
target_pointer_width = "32",
not(target_arch = "riscv32")
))]
{
use crate::sys::weak::weak;

// __clock_gettime64 was added to 32-bit arches in glibc 2.34,
// and it handles both vDSO calls and ENOSYS fallbacks itself.
weak!(fn __clock_gettime64(libc::clockid_t, *mut __timespec64) -> libc::c_int);

if let Some(clock_gettime64) = __clock_gettime64.get() {
let mut t = MaybeUninit::uninit();
cvt(unsafe { clock_gettime64(clock, t.as_mut_ptr()) }).unwrap();
return Timespec::from(unsafe { t.assume_init() });
}
}

let mut t = MaybeUninit::uninit();
cvt(unsafe { libc::clock_gettime(clock, t.as_mut_ptr()) }).unwrap();
Timespec::from(unsafe { t.assume_init() })
}

pub fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
if self >= other {
// NOTE(eddyb) two aspects of this `if`-`else` are required for LLVM
@@ -224,7 +258,6 @@ impl From<__timespec64> for Timespec {
))]
mod inner {
use crate::sync::atomic::{AtomicU64, Ordering};
use crate::sys::cvt;
use crate::sys_common::mul_div_u64;
use crate::time::Duration;

@@ -268,16 +301,6 @@ mod inner {
}
}

impl SystemTime {
pub fn now() -> SystemTime {
use crate::ptr;

let mut s = libc::timeval { tv_sec: 0, tv_usec: 0 };
cvt(unsafe { libc::gettimeofday(&mut s, ptr::null_mut()) }).unwrap();
return SystemTime::from(s);
}
}

impl From<libc::timeval> for Timespec {
fn from(t: libc::timeval) -> Timespec {
Timespec::new(t.tv_sec as i64, 1000 * t.tv_usec as i64)
@@ -345,11 +368,9 @@ mod inner {
)))]
mod inner {
use crate::fmt;
use crate::mem::MaybeUninit;
use crate::sys::cvt;
use crate::time::Duration;

use super::{SystemTime, Timespec};
use super::Timespec;

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Instant {
@@ -386,39 +407,4 @@ mod inner {
.finish()
}
}

impl SystemTime {
pub fn now() -> SystemTime {
SystemTime { t: Timespec::now(libc::CLOCK_REALTIME) }
}
}

impl 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",
not(target_arch = "riscv32")
))]
{
use crate::sys::weak::weak;

// __clock_gettime64 was added to 32-bit arches in glibc 2.34,
// and it handles both vDSO calls and ENOSYS fallbacks itself.
weak!(fn __clock_gettime64(libc::clockid_t, *mut super::__timespec64) -> libc::c_int);

if let Some(clock_gettime64) = __clock_gettime64.get() {
let mut t = MaybeUninit::uninit();
cvt(unsafe { clock_gettime64(clock, t.as_mut_ptr()) }).unwrap();
return Timespec::from(unsafe { t.assume_init() });
}
}

let mut t = MaybeUninit::uninit();
cvt(unsafe { libc::clock_gettime(clock, t.as_mut_ptr()) }).unwrap();
Timespec::from(unsafe { t.assume_init() })
}
}
}
3 changes: 1 addition & 2 deletions library/std/src/time.rs
Original file line number Diff line number Diff line change
@@ -221,7 +221,7 @@ pub struct Instant(time::Instant);
/// |-----------|----------------------------------------------------------------------|
/// | SGX | [`insecure_time` usercall]. More information on [timekeeping in SGX] |
/// | UNIX | [clock_gettime (Realtime Clock)] |
/// | Darwin | [gettimeofday] |
/// | Darwin | [clock_gettime (Realtime Clock)] |
/// | VXWorks | [clock_gettime (Realtime Clock)] |
/// | SOLID | `SOLID_RTC_ReadTime` |
/// | WASI | [__wasi_clock_time_get (Realtime Clock)] |
@@ -230,7 +230,6 @@ pub struct Instant(time::Instant);
/// [currently]: crate::io#platform-specific-behavior
/// [`insecure_time` usercall]: https://edp.fortanix.com/docs/api/fortanix_sgx_abi/struct.Usercalls.html#method.insecure_time
/// [timekeeping in SGX]: https://edp.fortanix.com/docs/concepts/rust-std/#codestdtimecode
/// [gettimeofday]: https://man7.org/linux/man-pages/man2/gettimeofday.2.html
/// [clock_gettime (Realtime Clock)]: https://linux.die.net/man/3/clock_gettime
/// [__wasi_clock_time_get (Realtime Clock)]: https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/docs.md#clock_time_get
/// [GetSystemTimePreciseAsFileTime]: https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime