Skip to content

Initial implementation of Stopwatch - #161817

Open
ChrisDenton wants to merge 1 commit into
rust-lang:mainfrom
ChrisDenton:stopwatch
Open

Initial implementation of Stopwatch#161817
ChrisDenton wants to merge 1 commit into
rust-lang:mainfrom
ChrisDenton:stopwatch

Conversation

@ChrisDenton

@ChrisDenton ChrisDenton commented Aug 26, 2026

Copy link
Copy Markdown
Member

For most platforms this currently delegates to Instant but they could drift apart later. For Linux I considered CLOCK_MONOTONIC_RAW but I wasn't fully convinced it was the right thing to do since adjustments do make CLOCK_MONOTONIC more accurate (and apparently there's a bug in older kernels that make calls to CLOCK_MONOTONIC_RAW slower). Windows currently uses QueryPerformanceCounter for both Instant and Stopwatch but without the need to convert to a duration as soon as getting the counter. It is expected for Instant to change in the future to use the same clock as timeouts, etc.

Tracking issue: #161809

r? joboet

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 26, 2026
@rustbot rustbot added the T-libs Relevant to the library team, which will review and decide on the PR/issue. label Aug 26, 2026
@ChrisDenton
ChrisDenton force-pushed the stopwatch branch 2 times, most recently from f1788d9 to 8c3406c Compare August 26, 2026 14:54
@ChrisDenton

ChrisDenton commented Aug 26, 2026

Copy link
Copy Markdown
Member Author

Huh, I'm not actually sure about apple. I thought CLOCK_MONOTONIC would resolve to the right thing but it seems like it's not actually the monotonic clock? I'll use mach_absolute_time directly.

Comment thread library/std/src/sys/time/unix.rs Outdated
@ChrisDenton
ChrisDenton force-pushed the stopwatch branch 2 times, most recently from 7983c80 to 2c64ef2 Compare August 26, 2026 16:17
@ChrisDenton

Copy link
Copy Markdown
Member Author

@bors try jobs=aarch64-apple-*

@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Aug 26, 2026
Initial implementation of `Stopwatch`


try-job: aarch64-apple-*
@rust-log-analyzer

This comment has been minimized.

@rust-bors

rust-bors Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 5207e14 (5207e14db106fcd737e2cd60d4dacee9799db329)
Base parent: c241221 (c24122146bb8b9cfd9e5c067e0f736c59f5826a1)

@joboet

joboet commented Aug 26, 2026

Copy link
Copy Markdown
Member

Huh, I'm not actually sure about apple. I thought CLOCK_MONOTONIC would resolve to the right thing but it seems like it's not actually the monotonic clock? I'll use mach_absolute_time directly.

It is monotonic, but it's measured by subtracting the system boot time from gettimeofday and thus only offers microsecond-accuracy. We currently go through CLOCK_UPTIME_RAW instead, which is equivalent to mach_absolute_time, but does all the nanosecond conversion internally. So there's definitely something to be gained by using mach_absolute_time for Stopwatch. There's also mach_continuous_time which measures time during suspend (and backs CLOCK_MONOTONIC_RAW), but I'm not sure whether that's important here...


impl PartialEq for Stopwatch {
fn eq(&self, other: &Self) -> bool {
self.ticks.abs_diff(other.ticks) <= 1

@joboet joboet Aug 27, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This violates transitivity: Stopwatch { ticks: 0 } is equal to Stopwatch { ticks: 1 }, which in turn equals Stopwatch { ticks: 2 }, but Stopwatch { ticks: 0 } is not equal to Stopwatch { ticks: 2 }.

View changes since the review

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. I was trying to simplify it and went too far, ha.

@joboet joboet Aug 27, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd move the Instant-wrapping implementation here instead of duplicating it across all those platforms.

View changes since the review

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. I was anticipating them diverging more once more platform maintainers start poking at it but a common default implementation is useful regardless.

Comment on lines +20 to +30
#[repr(C)]
struct mach_timebase_info {
numer: u32,
denom: u32,
}

unsafe extern "C" {
unsafe fn mach_timebase_info(info: *mut mach_timebase_info) -> libc::kern_return_t;
}
let mut timebase = mach_timebase_info { numer: 0, denom: 0 };
assert_eq!(unsafe { mach_timebase_info(&mut timebase) }, libc::KERN_SUCCESS);

@joboet joboet Aug 27, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic already exists for Instant::into_mach_absolute_time_ceil (it's used for sleep_until), it'd be nice to avoid duplication.

View changes since the review

Comment thread library/std/src/time.rs
/// | SGX | [`insecure_time` usercall]. More information on [timekeeping in SGX] |
/// | UNIX | [clock_gettime] with `CLOCK_MONOTONIC` |
/// | WASI | [clock_gettime] with `CLOCK_MONOTONIC` |
/// | Darwin | [clock_gettime] with `CLOCK_MONOTONIC` |

@joboet joboet Aug 27, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need updating...

View changes since the review

Comment thread library/std/src/time.rs
/// The following system calls are [currently] being used by `now()` to find out
/// the current time:
///
/// | Platform | System call |

@joboet joboet Aug 27, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder whether it'd be easier to only mention the platforms where Stopwatch deviates from Instant.

View changes since the review

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if/when this is stable it'd be good to consulate some of these docs at the module level. But in the meantime I guess it makes sense to keep duplication to a minimum.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, module-level sounds great! I've just noticed a tendency for these tables to fall out of sync with the actual implementation, so keeping duplication to a minimum hopefully helps prevent that.

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants