summaryrefslogtreecommitdiff
path: root/test/bench_util.zig
diff options
context:
space:
mode:
Diffstat (limited to 'test/bench_util.zig')
-rw-r--r--test/bench_util.zig43
1 files changed, 43 insertions, 0 deletions
diff --git a/test/bench_util.zig b/test/bench_util.zig
new file mode 100644
index 00000000..9b91e621
--- /dev/null
+++ b/test/bench_util.zig
@@ -0,0 +1,43 @@
+//! 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()) |_| {}
+}