From cdb6502632e2c667e3ce29078dae3f714dd8ab3c Mon Sep 17 00:00:00 2001 From: Christopher Serr Date: Mon, 4 Nov 2024 12:27:35 +0100 Subject: [PATCH] Use `CLOCK_BOOTTIME` on Fuchsia (#848) Fuchsia added kernel support for a monotonic clock that keeps running while the system is suspended. They technically have not yet exposed it through their libc, but one maintainer said that they will do so soon. --- Cargo.toml | 4 ++-- src/platform/normal/mod.rs | 27 ++++++++++++--------------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9d36b71e..d9a07b2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -84,7 +84,7 @@ tiny-skia = { version = "0.11.1", default-features = false, features = [ tiny-skia-path = { version = "0.11.1", default-features = false, optional = true } # SVG Rendering -foldhash = { version = "0.1.3", optional = true } +foldhash = { version = "0.1.3", default-features = false, optional = true } # Networking splits-io-api = { version = "0.4.0", optional = true } @@ -117,7 +117,7 @@ windows-sys = { version = "0.59.0", features = [ "Win32_Graphics_Gdi", ], optional = true } -[target.'cfg(any(target_os = "linux", target_os = "l4re", target_os = "android", target_os = "macos", target_os = "ios"))'.dependencies] +[target.'cfg(any(target_os = "linux", target_os = "l4re", target_os = "android", target_os = "fuchsia", target_os = "macos", target_os = "ios"))'.dependencies] # We need libc for our own implementation of Instant libc = { version = "0.2.101", optional = true } diff --git a/src/platform/normal/mod.rs b/src/platform/normal/mod.rs index fe6f2f48..13b2b265 100644 --- a/src/platform/normal/mod.rs +++ b/src/platform/normal/mod.rs @@ -19,8 +19,8 @@ cfg_if::cfg_if! { // correctly implemented in Linux and due to backwards compatibility // concerns they were never able to fix it properly. Thus `CLOCK_MONOTONIC` // means uptime on Linux whereas on other Unixes it means real time (the BSD - // family). So the solution is to use this on all operating systems that are - // based on the Linux kernel. + // family). As a solution the Linux kernel provides `CLOCK_BOOTTIME` to + // measure the real time. // // # macOS and iOS // @@ -36,26 +36,19 @@ cfg_if::cfg_if! { // // # Fuchsia // - // Fuchsia is based on the new Zircon kernel. It has two functions for - // querying the time: + // Fuchsia is based on the new Zircon kernel. It has `zx_clock_get_boot` to + // query the real time and `zx_clock_get_monotonic` to query the uptime. // - // zx_clock_get: - // https://fuchsia.dev/fuchsia-src/reference/syscalls/clock_get - // zx_clock_get_monotonic: - // https://fuchsia.dev/fuchsia-src/reference/syscalls/clock_get_monotonic + // https://fuchsia.dev/reference/syscalls/clock_get_boot // - // `zx_clock_get_monotonic` specifically calls out that it `does not adjust - // during sleep` which seems to mean that it doesn't count the time the OS - // is suspended. This is further evidenced by their libc implementation not - // treating `CLOCK_BOOTTIME` differently and a bug ticket being linked - // there: - // https://cs.opensource.google/fuchsia/fuchsia/+/main:zircon/third_party/ulib/musl/src/time/clock_gettime.c;l=40;drc=35e7a15cb21e16f0705560e5812b7a045d42c8a5 + // They are supposed to be available through `CLOCK_BOOTTIME` and + // `CLOCK_MONOTONIC` respectively, just like on Linux. // // # WASI // // https://github.com/WebAssembly/WASI/blob/5ab83a68d4eb4f218a898ed03b963b7393caaedc/phases/snapshot/docs.md#variant-cases // - // WASI seems to underspecify its `monotonic` a bit, but says that it `is + // WASI seems to under specify its `monotonic` a bit, but says that it `is // defined as a clock measuring real time`, making it sound like a compliant // implementation should measure the time the OS is suspended as well. // @@ -98,10 +91,14 @@ cfg_if::cfg_if! { // the Linux kernel and instead has its own implementation in JavaScript // where it actually errors out on `CLOCK_BOOTTIME`: // https://github.com/emscripten-core/emscripten/blob/9bdb310b89472a0f4d64f36e4a79273d8dc7fa98/system/lib/libc/emscripten_time.c#L50-L57 + // + // And we add Fuchsia to this list as it's based on the Zircon kernel which + // uses `CLOCK_BOOTTIME` in the same way as Linux. if #[cfg(any( target_os = "linux", target_os = "l4re", target_os = "android", + target_os = "fuchsia", ))] { use core::{mem::MaybeUninit, ops::Sub};