DoxigAlpha

since

Returns elapsed time in nanoseconds since the earlier Instant. This assumes that the earlier Instant represents a moment in time before or equal to self. This also assumes that the time that has passed between both Instants fits inside a u64 (~585 yrs).

Function parameters

Parameters

#

Type definitions in this namespace

Types

#
Instant
An Instant represents a timestamp with respect to the currently
Timer
A monotonic, high performance timer.

Get a calendar timestamp, in seconds, relative to UTC 1970-01-01.

Functions

#
timestamp
Get a calendar timestamp, in seconds, relative to UTC 1970-01-01.
milliTimestamp
Get a calendar timestamp, in milliseconds, relative to UTC 1970-01-01.
microTimestamp
Get a calendar timestamp, in microseconds, relative to UTC 1970-01-01.
nanoTimestamp
Get a calendar timestamp, in nanoseconds, relative to UTC 1970-01-01.

= 1000

Values

#
ns_per_us
= 1000
ns_per_ms
= 1000 * ns_per_us
ns_per_s
= 1000 * ns_per_ms
ns_per_min
= 60 * ns_per_s
ns_per_hour
= 60 * ns_per_min
ns_per_day
= 24 * ns_per_hour
ns_per_week
= 7 * ns_per_day
us_per_ms
= 1000
us_per_s
= 1000 * us_per_ms
us_per_min
= 60 * us_per_s
us_per_hour
= 60 * us_per_min
us_per_day
= 24 * us_per_hour
us_per_week
= 7 * us_per_day
ms_per_s
= 1000
ms_per_min
= 60 * ms_per_s
ms_per_hour
= 60 * ms_per_min
ms_per_day
= 24 * ms_per_hour
ms_per_week
= 7 * ms_per_day
s_per_hour
= s_per_min * 60
s_per_day
= s_per_hour * 24
s_per_week
= s_per_day * 7

Source

Implementation

#
pub fn since(self: Instant, earlier: Instant) u64 {
    switch (builtin.os.tag) {
        .windows => {
            // We don't need to cache QPF as it's internally just a memory read to KUSER_SHARED_DATA
            // (a read-only page of info updated and mapped by the kernel to all processes):
            // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/ns-ntddk-kuser_shared_data
            // https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntexapi_x/kuser_shared_data/index.htm
            const qpc = self.timestamp - earlier.timestamp;
            const qpf = windows.QueryPerformanceFrequency();

            // 10Mhz (1 qpc tick every 100ns) is a common enough QPF value that we can optimize on it.
            // https://github.com/microsoft/STL/blob/785143a0c73f030238ef618890fd4d6ae2b3a3a0/stl/inc/chrono#L694-L701
            const common_qpf = 10_000_000;
            if (qpf == common_qpf) {
                return qpc * (ns_per_s / common_qpf);
            }

            // Convert to ns using fixed point.
            const scale = @as(u64, std.time.ns_per_s << 32) / @as(u32, @intCast(qpf));
            const result = (@as(u96, qpc) * scale) >> 32;
            return @as(u64, @truncate(result));
        },
        .uefi, .wasi => {
            // UEFI and WASI timestamps are directly in nanoseconds
            return self.timestamp - earlier.timestamp;
        },
        else => {
            // Convert timespec diff to ns
            const seconds = @as(u64, @intCast(self.timestamp.sec - earlier.timestamp.sec));
            const elapsed = (seconds * ns_per_s) + @as(u32, @intCast(self.timestamp.nsec));
            return elapsed - @as(u32, @intCast(earlier.timestamp.nsec));
        },
    }
}