diff --git a/src/ex/work.zig b/src/ex/work.zig index 94b04f9..d13fcc4 100644 --- a/src/ex/work.zig +++ b/src/ex/work.zig @@ -197,7 +197,7 @@ fn work_loop(p: ?*anyopaque) void { const dynamic = ctx.get_tag() == 1; while (true) { - const timeout: ?r.Nanoseconds = if (dynamic) std.time.ns_per_s * 5 else null; + const timeout: ?r.Nanoseconds = if (dynamic) .from(r.Seconds.init(5)) else null; const item = ctx.get_ptr().queue.remove(timeout) catch { _ = ctx.get_ptr().total_threads.fetchSub(1, .monotonic); diff --git a/src/kern/dpc.zig b/src/kern/dpc.zig index 0d78022..c9a07fe 100644 --- a/src/kern/dpc.zig +++ b/src/kern/dpc.zig @@ -113,7 +113,7 @@ fn dispatch_queue(cpu: u32) void { if (sched_cpu.start_timer) { ke.timer.set( &sched_cpu.resched_timer, - std.time.ns_per_ms * config.sched_timeslice, + .from(r.Milliseconds.init(config.sched_timeslice)), .{ .dpc = &sched_cpu.resched_dpc }, ); } @@ -123,7 +123,7 @@ fn dispatch_queue(cpu: u32) void { ke.timer.cancel(&sched_cpu.resched_timer); ke.timer.set( &sched_cpu.resched_timer, - std.time.ns_per_ms * config.sched_timeslice, + .from(r.Milliseconds.init(config.sched_timeslice)), .{ .dpc = &sched_cpu.resched_dpc }, ); } diff --git a/src/kern/init.zig b/src/kern/init.zig index 772238a..6968bc9 100644 --- a/src/kern/init.zig +++ b/src/kern/init.zig @@ -20,7 +20,13 @@ pub fn init(boot_info: *r.BootInfo) linksection(r.init) void { ki.cpu.init_cpu(0); ki.turnstile.init_turnstiles(); - thread0.init(@intFromPtr(&stack), r.kib(16), ke.Thread.Priority.idle_low, ki.sched.idle, null); + thread0.init( + @intFromPtr(&stack), + r.kib(16), + ke.Thread.Priority.idle_low, + ki.sched.idle, + null, + ); thread0.priority = 0; thread0.base_priority = 0; thread0.pinned = true; diff --git a/src/kern/log.zig b/src/kern/log.zig index acd99f4..4e5e395 100644 --- a/src/kern/log.zig +++ b/src/kern/log.zig @@ -89,6 +89,12 @@ pub fn log( const ipl = out_lock.acquire_at(.High); defer out_lock.release(ipl); - writer.interface.print("[{:>5}.{:06}] ", .{ res.info.timestamp / std.time.ns_per_s, (res.info.timestamp % std.time.ns_per_s) / std.time.ns_per_us }) catch return; + writer.interface.print( + "[{:>5}.{:06}] ", + .{ + res.info.timestamp.value / std.time.ns_per_s, + (res.info.timestamp.value % std.time.ns_per_s) / std.time.ns_per_us, + }, + ) catch return; _ = writer.interface.writeAll(res.buf[0..res.info.length]) catch return; } diff --git a/src/kern/log_ring.zig b/src/kern/log_ring.zig index 49e1589..3dabe39 100644 --- a/src/kern/log_ring.zig +++ b/src/kern/log_ring.zig @@ -92,7 +92,7 @@ const Desc = struct { pub const Info = struct { sequence: u64, - timestamp: u64, + timestamp: r.Nanoseconds, length: u16, }; diff --git a/src/kern/sched.zig b/src/kern/sched.zig index caeb404..5d33f72 100644 --- a/src/kern/sched.zig +++ b/src/kern/sched.zig @@ -215,7 +215,7 @@ pub const Average = struct { // Amount of the period that has been accounted for period_contrib: usize, /// Timestamp (us) up to which history has been accounted. - last_update: u64, + last_update: r.Microseconds, }; pub const percpu = ke.CpuLocal(PerCpu, undefined); @@ -242,8 +242,8 @@ fn pelt_do_decay(val: u64, n: u64) u64 { } fn pelt_update(avg: *Average, runnable: bool) void { - const now = ke.time.read_time() / std.time.ns_per_us; - const new_delta = now - avg.last_update; + const now = ke.time.read_time().to(r.Microseconds); + const new_delta = now.value - avg.last_update.value; if (new_delta == 0) return; @@ -318,8 +318,8 @@ fn pelt_update_td(td: *ke.Thread, cpu: ?*PerCpu, runnable: bool) void { fn attach_load_avg(cpu: *PerCpu, td: *ke.Thread) void { if (!tracks_load_avg(td)) return; - if (td.avg.last_update == 0) { - td.avg.last_update = ke.time.read_time() / std.time.ns_per_us; + if (td.avg.last_update.value == 0) { + td.avg.last_update = ke.time.read_time().to(r.Microseconds); } else { pelt_update_td(td, null, false); } @@ -470,7 +470,7 @@ pub fn block() void { /// Block the currently running thread with its lock held. pub fn block_locked(curtd: *ke.Thread) void { curtd.state.store(.Blocked, .monotonic); - curtd.sleep_start = ke.time.read_time(); + curtd.sleep_start = ke.time.read_time().value; curtd.runq = null; detach_load_avg(percpu.local(), curtd); @@ -537,7 +537,7 @@ pub fn unblock_locked(td: *ke.Thread) void { std.debug.assert(td.lock.is_locked()); std.debug.assert(td.state.load(.monotonic) == .Blocked); - const delta = (ke.time.read_time() - td.sleep_start) / std.time.ns_per_ms; + const delta = (ke.time.read_time().value - td.sleep_start) / std.time.ns_per_ms; td.sleep_time += delta; @@ -685,7 +685,7 @@ pub fn late_init() linksection(r.init) void { balance_timer.init(); ke.timer.set( &balance_timer, - balance_interval * std.time.ns_per_ms, + .from(r.Milliseconds.init(balance_interval)), .{ .dpc = &balance_dpc }, ); } @@ -1136,7 +1136,7 @@ fn pick_cpu(td: *ke.Thread) u32 { var ran_recently = true; if (td.sleep_start != 0) { - const delta = ke.time.read_time() - td.sleep_start; + const delta = ke.time.read_time().value - td.sleep_start; // If we haven't been on this CPU in the last second, don't bother. if (delta > std.time.ns_per_s) { @@ -1455,5 +1455,5 @@ fn balance(_: *ke.Dpc, _: ?*anyopaque) void { const offset = lcg.next() % balance_interval; const ms = (balance_interval) + offset; - ke.timer.set(&balance_timer, ms * std.time.ns_per_ms, .{ .dpc = &balance_dpc }); + ke.timer.set(&balance_timer, .from(r.Milliseconds.init(ms)), .{ .dpc = &balance_dpc }); } diff --git a/src/kern/thread.zig b/src/kern/thread.zig index 6d06752..a931457 100644 --- a/src/kern/thread.zig +++ b/src/kern/thread.zig @@ -159,7 +159,7 @@ pub const Thread = struct { .stack = stack, .switching = .init(false), .avg = .{ - .last_update = 0, + .last_update = .init(0), // New threads are considered heavy until they prove themselves, // this might allow for better balancing during bursts. .load = ki.sched.pelt_load_avg_max, diff --git a/src/kern/time.zig b/src/kern/time.zig index e2449a3..55b7f84 100644 --- a/src/kern/time.zig +++ b/src/kern/time.zig @@ -89,12 +89,12 @@ pub fn register_source(tc: *TimeCounter) void { /// Return the time elapsed since boot in nanoseconds. pub fn read_time() r.Nanoseconds { - const tc = best_tc orelse return 0; + const tc = best_tc orelse return .init(0); const s = state.load(); const curr_count = tc.read_count() & tc.mask; const elapsed = (curr_count - s.initial_count) & tc.mask; - return s.offset + ticks_to_ns(tc, elapsed); + return .init(s.offset + ticks_to_ns(tc, elapsed)); } /// Return the best TimeCounter. @@ -109,14 +109,14 @@ pub fn sleep(ns: r.Nanoseconds) void { while (true) { var cur = read_time(); - if (cur < start) continue; + if (cur.value < start.value) continue; - if (cur - start >= ns) { + if (cur.value - start.value >= ns.value) { cur = read_time(); // Check again as we may have overflowed and read a bogus value.. // This is kinda hacky but oh well. - if (cur - start >= ns) { + if (cur.value - start.value >= ns.value) { break; } } diff --git a/src/kern/timer.zig b/src/kern/timer.zig index 1ce759a..bda5392 100644 --- a/src/kern/timer.zig +++ b/src/kern/timer.zig @@ -42,7 +42,7 @@ pub const Timer = struct { self.* = .{ .hdr = undefined, .state = .init(.Stopped), - .deadline = 0, + .deadline = .init(0), .dpc = null, .node = .{}, .cpu = null, @@ -79,7 +79,7 @@ pub fn set(timer: *Timer, time: r.Nanoseconds, opts: Options) void { defer cpu.lock.release_no_ipl(); // Initialize the timer. - timer.deadline = ke.time.read_time() + time; + timer.deadline = .init(ke.time.read_time().value + time.value); timer.cpu = cpu; timer.dpc = opts.dpc; @@ -130,7 +130,7 @@ pub fn cmp_timer(a: *rtl.pairing_heap.Node, b_: *rtl.pairing_heap.Node) std.math const timer_a: *Timer = @fieldParentPtr("node", a); const timer_b: *Timer = @fieldParentPtr("node", b_); - return std.math.order(timer_a.deadline, timer_b.deadline); + return std.math.order(timer_a.deadline.value, timer_b.deadline.value); } /// Called by the platform on a clock interrupt. @@ -161,18 +161,18 @@ fn handle_expiry(_: *ke.Dpc, _: ?*anyopaque) void { // If the timer expires more than 1ms in the future, consider it not yet due. // Sub-millisecond differences are close enough to expire immediately. - if (timer.deadline > curtime and timer.deadline - curtime > std.time.ns_per_ms) { + if (timer.deadline.value > curtime.value and timer.deadline.value - curtime.value > std.time.ns_per_ms) { const next = timer; cpu.lock.release_no_ipl(); // Re-check in case the timer expired while we were here. const now = ke.time.read_time(); - if (next.deadline <= now or next.deadline - now <= std.time.ns_per_ms) { + if (next.deadline.value <= now.value or next.deadline.value - now.value <= std.time.ns_per_ms) { continue; // expired in the meantime, loop again } - std.debug.assert(next.deadline > now); - pl.arm_timer(next.deadline - now); + std.debug.assert(next.deadline.value > now.value); + pl.arm_timer(.init(next.deadline.value - now.value)); return; } diff --git a/src/kern/wait.zig b/src/kern/wait.zig index 9089b6a..4819930 100644 --- a/src/kern/wait.zig +++ b/src/kern/wait.zig @@ -166,7 +166,7 @@ pub fn wait_any(objects: []*DispatchHeader, reason: []const u8, opts: Options) ! } // Wait was already satisfied, back out. - if (satisfier != null or (has_timeout and opts.timeout.? == 0)) { + if (satisfier != null or (has_timeout and opts.timeout.?.value == 0)) { if (satisfier != null) { std.debug.assert(curtd.wait_status.load(.acquire) == .Satisfied); } diff --git a/src/mm/zone.zig b/src/mm/zone.zig index 7d1582c..dacd4d5 100644 --- a/src/mm/zone.zig +++ b/src/mm/zone.zig @@ -118,7 +118,7 @@ const mi = mm.private; /// Interval at which we do housekeeping (working set update, reaping, etc.) const update_interval_s = 15; -const update_interval = std.time.ns_per_s * update_interval_s; +const update_interval: r.Nanoseconds = .from(r.Seconds.init(update_interval_s)); var update_work_item: ex.DelayedWorkItem = undefined; /// Fixed point conversion for WMA computation. @@ -134,7 +134,7 @@ const zones_num = 32; const magazine_size = ke.Tunable(u8, 8, "mm.zone.mag_size"); /// How much extra memory CPUs are allowed to keep around. -const max_local_memory = ke.Tunable(u32, r.kib(128), "mm.zone.max_local_mem"); +const max_local_memory = ke.Tunable(u32, @intCast(r.kib(128)), "mm.zone.max_local_mem"); /// Number of contentions allowed per second before the depot grows. const depot_grow_level = ke.Tunable(u32, 5 * wma_unit, "mm.zone.depot_grow_level"); @@ -146,7 +146,7 @@ const depot_shrink_level = ke.Tunable(u32, wma_unit / 2, "mm.zone.depot_shrink_l const excess_magazines = ke.Tunable(u32, 8, "mm.zone.excess_mags"); /// Excess memory in a zone before magazines are trimmed. -const excess_memory = ke.Tunable(u32, r.kib(16), "mm.zone.excess_mem"); +const excess_memory = ke.Tunable(u32, @intCast(r.kib(16)), "mm.zone.excess_mem"); /// Every power-of-two-size from 8 to 2048 (inclusively). const generic_zones_num = 9; diff --git a/src/platform/pc/apic.zig b/src/platform/pc/apic.zig index 0ba1832..ae02c9a 100644 --- a/src/platform/pc/apic.zig +++ b/src/platform/pc/apic.zig @@ -161,7 +161,7 @@ fn lapic_calibrate(ms: u64) u64 { write(.LvtTimer, (1 << 16)); write(.TimerInitialCount, std.math.maxInt(u32)); - ke.time.sleep(std.time.ns_per_ms * ms); + ke.time.sleep(.from(r.Milliseconds.init(ms))); const ticks = std.math.maxInt(u32) - read(.TimerCurrentCount); @@ -200,7 +200,7 @@ pub fn arm_timer(ns: r.Nanoseconds) void { if (amd64.cpu_features.tsc_deadline) { const now = amd64.rdtsc(); - const delta: u64 = @intCast((@as(u128, ns) * tsc.tsc_timer.frequency) / std.time.ns_per_s); + const delta: u64 = @intCast((@as(u128, ns.value) * tsc.tsc_timer.frequency) / std.time.ns_per_s); const deadline = now +% delta; @@ -212,7 +212,7 @@ pub fn arm_timer(ns: r.Nanoseconds) void { write(.LvtTimer, 1 << 16); write(.TimerInitialCount, 0); - const us = ns / std.time.ns_per_us; + const us = ns.to(r.Microseconds).value; const ticks: u32 = @truncate(@max(us * timer_ticks_per_us.local().*, 1)); // Setup IRQ. diff --git a/src/platform/pc/smp.zig b/src/platform/pc/smp.zig index e9c968f..30ccb0c 100644 --- a/src/platform/pc/smp.zig +++ b/src/platform/pc/smp.zig @@ -65,8 +65,8 @@ pub fn init() linksection(r.init) void { .Unknown => false, }; - const init_delay: usize = if (skip_delay) 0 else std.time.ns_per_ms * 10; - const sipi_delay: usize = if (skip_delay) std.time.ns_per_us * 10 else std.time.ns_per_us * 300; + const init_delay: r.Nanoseconds = .init(if (skip_delay) 0 else std.time.ns_per_ms * 10); + const sipi_delay: r.Nanoseconds = .init(if (skip_delay) std.time.ns_per_us * 10 else std.time.ns_per_us * 300); const page: [*]u8 = @ptrFromInt(mm.p2v(0x8000)); @memcpy(page[0..trampoline_size], @as([*]u8, @ptrFromInt(trampoline_start))); diff --git a/src/platform/pc/tsc.zig b/src/platform/pc/tsc.zig index 881d1b3..2953881 100644 --- a/src/platform/pc/tsc.zig +++ b/src/platform/pc/tsc.zig @@ -46,7 +46,7 @@ pub fn init() linksection(r.init) void { // Calculate how many ticks it costs to call tc_sleep. for (0..calib_cost_runs) |_| { const start = amd64.rdtsc(); - ke.time.sleep(0); + ke.time.sleep(.init(0)); const end = amd64.rdtsc(); calib_cost += (end - start); } @@ -61,7 +61,7 @@ pub fn init() linksection(r.init) void { for (0..runs) |i| { const start = amd64.rdtsc(); - ke.time.sleep(calib_time); + ke.time.sleep(.init(calib_time)); const end = amd64.rdtsc(); freqs[i] = (end - start - calib_cost) * (std.time.ns_per_s / calib_time); } diff --git a/src/platform/root.zig b/src/platform/root.zig index 224647f..fef43d9 100644 --- a/src/platform/root.zig +++ b/src/platform/root.zig @@ -33,7 +33,7 @@ pub inline fn debug_read() u8 { } /// Arm a one-shot timer to fire in `ns` nanoseconds. -pub inline fn arm_timer(ns: u64) void { +pub inline fn arm_timer(ns: r.Nanoseconds) void { return impl.arm_timer(ns); } diff --git a/src/root.zig b/src/root.zig index f8c02a1..a0268dd 100644 --- a/src/root.zig +++ b/src/root.zig @@ -21,13 +21,24 @@ pub const percpu = ".data.percpu"; pub const VAddr = usize; pub const PAddr = usize; -pub const Nanoseconds = u64; +pub const Nanoseconds = rtl.units.Nanoseconds; +pub const Microseconds = rtl.units.Microseconds; +pub const Milliseconds = rtl.units.Milliseconds; +pub const Seconds = rtl.units.Seconds; pub var kernel_heap_base: usize = 0; pub var kernel_pfndb_base: usize = 0; pub var boot_info: *BootInfo = undefined; +pub inline fn mmio_read(comptime T: type, addr: usize) T { + return @as(*volatile T, @ptrFromInt(addr)).*; +} + +pub inline fn mmio_write(comptime T: type, addr: usize, value: T) void { + @as(*volatile T, @ptrFromInt(addr)).* = value; +} + /// Return N kibibytes in bytes. pub fn kib(comptime N: u32) usize { return N * 1024; @@ -48,14 +59,6 @@ pub fn tib(comptime N: u32) usize { return gib(N) * 1024; } -pub inline fn mmio_read(comptime T: type, addr: usize) T { - return @as(*volatile T, @ptrFromInt(addr)).*; -} - -pub inline fn mmio_write(comptime T: type, addr: usize, value: T) void { - @as(*volatile T, @ptrFromInt(addr)).* = value; -} - pub const std_options = std.Options{ .logFn = ke.log.log, }; diff --git a/src/rtl/root.zig b/src/rtl/root.zig index 30385e2..0071f99 100644 --- a/src/rtl/root.zig +++ b/src/rtl/root.zig @@ -1,5 +1,6 @@ const std = @import("std"); +pub const units = @import("units.zig"); pub const List = @import("list.zig").List; pub const SeqLock = @import("seqlock.zig").SeqLock; pub const barrier = @import("barrier.zig"); diff --git a/src/rtl/units.zig b/src/rtl/units.zig new file mode 100644 index 0000000..9f19e7a --- /dev/null +++ b/src/rtl/units.zig @@ -0,0 +1,60 @@ +/// Type-safe measurement units. +const std = @import("std"); + +const Dimension = enum { Time }; + +fn scale_value(comptime from_scale: u64, comptime to_scale: u64, value: u64) u64 { + if (comptime from_scale >= to_scale) { + return value * comptime (from_scale / to_scale); + } else { + return value / comptime (to_scale / from_scale); + } +} + +pub fn Unit( + comptime dim: Dimension, + comptime scale: u64, + comptime unit_suffix: []const u8, +) type { + return struct { + const Self = @This(); + pub const dimension = dim; + pub const base_per_unit = scale; + + value: u64, + + fn check(comptime T: type) void { + comptime { + if (!(@typeInfo(T) == .@"struct" and @hasDecl(T, "dimension"))) + @compileError(@typeName(T) ++ " is not a unit"); + if (T.dimension != dim) + @compileError("cannot convert between " ++ @tagName(T.dimension) ++ + " and " ++ @tagName(dim)); + } + } + + pub fn init(value: u64) Self { + return .{ .value = value }; + } + + pub fn to(self: Self, comptime T: type) T { + check(T); + return T.init(scale_value(scale, T.base_per_unit, self.value)); + } + + pub fn from(other: anytype) Self { + const From = @TypeOf(other); + check(From); + return Self.init(scale_value(From.base_per_unit, scale, other.value)); + } + + pub inline fn format(self: Self, writer: *std.Io.Writer) !void { + try writer.print("{} {s}", .{ self.value, unit_suffix }); + } + }; +} + +pub const Nanoseconds = Unit(.Time, 1, "ns"); +pub const Microseconds = Unit(.Time, std.time.ns_per_us, "us"); +pub const Milliseconds = Unit(.Time, std.time.ns_per_ms, "ms"); +pub const Seconds = Unit(.Time, std.time.ns_per_s, "s"); diff --git a/src/tests/fireworks.zig b/src/tests/fireworks.zig index 075fe97..a086eef 100644 --- a/src/tests/fireworks.zig +++ b/src/tests/fireworks.zig @@ -32,7 +32,7 @@ fn plot_pixel(x: i64, y: i64, color: u32) void { } fn rand_tsc_based() u32 { - const tsc = ke.time.read_time(); + const tsc = ke.time.read_time().value; const lo: u32 = @truncate(tsc); const hi: u32 = @truncate(tsc >> 32); return lo ^ hi; @@ -100,7 +100,7 @@ fn get_random_color() u32 { fn perform_delay(ms: usize) void { var timer: ke.Timer = undefined; timer.init(); - ke.timer.set(&timer, std.time.ns_per_ms * ms, .{}); + ke.timer.set(&timer, .init(std.time.ns_per_ms * ms), .{}); _ = ke.wait.wait_one(&timer.hdr, "sleep", .{}) catch unreachable; } diff --git a/src/tests/mutex.zig b/src/tests/mutex.zig index 16f2a1b..a976610 100644 --- a/src/tests/mutex.zig +++ b/src/tests/mutex.zig @@ -34,13 +34,13 @@ fn rand(state: *u64) u64 { fn delay_ms(ms: usize) void { var timer: ke.Timer = undefined; timer.init(); - ke.timer.set(&timer, std.time.ns_per_ms * ms, .{}); + ke.timer.set(&timer, .init(std.time.ns_per_ms * ms), .{}); _ = ke.wait.wait_one(&timer.hdr, "sleep", .{}) catch unreachable; } fn worker(param: ?*anyopaque) void { const id = @intFromPtr(param.?) - 1; - var seed = (ke.time.read_time() ^ (id *% 0x9e3779b97f4a7c15)) | 1; + var seed = (ke.time.read_time().value ^ (id *% 0x9e3779b97f4a7c15)) | 1; var iter: u64 = 0; while (true) : (iter += 1) { diff --git a/src/tests/smr.zig b/src/tests/smr.zig index fb2b413..d579a38 100644 --- a/src/tests/smr.zig +++ b/src/tests/smr.zig @@ -35,13 +35,13 @@ fn rand(state: *u64) u64 { } fn seed_from(param: ?*anyopaque) u64 { - return (ke.time.read_time() ^ (@intFromPtr(param.?) *% 0x9e3779b97f4a7c15)) | 1; + return (ke.time.read_time().value ^ (@intFromPtr(param.?) *% 0x9e3779b97f4a7c15)) | 1; } fn delay_ms(ms: usize) void { var timer: ke.Timer = undefined; timer.init(); - ke.timer.set(&timer, std.time.ns_per_ms * ms, .{}); + ke.timer.set(&timer, .init(std.time.ns_per_ms * ms), .{}); _ = ke.wait.wait_one(&timer.hdr, "sleep", .{}) catch unreachable; } diff --git a/src/tests/smr_pi.zig b/src/tests/smr_pi.zig index 98ef543..e85d84a 100644 --- a/src/tests/smr_pi.zig +++ b/src/tests/smr_pi.zig @@ -57,13 +57,13 @@ fn rand(state: *u64) u64 { } fn seed_from(param: ?*anyopaque) u64 { - return (ke.time.read_time() ^ (@intFromPtr(param.?) *% 0x9e3779b97f4a7c15)) | 1; + return (ke.time.read_time().value ^ (@intFromPtr(param.?) *% 0x9e3779b97f4a7c15)) | 1; } fn delay_ms(ms: usize) void { var timer: ke.Timer = undefined; timer.init(); - ke.timer.set(&timer, std.time.ns_per_ms * ms, .{}); + ke.timer.set(&timer, .init(std.time.ns_per_ms * ms), .{}); _ = ke.wait.wait_one(&timer.hdr, "sleep", .{}) catch unreachable; } @@ -79,7 +79,7 @@ fn park_point() void { fn spin_us(us: u64) void { const began = ke.time.read_time(); - while (ke.time.read_time() - began < us * std.time.ns_per_us) { + while (ke.time.read_time().value - began.value < us * std.time.ns_per_us) { std.atomic.spinLoopHint(); } } diff --git a/src/tests/turnstile.zig b/src/tests/turnstile.zig index aa4cea9..a093de3 100644 --- a/src/tests/turnstile.zig +++ b/src/tests/turnstile.zig @@ -45,7 +45,7 @@ fn rand(state: *u64) u64 { fn delay_ms(ms: usize) void { var timer: ke.Timer = undefined; timer.init(); - ke.timer.set(&timer, std.time.ns_per_ms * ms, .{}); + ke.timer.set(&timer, .init(std.time.ns_per_ms * ms), .{}); _ = ke.wait.wait_one(&timer.hdr, "sleep", .{}) catch unreachable; } @@ -145,7 +145,7 @@ fn chain_test() void { fn stress(param: ?*anyopaque) void { const id = @intFromPtr(param.?) - 1; - var seed = (ke.time.read_time() ^ (id *% 0x9e3779b97f4a7c15)) | 1; + var seed = (ke.time.read_time().value ^ (id *% 0x9e3779b97f4a7c15)) | 1; var iter: u64 = 0; while (true) : (iter += 1) {