mirror of
https://github.com/rdmsr/zag.git
synced 2026-10-27 13:58:20 +00:00
all: type-safe time units
This commit is contained in:
+1
-1
@@ -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);
|
||||
|
||||
|
||||
+2
-2
@@ -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 },
|
||||
);
|
||||
}
|
||||
|
||||
+7
-1
@@ -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;
|
||||
|
||||
+7
-1
@@ -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;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ const Desc = struct {
|
||||
|
||||
pub const Info = struct {
|
||||
sequence: u64,
|
||||
timestamp: u64,
|
||||
timestamp: r.Nanoseconds,
|
||||
length: u16,
|
||||
};
|
||||
|
||||
|
||||
+10
-10
@@ -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 });
|
||||
}
|
||||
|
||||
+1
-1
@@ -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,
|
||||
|
||||
+5
-5
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+7
-7
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
|
||||
+3
-3
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+12
-9
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -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) {
|
||||
|
||||
+2
-2
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user