From ab409f3e4ba9efe7aa4552c2baf33960903fab1c Mon Sep 17 00:00:00 2001 From: japabu Date: Thu, 15 Oct 2026 11:19:25 +0200 Subject: [PATCH] SYS_CLOCK_REALTIME is deleted; its two callers format SYS_CLOCK_EPOCH Both handlers read clock::utc_secs(); SYS_CLOCK_REALTIME only packed it into h:m:s, carrying nothing SYS_CLOCK_EPOCH does not. The syscall, its kernel arm, toyos_abi's clock_realtime and RealTime, and toyos's wrapper go. The compositor's taskbar clock formats clock_epoch() through toyos_wallclock::Civil, the tree's one calendar. wall_clock_now loses its "both answered or neither" assertion, which one syscall makes vacuous, and its realtime= print, which no host test read. No consumer outside the tree: ToyOS's std fork, the fork clones and ~/.cargo/git/checkouts name neither the number nor the function. Closes issues/sys-clock-realtime-is-now-a-format-of-sys-clock-epoch.md; the capability end state's list of machine facts drops the syscall. --- Cargo.lock | 1 + ...time-is-now-a-format-of-sys-clock-epoch.md | 19 --------------- ...-capability-end-state-is-twelve-answers.md | 8 +++---- kernel/src/syscall/dispatch.rs | 9 +------- lib/wallclock/src/lib.rs | 6 ++--- sdk/abi/src/syscall.rs | 23 ++----------------- sdk/toyos/src/system.rs | 9 ++------ system/compositor/Cargo.toml | 1 + system/compositor/src/render.rs | 7 ++++-- .../rust-tests/src/bin/wall_clock_now.rs | 22 +++--------------- tests/toyos.rs | 2 +- 11 files changed, 23 insertions(+), 84 deletions(-) delete mode 100644 issues/sys-clock-realtime-is-now-a-format-of-sys-clock-epoch.md diff --git a/Cargo.lock b/Cargo.lock index 089d64710b4..e76df05401b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -582,6 +582,7 @@ dependencies = [ "toyos-pci-claim", "toyos-virtio", "toyos-virtio-gpu", + "toyos-wallclock", "toyos-window", ] diff --git a/issues/sys-clock-realtime-is-now-a-format-of-sys-clock-epoch.md b/issues/sys-clock-realtime-is-now-a-format-of-sys-clock-epoch.md deleted file mode 100644 index 5c0f42718e3..00000000000 --- a/issues/sys-clock-realtime-is-now-a-format-of-sys-clock-epoch.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -status: open -kind: defect -opened: 2026-09-28 ---- - -# `SYS_CLOCK_REALTIME` is now a format of `SYS_CLOCK_EPOCH`, and retiring it is an ABI discussion - -Since the RTC-keeps-UTC ruling, `SYS_CLOCK_REALTIME`'s handler and -`SYS_CLOCK_EPOCH`'s both read `crate::clock::utc_secs()`; the first packs it -into `h:m:s` (`toyos_abi::syscall::clock_realtime`), which every caller today -could derive from `clock_epoch()` instead, with no information -`SYS_CLOCK_REALTIME` carries that `SYS_CLOCK_EPOCH` does not. - -Exit condition: `SYS_CLOCK_REALTIME`, its kernel handler and `toyos_abi::syscall::clock_realtime` are -deleted, `toyos::system::clock_realtime` and both its callers -(`system/compositor/src/render.rs`, -`tests/guest/rust-tests/src/bin/wall_clock_now.rs`) move to `clock_epoch`, all -in a PR of their own, and this file is deleted in that PR's merge. diff --git a/issues/the-capability-end-state-is-twelve-answers.md b/issues/the-capability-end-state-is-twelve-answers.md index e5f1ee8c69a..d991ea2b13a 100644 --- a/issues/the-capability-end-state-is-twelve-answers.md +++ b/issues/the-capability-end-state-is-twelve-answers.md @@ -146,10 +146,10 @@ table** can still reach: `SYS_STACK_INFO`; - **its own record** — `SYS_GETPID`, `SYS_GET_ENV`, `SYS_ENDOWMENTS`, `SYS_QUERY_MODULES`, `SYS_SCHED_INFO`, `SYS_GETCWD`, `SYS_CHDIR`; -- **machine facts** — `SYS_CLOCK_REALTIME`, `SYS_CLOCK_EPOCH`, - `SYS_CPU_COUNT`, `SYS_RANDOM`, and `SYS_SYSINFO`'s header (total and used - memory, the CPU count, the live-thread count, the uptime and the two CPU-time - accumulators) but not the roster after it; +- **machine facts** — `SYS_CLOCK_EPOCH`, `SYS_CPU_COUNT`, `SYS_RANDOM`, and + `SYS_SYSINFO`'s header (total and used memory, the CPU count, the live-thread + count, the uptime and the two CPU-time accumulators) but not the roster after + it; - **object creation, which confers nothing over anything that exists** — `SYS_PIPE`, `SYS_PORT_CREATE` ("needs no right and grants none — a port with no clients is not authority", `4a98107f^:kernel/src/arch/syscall.rs:1731`), diff --git a/kernel/src/syscall/dispatch.rs b/kernel/src/syscall/dispatch.rs index aa522196a4e..79366d19de8 100644 --- a/kernel/src/syscall/dispatch.rs +++ b/kernel/src/syscall/dispatch.rs @@ -254,15 +254,8 @@ pub(crate) fn syscall_dispatch(num: u64, a1: u64, a2: u64, a3: u64, a4: u64) -> SYS_MARK_TTY => with_object(RawHandle(a1 as u32), Rights::NONE, ops::mark_tty), SYS_THREAD_SPAWN => sys_thread_spawn(a1, a2, a3, a4), SYS_THREAD_JOIN => sys_thread_join(a1), - // Both answer from the boot-time anchor, never the CMOS: NotSupported beats a + // Answers from the boot-time anchor, never the CMOS: NotSupported beats a // 1970-epoch number a caller cannot tell from real time. - SYS_CLOCK_REALTIME => crate::clock::utc_secs().map_or( - SyscallError::NotSupported.to_u64(), - |secs| { - let now = toyos_wallclock::Civil::from_unix_secs(secs); - (now.hour << 16) | (now.min << 8) | now.sec - }, - ), SYS_CLOCK_EPOCH => { crate::clock::utc_secs().unwrap_or(SyscallError::NotSupported.to_u64()) } diff --git a/lib/wallclock/src/lib.rs b/lib/wallclock/src/lib.rs index e2b92d93c42..33fe876339a 100644 --- a/lib/wallclock/src/lib.rs +++ b/lib/wallclock/src/lib.rs @@ -13,9 +13,9 @@ const DAY: u64 = 86_400; /// A wall-clock instant in the fields a human reads. /// /// The one calendar in the tree. The RTC decodes its registers into this, the -/// log's file names come out of it, `SYS_CLOCK_REALTIME` answers out of it and -/// FAT's directory stamps are built from it — so there is one conversion -/// between seconds and dates rather than one per caller. +/// log's file names come out of it, the compositor's clock reads it and FAT's +/// directory stamps are built from it — so there is one conversion between +/// seconds and dates rather than one per caller. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Civil { pub year: u64, diff --git a/sdk/abi/src/syscall.rs b/sdk/abi/src/syscall.rs index 6af98d26441..a5e16ee650a 100644 --- a/sdk/abi/src/syscall.rs +++ b/sdk/abi/src/syscall.rs @@ -22,7 +22,6 @@ pub const SYS_SPAWN: u64 = 25; pub const SYS_MARK_TTY: u64 = 28; pub const SYS_THREAD_SPAWN: u64 = 40; pub const SYS_THREAD_JOIN: u64 = 41; -pub const SYS_CLOCK_REALTIME: u64 = 42; /// A header describing the machine, optionally followed by the roster of every /// live thread in it. See [`sysinfo`]. /// @@ -665,14 +664,6 @@ pub struct PipeEnds { pub write: RawHandle, } -/// Wall-clock time from RTC. -#[derive(Debug, Clone, Copy)] -pub struct RealTime { - pub hours: u8, - pub minutes: u8, - pub seconds: u8, -} - /// File metadata returned by [`fstat`] and [`stat`]. #[repr(C)] #[derive(Clone, Copy, Debug, Default)] @@ -1177,22 +1168,12 @@ pub fn random(buf: &mut [u8]) -> Result<(), SyscallError> { check_unit(syscall(SYS_RANDOM, buf.as_mut_ptr() as u64, buf.len() as u64, 0, 0)) } +/// Seconds since the Unix epoch (1970-01-01 00:00:00 UTC). +/// /// `None` is a machine that never said what time it is — an RTC that is absent, /// wedged, or answering with something that is not a date. It is `None` for the /// whole of such a boot rather than intermittently, because the kernel reads /// the clock once. -pub fn clock_realtime() -> Option { - let raw = check(syscall(SYS_CLOCK_REALTIME, 0, 0, 0, 0)).ok()?; - Some(RealTime { - hours: ((raw >> 16) & 0xFF) as u8, - minutes: ((raw >> 8) & 0xFF) as u8, - seconds: (raw & 0xFF) as u8, - }) -} - -/// Seconds since the Unix epoch (1970-01-01 00:00:00 UTC). -/// -/// `None` on the same machine and for the same reason as [`clock_realtime`]. /// Cheap: the kernel serves it from an anchor it took at boot plus the /// monotonic clock, so this is a syscall and not a device access. pub fn clock_epoch() -> Option { diff --git a/sdk/toyos/src/system.rs b/sdk/toyos/src/system.rs index 50c51a29339..f7783066f0a 100644 --- a/sdk/toyos/src/system.rs +++ b/sdk/toyos/src/system.rs @@ -1,18 +1,13 @@ //! System information and control. -pub use toyos_abi::syscall::RealTime; use toyos_abi::syscall; /// The ABI's, re-exported rather than restated: two spellings of one layout are /// a reader that walks off by a field the day one of them moves. pub use toyos_abi::syscall::{SYSINFO_ENTRY_SIZE, SYSINFO_HEADER_SIZE}; -/// The time of day, or `None` on a machine whose clock never answered. -pub fn clock_realtime() -> Option { - syscall::clock_realtime() -} - -/// Seconds since the Unix epoch, which is UTC, or `None` for the same machine. +/// Seconds since the Unix epoch, which is UTC, or `None` on a machine whose +/// clock never answered. /// /// Cheap: the kernel serves it from an anchor it took at boot plus the /// monotonic clock, so calling it in a loop costs a syscall each and no device diff --git a/system/compositor/Cargo.toml b/system/compositor/Cargo.toml index 3e1a07c41f0..88c3807f050 100644 --- a/system/compositor/Cargo.toml +++ b/system/compositor/Cargo.toml @@ -18,6 +18,7 @@ toyos-manifest = { path = "../../lib/manifest" } toyos-pci-claim = { path = "../../lib/pci-claim" } toyos-virtio = { path = "../../lib/virtio" } toyos-virtio-gpu = { path = "virtio-gpu" } +toyos-wallclock = { path = "../../lib/wallclock" } toyos-window = { path = "../../sdk/window" } [package.metadata.toyos.host] diff --git a/system/compositor/src/render.rs b/system/compositor/src/render.rs index 7047d385ee7..3421ac8f5e1 100644 --- a/system/compositor/src/render.rs +++ b/system/compositor/src/render.rs @@ -287,8 +287,11 @@ fn draw_taskbar( if clip.overlaps(status) { // Dashes and not 00:00 on a machine whose clock never answered: a // reader cannot tell a plausible midnight from a missing clock. - let clock = match toyos::system::clock_realtime() { - Some(time) => format!("{:02}:{:02}", time.hours, time.minutes), + let clock = match toyos::system::clock_epoch() { + Some(secs) => { + let now = toyos_wallclock::Civil::from_unix_secs(secs); + format!("{:02}:{:02}", now.hour, now.min) + } None => String::from("--:--"), }; let text: String = diff --git a/tests/guest/rust-tests/src/bin/wall_clock_now.rs b/tests/guest/rust-tests/src/bin/wall_clock_now.rs index 6343a540b33..05f790687c4 100644 --- a/tests/guest/rust-tests/src/bin/wall_clock_now.rs +++ b/tests/guest/rust-tests/src/bin/wall_clock_now.rs @@ -1,4 +1,4 @@ -//! What the two clock syscalls answer, from inside the machine. +//! What `SYS_CLOCK_EPOCH` answers, from inside the machine. //! //! What it asserts itself is only what holds on *every* machine, because it //! runs on four of them: the shared boot, and the three whose clocks are staged @@ -8,27 +8,11 @@ const CALLS: u32 = 1000; fn main() { - let epoch = toyos::system::clock_epoch(); - let time = toyos::system::clock_realtime(); - - // The two come from one anchor the kernel took at boot, so a machine that - // has one and not the other has a kernel bug rather than a broken clock. - // True on every machine this runs on, which is what makes it worth - // asserting here rather than on the host. - assert_eq!( - epoch.is_some(), - time.is_some(), - "one clock syscall answered and the other did not: epoch={epoch:?} time={time:?}" - ); - - let (Some(epoch), Some(time)) = (epoch, time) else { + let Some(epoch) = toyos::system::clock_epoch() else { println!("wall-clock: no epoch"); return; }; - println!( - "wall-clock: epoch={epoch} realtime={:02}:{:02}:{:02}", - time.hours, time.minutes, time.seconds - ); + println!("wall-clock: epoch={epoch}"); // What `std` makes of the same clock. The host puts this print against the // instant it staged in the RTC, which is the one reading from outside. diff --git a/tests/toyos.rs b/tests/toyos.rs index d5c1c78e27e..e5a9fffec86 100644 --- a/tests/toyos.rs +++ b/tests/toyos.rs @@ -270,7 +270,7 @@ const DRIVEN_AND_SHARED: &[&str] = &[ // first on each bench, and `crypto_instrument_prints_its_table` before the // instrument under QEMU. "ring_kat", - // Its shared run asserts what holds of the clock syscalls on x86-64; + // Its shared run asserts what holds of `SYS_CLOCK_EPOCH` on x86-64; // `virt_wall_clock_utc` builds it for AArch64 and judges what it read // against the instant the job case stages in the RTC. "wall_clock_now",