aboutsummaryrefslogtreecommitdiff
path: root/src/io/time.zig
blob: 8ebf5de6ea575a5ee92c11a1b73b7e4a82614da6 (plain) (blame)
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
const std = @import("std");
const assert = std.debug.assert;
const is_darwin = @import("builtin").target.isDarwin();

pub const Time = struct {
    const Self = @This();

    /// Hardware and/or software bugs can mean that the monotonic clock may regress.
    /// One example (of many): https://bugzilla.redhat.com/show_bug.cgi?id=448449
    /// We crash the process for safety if this ever happens, to protect against infinite loops.
    /// It's better to crash and come back with a valid monotonic clock than get stuck forever.
    monotonic_guard: u64 = 0,

    /// A timestamp to measure elapsed time, meaningful only on the same system, not across reboots.
    /// Always use a monotonic timestamp if the goal is to measure elapsed time.
    /// This clock is not affected by discontinuous jumps in the system time, for example if the
    /// system administrator manually changes the clock.
    pub fn monotonic(self: *Self) u64 {
        const m = blk: {
            // Uses mach_continuous_time() instead of mach_absolute_time() as it counts while suspended.
            // https://developer.apple.com/documentation/kernel/1646199-mach_continuous_time
            // https://opensource.apple.com/source/Libc/Libc-1158.1.2/gen/clock_gettime.c.auto.html
            if (is_darwin) {
                const darwin = struct {
                    const mach_timebase_info_t = std.os.darwin.mach_timebase_info_data;
                    extern "c" fn mach_timebase_info(info: *mach_timebase_info_t) std.os.darwin.kern_return_t;
                    extern "c" fn mach_continuous_time() u64;
                };

                const now = darwin.mach_continuous_time();
                var info: darwin.mach_timebase_info_t = undefined;
                if (darwin.mach_timebase_info(&info) != 0) @panic("mach_timebase_info() failed");
                return (now * info.numer) / info.denom;
            }

            // The true monotonic clock on Linux is not in fact CLOCK_MONOTONIC:
            // CLOCK_MONOTONIC excludes elapsed time while the system is suspended (e.g. VM migration).
            // CLOCK_BOOTTIME is the same as CLOCK_MONOTONIC but includes elapsed time during a suspend.
            // For more detail and why CLOCK_MONOTONIC_RAW is even worse than CLOCK_MONOTONIC,
            // see https://github.com/ziglang/zig/pull/933#discussion_r656021295.
            var ts: std.os.timespec = undefined;
            std.os.clock_gettime(std.os.CLOCK_BOOTTIME, &ts) catch @panic("CLOCK_BOOTTIME required");
            break :blk @intCast(u64, ts.tv_sec) * std.time.ns_per_s + @intCast(u64, ts.tv_nsec);
        };

        // "Oops!...I Did It Again"
        if (m < self.monotonic_guard) @panic("a hardware/kernel bug regressed the monotonic clock");
        self.monotonic_guard = m;
        return m;
    }

    /// A timestamp to measure real (i.e. wall clock) time, meaningful across systems, and reboots.
    /// This clock is affected by discontinuous jumps in the system time.
    pub fn realtime(_: *Self) i64 {
        // macos has supported clock_gettime() since 10.12:
        // https://opensource.apple.com/source/Libc/Libc-1158.1.2/gen/clock_gettime.3.auto.html

        var ts: std.os.timespec = undefined;
        std.os.clock_gettime(std.os.CLOCK_REALTIME, &ts) catch unreachable;
        return @as(i64, ts.tv_sec) * std.time.ns_per_s + ts.tv_nsec;
    }

    pub fn tick(_: *Self) void {}
};
+4 2023-10-07feat(KeyObject) (#5940)Gravatar Ciro Spaciari 106-67/+9342 * oops * createSecretKey but weird error * use the right prototype, do not add a function called export lol * HMAC JWT export + base64 fix * Fix Equals, Fix Get KeySize, add complete export RSA * fix RSA export * add EC exports * X25519 and ED25519 export + fixes * fix default exports * better asymmetricKeyType * fix private exports * fix symmetricKeySize * createPublicKey validations + refactor * jwt + der fixes * oopsies * add PEM into createPublicKey * cleanup * WIP * bunch of fixes * public from private + private OKP * encrypted keys fixes * oops * fix clear tls error, add some support to jwk and other formats on publicEncrypt/publicDecrypt * more fixes and tests working * more fixes more tests * more clear hmac errors * more tests and fixes * add generateKeyPair * more tests passing, some skips * fix EC key from private * fix OKP JWK * nodejs ignores ext and key_ops on KeyObject.exports * add EC sign verify test * some fixes * add crypto.generateKeyPairSync(type, options) * more fixes and more tests * fix hmac tests * jsonwebtoken tests * oops * oops2 * generated files * revert package.json * vm tests * todos instead of failues * toBunString -> toString * undo simdutf * improvements * unlikely * cleanup * cleanup 2 * oops * move _generateKeyPairSync checks to native 2023-10-07Exclude more filesGravatar Jarred Sumner 1-1/+1 2023-10-07Exclude more filesGravatar Jarred Sumner 1-1/+2 2023-10-07Update settings.jsonGravatar Jarred Sumner 1-1/+2 2023-10-07Update settings.jsonGravatar Jarred Sumner 1-2/+3 2023-10-06fix a couple install testsGravatar Dylan Conway 1-8/+8 2023-10-06formatGravatar Dylan Conway 1-1/+2 2023-10-06Fix memory leak in fetch() (#6350)Gravatar Jarred Sumner 1-2/+0 Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-10-06[types] allow onLoad plugin callbacks to return undefined (#6346)Gravatar Silver 1-1/+1 Returning undefined simply falls through to the next plugin, or to the default loader. This is defined by esbuild, and supported by Bun, but the types don't reflect it properly. 2023-10-06docs: `file.stream()` is not a promise (#6337)Gravatar Paul Nodet 1-1/+1