1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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()) |_| {}
}
|