92613a25fc
make `Instant::{duration_since, elapsed, sub}` saturating and remove workarounds This removes all mutex/atomic-based workarounds for non-monotonic clocks and makes the previously panicking methods saturating instead. Additionally `saturating_duration_since` becomes deprecated since `duration_since` now fills that role. Effectively this moves the fixup from `Instant` construction to the comparisons. This has some observable effects, especially on platforms without monotonic clocks: * Incorrectly ordered Instant comparisons no longer panic in release mode. This could hide some programming errors, but since debug mode still panics tests can still catch them. * `checked_duration_since` will now return `None` in more cases. Previously it only happened when one compared instants obtained in the wrong order or manually created ones. Now it also does on backslides. * non-monotonic intervals will not be transitive, i.e. `b.duration_since(a) + c.duration_since(b) != c.duration_since(a)` The upsides are reduced complexity and lower overhead of `Instant::now`. ## Motivation Currently we must choose between two poisons. One is high worst-case latency and jitter of `Instant::now()` due to explicit synchronization; see #83093 for benchmarks, the worst-case overhead is > 100x. The other is sporadic panics on specific, rare combinations of CPU/hypervisor/operating system due to platform bugs. Use-cases where low-overhead, fine-grained timestamps are needed - such as syscall tracing, performance profiles or sensor data acquisition (drone flight controllers were mentioned in a libs meeting) in multi-threaded programs - are negatively impacted by the synchronization. The panics are user-visible (program crashes), hard to reproduce and can be triggered by any dependency that might be using Instants for any reason. A solution that is fast _and_ doesn't panic is desirable. ---- closes #84448 closes #86470 |
||
---|---|---|
.. | ||
benches | ||
primitive_docs | ||
src | ||
tests | ||
build.rs | ||
Cargo.toml |