adding clock system call
This commit is contained in:
@@ -27,6 +27,16 @@ pub fn sleep(ms: usize) void {
|
|||||||
_ = sc.systemCall1(.sleep, ms);
|
_ = 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.
|
/// End the process. Never returns.
|
||||||
pub fn exit(code: usize) noreturn {
|
pub fn exit(code: usize) noreturn {
|
||||||
_ = sc.systemCall1(.exit, code);
|
_ = sc.systemCall1(.exit, code);
|
||||||
|
|||||||
@@ -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
|
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_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
|
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)
|
||||||
_,
|
_,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -92,6 +92,8 @@ pub fn run(case: []const u8, boot_information: *const BootInformation) void {
|
|||||||
iommuTest();
|
iommuTest();
|
||||||
} else if (eql(case, "ioport")) {
|
} else if (eql(case, "ioport")) {
|
||||||
ioPortTest();
|
ioPortTest();
|
||||||
|
} else if (eql(case, "clock")) {
|
||||||
|
clockTest();
|
||||||
} else if (eql(case, "smp")) {
|
} else if (eql(case, "smp")) {
|
||||||
smpTest();
|
smpTest();
|
||||||
} else if (eql(case, "affinity")) {
|
} else if (eql(case, "affinity")) {
|
||||||
@@ -1100,6 +1102,30 @@ fn ioPortTest() void {
|
|||||||
result();
|
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_run: bool = true;
|
||||||
var proc_worker_ran: bool = false;
|
var proc_worker_ran: bool = false;
|
||||||
|
|
||||||
|
|||||||
@@ -151,6 +151,10 @@ CASES = [
|
|||||||
{"name": "ioport",
|
{"name": "ioport",
|
||||||
"expect": r"DANOS-TEST-RESULT: PASS",
|
"expect": r"DANOS-TEST-RESULT: PASS",
|
||||||
"fail": r"DANOS-TEST-RESULT: FAIL"},
|
"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.
|
# Parallelism: needs more than one core, so this case boots with -smp 4.
|
||||||
{"name": "smp",
|
{"name": "smp",
|
||||||
"smp": 4,
|
"smp": 4,
|
||||||
|
|||||||
Reference in New Issue
Block a user