//! What the PDF benches share: a clock, a fatal exit named for the bench, a //! seeded hash, a count parser and the core's effect drain. const std = @import("std"); pub fn nowNs() u64 { var ts: std.c.timespec = undefined; _ = std.c.clock_gettime(.MONOTONIC, &ts); return @as(u64, @intCast(ts.sec)) *| 1_000_000_000 +| @as(u64, @intCast(ts.nsec)); } /// `fatal` for the bench called `who`: says so, prefixed, and exits 1. pub fn Fatal(comptime who: []const u8) type { return struct { pub fn f(comptime format: []const u8, args: anytype) noreturn { std.debug.print(who ++ ": " ++ format ++ "\n", args); std.process.exit(1); } }; } /// A seeded hash of `value`'s bytes; a comptime integer hashes as a u64. pub fn mix(seed: u64, value: anytype) u64 { const Value = @TypeOf(value); const Stable = switch (@typeInfo(Value)) { .comptime_int => u64, else => Value, }; var stable: Stable = value; return std.hash.Wyhash.hash(seed, std.mem.asBytes(&stable)); } /// A flag's value as a count in 1..`maximum`, or `fatal` saying why not. pub fn parsePositive(comptime fatal: anytype, name: []const u8, text: []const u8, maximum: usize) usize { const value = std.fmt.parseUnsigned(usize, text, 10) catch fatal("{s} expects a positive integer", .{name}); if (value == 0 or value > maximum) fatal("{s} must be in 1..{d}", .{ name, maximum }); return value; } pub fn drainEffects(core: anytype) void { while (core.nextEffect()) |_| {} }