adding clock system call

This commit is contained in:
Daniel Samson
2026-07-11 03:43:33 +01:00
parent 2ab0d129a2
commit e499f500c3
4 changed files with 41 additions and 0 deletions
+10
View File
@@ -27,6 +27,16 @@ pub fn sleep(ms: usize) void {
_ = sc.systemCall1(.sleep, ms);
}
/// Monotonic nanoseconds since boot — a time source for timeouts and short delays. It
/// only ever moves forward. This is *not* wall-clock time (no date, no timezone — that
/// is a user-space service layered on top). Deadline pattern for a bounded poll loop:
///
/// const deadline = clock() + timeout_ns;
/// while (clock() < deadline) { ... }
pub fn clock() u64 {
return @intCast(sc.systemCall0(.clock));
}
/// End the process. Never returns.
pub fn exit(code: usize) noreturn {
_ = sc.systemCall1(.exit, code);
+1
View File
@@ -49,6 +49,7 @@ pub const SystemCall = enum(u64) {
msi_bind = 20, // msi_bind(device_id, endpoint) -> address (rax), data (rdx): a per-device MSI vector for a claimed device
io_read = 21, // io_read(device_id, resource_index, offset, width) -> value: read a port in a claimed device's io_port resource
io_write = 22, // io_write(device_id, resource_index, offset, width, value) -> 0: write a port in a claimed device's io_port resource
clock = 23, // clock() -> nanoseconds since boot: a monotonic time source (for timeouts/delays)
_,
};
+26
View File
@@ -92,6 +92,8 @@ pub fn run(case: []const u8, boot_information: *const BootInformation) void {
iommuTest();
} else if (eql(case, "ioport")) {
ioPortTest();
} else if (eql(case, "clock")) {
clockTest();
} else if (eql(case, "smp")) {
smpTest();
} else if (eql(case, "affinity")) {
@@ -1100,6 +1102,30 @@ fn ioPortTest() void {
result();
}
/// The monotonic clock (the source `clock()` surfaces to user space). It must be
/// calibrated, move forward over a spin, and never run backwards — the guarantees a
/// driver's deadline timeout depends on. The syscall is a thin wrapper over this same
/// `architecture.nanos()`.
fn clockTest() void {
log("DANOS-TEST-BEGIN: clock\n", .{});
const t0 = architecture.nanos();
check("monotonic clock is calibrated (nonzero)", t0 != 0);
var last = t0;
var monotonic = true;
var advanced = false;
var i: u32 = 0;
while (i < 1_000_000) : (i += 1) {
const t = architecture.nanos();
if (t < last) monotonic = false;
if (t > t0) advanced = true;
last = t;
}
check("clock advanced over the spin", advanced);
check("clock never ran backwards (monotonic)", monotonic);
result();
}
var proc_worker_run: bool = true;
var proc_worker_ran: bool = false;
+4
View File
@@ -151,6 +151,10 @@ CASES = [
{"name": "ioport",
"expect": r"DANOS-TEST-RESULT: PASS",
"fail": r"DANOS-TEST-RESULT: FAIL"},
# Monotonic clock (clock() syscall source): calibrated, advancing, never backwards.
{"name": "clock",
"expect": r"DANOS-TEST-RESULT: PASS",
"fail": r"DANOS-TEST-RESULT: FAIL"},
# Parallelism: needs more than one core, so this case boots with -smp 4.
{"name": "smp",
"smp": 4,