Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 0 additions & 19 deletions issues/sys-clock-realtime-is-now-a-format-of-sys-clock-epoch.md

This file was deleted.

8 changes: 4 additions & 4 deletions issues/the-capability-end-state-is-twelve-answers.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`),
Expand Down
9 changes: 1 addition & 8 deletions kernel/src/syscall/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
Expand Down
6 changes: 3 additions & 3 deletions lib/wallclock/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
23 changes: 2 additions & 21 deletions sdk/abi/src/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`].
///
Expand Down Expand Up @@ -660,14 +659,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)]
Expand Down Expand Up @@ -1172,22 +1163,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<RealTime> {
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<u64> {
Expand Down
9 changes: 2 additions & 7 deletions sdk/toyos/src/system.rs
Original file line number Diff line number Diff line change
@@ -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<RealTime> {
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
Expand Down
1 change: 1 addition & 0 deletions system/compositor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
7 changes: 5 additions & 2 deletions system/compositor/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
22 changes: 3 additions & 19 deletions tests/guest/rust-tests/src/bin/wall_clock_now.rs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion tests/toyos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down