-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
use CLOCK_BOOTTIME in Instant::now #88714
Conversation
(rust-highfive has picked a reviewer for you, use r? to override) |
library/std/src/sys/unix/time.rs
Outdated
let t = match now(libc::CLOCK_BOOTTIME) { | ||
Err(e) if e.kind() == io::ErrorKind::InvalidInput => now(libc::CLOCK_MONOTONIC), | ||
v => v, | ||
} | ||
.unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO this match is easier to read than a or_else
, but I'm not sure if that's faster/better/stronger.
Here's a godbolt link, maybe someone can decide what to use: https://rust.godbolt.org/z/6Eoxc7PEz
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At a glance, there is not what I would consider a significant enough difference in the assembly to merit one approach over another, which is as it should be for such similar expressions. One may be better contextually if carefully benchmarked.
library/std/src/sys/unix/time.rs
Outdated
let mut t = Timespec { t: libc::timespec { tv_sec: 0, tv_nsec: 0 } }; | ||
cvt(unsafe { libc::clock_gettime(clock, &mut t.t) }).unwrap(); | ||
t | ||
cvt(unsafe { libc::clock_gettime(clock, &mut t.t) }).map(|_| t) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I write:
cvt(...)?;
t
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, please.
Alright, so the situation is the following:
So yeah, that's why I didn't open this PR yet. |
macos currently uses
and
Following that: http://manpagez.com/man/3/clock_gettime_nsec_np/
I'm more than willing to also add a change for that. Only problem I don't have a mac to test that. |
Essentially all the clock APIs on Darwin other than We support back to macOS 10.6 or 10.7, which is considerably older. Darwin 16 is only about 4 or 5 years old, and I think it would be a problem for libstd to require this. |
It would be a good idea if further metadiscussion took place in the original issue, since it seems to be that the discussion is ongoing. Discussion immediately relevant to this PR's code, of course, can continue here. |
@thomcc I think it's reasonable to handle macOS in a separate PR. And as with this PR, it'd be acceptable if the primary approach required new macOS and the fallback didn't account for suspend time. |
Should this also be tagged with |
This needs an update to make the use of This also needs an update (as noticed by the author) to use |
Ping from triage: |
I'm sorry for the late response. Got many things to do. I reworked the error handling in the Linux is only used if I see it correctly because of the |
The You need to add a cfg limiting the use of |
ALright, I wrapped it into |
Please add I'm not on the libs team, but I see no reason we'd need a fallback path now that #95026 is merged - we no longer support any of the Linux systems where |
We don't need a fallback anymore -- we just need to decide if we want to change this after all. |
Can we please make this happen now? My impression is that we had agreed on switching to |
☔ The latest upstream changes (presumably #104573) made this pull request unmergeable. Please resolve the merge conflicts. |
@hellow554 - PR has merge conflicts FYI: when a PR is ready for review, send a message containing |
My impression is this PR is still waiting on the decision. |
There was a discussion on rust-lang#87907 that all platforms expect linux advance its monotonic timer if the system goes into a sleep state (e.g. suspend or hibernate). It was decided that CLOCK_BOOTTIME should be used on unix targets.
Hey! It looks like you've submitted a new PR for the library teams! If this PR contains changes to any Examples of
|
@rustbot ready |
This comment has been minimized.
This comment has been minimized.
That's an error I can't explain. Maybe somebody can? - Instant {
- t: Timespec::now(if cfg!(target_os = "linux") {
- libc::CLOCK_BOOTTIME
- } else {
- libc::CLOCK_MONOTONIC
- }),
- }
+ #[cfg(target_os = "macos")]
+ const clock_id: libc::clockid_t = libc::CLOCK_UPTIME_RAW;
+
+ #[cfg(target_os = "linux")]
+ const clock_id: libc::clockid_t = libc::CLOCK_BOOTTIME;
+
+ #[cfg(not(any(target_os = "macos", target_os = "linux")))]
+ const clock_id: libc::clockid_t = libc::CLOCK_MONOTONIC;
+
+ Instant { t: Timespec::now(clock_id) } that's not a lot of changes and certainly no changes that should do have an impact. Maybe something else changed in the meantime? |
It looks like Miri tests are failing when emulating I think it needs to be added to the shims: |
The Miri subtree was changed cc @rust-lang/miri |
This does not seem accurate. Since #103594, macOS on aarch64 uses CLOCK_UPTIME_RAW which does not increment when the system is asleep. On x86 it uses mach_absolute_time which, according to that manpage, also does not increment when the system is asleep. |
@@ -45,6 +45,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { | |||
relative_clocks = vec![ | |||
this.eval_libc_i32("CLOCK_MONOTONIC")?, | |||
this.eval_libc_i32("CLOCK_MONOTONIC_COARSE")?, | |||
// This is the equivalent to `CLOCK_UPTIME_RAW` in the macos section | |||
// We support it, because std relies on it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is backwards -- BOOTTIME you say does increment when the machine is asleep, but CLOCK_UPTIME_RAW does not.
If anything, it seems like CLOCK_BOOTTIME on linux is like CLOCK_MONOTONIC on macOS, and CLOCK_MONOTONIC on linux is like CLOCK_UPTIME_RAW (and mach_absolute_time) on macos?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah judging from a quick search, looks like MONOTONIC on Linux does not increment when sleeping, but on macos it does. It also looks before this PR we are actually consistent (both Linux and macos use clocks that do not count when the system is asleep), and this PR makes us inconsistent by changing only Linux.
Or maybe I am looking at the wrong docs? This seems to look reasonably official though for macos.
#[cfg(not(target_os = "macos"))] | ||
|
||
#[cfg(target_os = "linux")] | ||
const clock_id: libc::clockid_t = libc::CLOCK_BOOTTIME; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we have documentation saying that Instant
, when possible, will use a clock that keeps going when the system is asleep -- and list on which targets this is definitely the case?
Judging from this and this PR, that would be Windows and Linux. No idea about Android, the BSDs, iOS/watchOS, ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I fixed it for my crate I looked into most platforms: https://github.com/LiveSplit/livesplit-core/blob/092e336e24abd26e97e5a2e55abb0bbd97ff0b44/src/platform/normal/mod.rs#L6
Formatted as Markdown: https://gist.github.com/CryZe/afb052b82839d36d5bdbe4e88551f4dc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay so it seems like after this PR it's pretty much "everything except macOS"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fuchsia is also problematic as they specifically defined their monotonic to behave like Linux's... but they didn't provide an alternative BOOTTIME one yet. Also the PR only checks for "linux" specifically and not Linux derivatives such as Android and l4re (not sure 100% on l4re, at least libc usually bundles it into the Linux-like #[cfg]s), which it probably should (just not emscripten as it errors out on BOOTTIME atm).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, doesn't look like this actually closes #87906 quite yet then.
// This is the equivalent to `CLOCK_UPTIME_RAW` in the macos section | ||
// We support it, because std relies on it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// This is the equivalent to `CLOCK_UPTIME_RAW` in the macos section | |
// We support it, because std relies on it | |
// Unlike `CLOCK_MONOTONIC` (which is weird on Linux in that it does not increment | |
// during system sleep), this *is* supposed to increment during system sleep... | |
// but that's not really something a program running inside Miri can tell, anyway. | |
// We support it because std relies on it. |
This issue was discussed again in the libs meeting last week. There is currently no consensus for switching to CLOCK_BOOTTIME. One of the points that was brought up is that many Linux APIs like futex(), futex_waitv(), and pthread_cond_t only support CLOCK_REALTIME and CLOCK_MONOTONIC. In general, it seems that CLOCK_MONOTONIC is the 'default' monotonic clock on Linux in many situations, unlike CLOCK_BOOTTIME. It seems best for std's Instant to just use whatever is the 'standard' monotonic clock on each platform. What was also mentioned is that without providing additional guarantees that hold across all platforms, switching just one platform doesn't seem that useful; users still wouldn't be able to rely on the exact behaviour. |
So I'm gonna close this. |
There was a discussion on #87907 that all platforms expect
linux advance its monotonic timer if the system goes into a sleep state
(e.g. suspend or hibernate).
It was decided that CLOCK_BOOTTIME should be used on inux targets, but
because that constant would break older systems (e.g. linux kernels
<2.6.39) there should be a fallback to CLOCK_MONOTONIC.
Related to #87907
Closes #87906
cc @joshtriplett @cuviper