aboutsummaryrefslogtreecommitdiff
path: root/src/io/time.zig
blob: 1454d009bafcb39f33d310e56717930b7a15b447 (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 @as(u64, @intCast(ts.tv_sec)) * std.time.ns_per_s + @as(u64, @intCast(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 {}
};
ow=1'>fix bun server segfault with abortsignal (#2261)Gravatar Ciro Spaciari 3-133/+79 2023-03-01fix(node:http): match Node `http.request()` GET/HEAD w/ body (#2262)Gravatar Derrick Farris 2-2/+31 2023-03-01Add a test for https request in node:httpGravatar Jarred Sumner 2-17/+28 2023-03-01fix(node:http/https): fix passing `URL` objs to `http.request`(#2253) (#2258)Gravatar Derrick Farris 2-43/+63 2023-03-01Revert "Update clap (#2238)"Gravatar Jarred Sumner 16-290/+1840 2023-03-01Revert "Add `-D`, `--dev` flags for bun install (#2240)"Gravatar Jarred Sumner 1-9/+9 2023-03-01Use GitHub action ID instead of SHA for test workflowGravatar Ashcon Partovi 1-1/+1 2023-03-01avoids segfault after aborted onReject in Bun.serve streams (#2256)Gravatar Ciro Spaciari 1-7/+8 2023-03-01Run tests in CI for bun-linux-aarch64Gravatar Ashcon Partovi 2-1/+30 2023-03-01Revert spawnSync changeGravatar Jarred Sumner 1-1/+2 2023-03-01Update bindings.zigGravatar Jarred Sumner 1-1/+3 2023-03-01fix deinit behavior when connection is aborted using ResponseStream and abort...Gravatar Ciro Spaciari 3-34/+174 2023-03-01fix Bun.file.arrayBuffer() segmentation fault on empty file #2248 (#2249)Gravatar Ciro Spaciari 3-7/+23 2023-03-01Fix async in sqliteGravatar Colin McDonnell 1-2/+2 2023-02-28Forces a specific libdir for c-ares (#2241)Gravatar Justin Whear 1-1/+5 2023-02-28Make Bun.gc(true) more aggressiveGravatar Jarred Sumner 1-0/+3 2023-02-28Expose JSC::Options via `BUN_JSC_` prefixGravatar Jarred Sumner 6-8/+47 2023-02-28fixupGravatar Jarred Sumner 1-1/+1 2023-02-28Fix typecheckGravatar Colin McDonnell 2-1/+4 2023-02-28Fix incorrect Bun version in docs (#2236)Gravatar Derrick Farris 1-1/+1 2023-02-28just some comments fix (#2237)Gravatar Ciro Spaciari 1-4/+2 2023-02-28Add `-D`, `--dev` flags for bun install (#2240)Gravatar Justin Whear 1-9/+9 2023-02-28Document punningGravatar Colin McDonnell 1-1/+18