rust-lang / rust-lang/libs-team
allow specifying whether `Instant` should be suspend-aware
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 178
- Forks
- 28
- Avg merge
- 15m
- Merged PRs (30d)
- 1
Description
Proposal
Problem statement
Currently, whether Instant counts time during system sleep or hibernation is platform-dependent, but quite a lot of programs need to decide this explicitly.
Motivating examples or use cases
Quite a lot of system and interactive software needs to explicitly decide whether to count time during suspend/hibernate. For instance, an audio player might not want to count suspended time against the audio play time, since nothing was actually played during suspend. An audio streaming solution, on the other hand, needs to be aware of suspend time in order to better track latencies. Similarly, a network server might want to count suspend times against timeout, but a browser might want to freeze animations across a suspend.
Solution sketch
I'd like to propose modifying the API of Instant to take account the clock choice:
// in std::time
struct Instant<C: Clock = ContinuousClock> { .. }
impl Instant<ContinuousClock> {
fn now() -> Instant;
}
impl<C: Clock> Instant<C> {
/* all methods except now */
}
trait Clock: Sealed {
fn now(&self) -> Instant<Self>;
// And potentially:
fn resolution(&self) -> Duration;
fn sleep(&self, duration: Duration);
fn sleep_until(&self, deadline: Instant<Self>);
}
struct ContinuousClock;
impl Clock for ContinuousClock {}
struct SuspendingClock;
impl Clock for SuspendingClock {}
and (perhaps) deprecate Instant::now in favour of ContinuousClock.now()/SuspendingClock.now(). Solving this using generics means that it is impossible to compare times across clocks, which is (in most cases) meaningless anyway.
Drawbacks
This is difficult to implement on Windows. While the QueryInterruptTimePrecise and QueryUnbiasedInterruptTimePrecise display the correct behaviour, they have less precision (up to 100 ns precision) than the QueryPerformanceCounter API (potentially nanosecond precision, although realistically at least 5 ns since RDTSC takes a few cycles itself) currently used for Instant. Also, Windows (AFAIK) doesn't have a suspend-tracking sleep operation.
This switches the current behaviour of Instant on macOS and Linux, where Instant currently doesn't count time during suspend.
Alternatives
- Make
SuspendingClockthe default clock – this preserves the currentInstantbehaviour on Linux and macOS, but changes behaviour on Windows (QueryPerformanceCounteradvances time during sleep). I find that most uses ofInstantare related to timeouts and deadlines – for those, tracking suspend time is a good idea. - Make
nowgeneric and implement it forClock + Default. - Add a new
Instant-like type for the other clock type. - Also add
WalltimeClockand makeSystemTimean alias forInstant<WalltimeClock>. That would result in problems for the time arithmetic functions however, as e.g.SystemTime::duration_sincereturns aResult<Duration, SystemTimeError, but the currentInstant::duration_sinceis infallible.
Links and related work
This is heavily inspired by Swift's clock support, see SE-0329 and the API documentation that resulted from it.
What happens now?
This issue contains an API change proposal (or ACP) and is part of the libs-api team feature lifecycle. Once this issue is filed, the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.
Possible responses
The libs team may respond in various different ways. First, the team will consider the problem (this doesn't require any concrete solution or alternatives to have been proposed):
- We think this problem seems worth solving, and the standard library might be the right place to solve it.
- We think that this probably doesn't belong in the standard library.
Second, if there's a concrete solution:
- We think this specific solution looks roughly right, approved, you or someone else should implement this. (Further review will still happen on the subsequent implementation PR.)
- We're not sure this is the right solution, and the alternatives or other materials don't give us enough information to be sure about that. Here are some questions we have that aren't answered, or rough ideas about alternatives we'd want to see discussed.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the proposed std::time API for Instant, Clock, ContinuousClock, and SuspendingClock, then read the linked feature lifecycle. Compare the Windows, macOS, and Linux clock behavior described in the issue and review the listed alternatives. Done means an agreed libs-api direction or approved design, not an implementation patch.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- backend-api-design, operating-systems
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100