mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 08:45:52 +00:00
Merge pull request #18328 from ExpidusOS/feat/uefi-time
std: add support for getting the time in UEFI
This commit is contained in:
commit
94c63f31f2
@ -131,6 +131,31 @@ pub const Time = extern struct {
|
||||
|
||||
/// Time is to be interpreted as local time
|
||||
pub const unspecified_timezone: i16 = 0x7ff;
|
||||
|
||||
fn daysInYear(year: u16, maxMonth: u4) u32 {
|
||||
const leapYear: std.time.epoch.YearLeapKind = if (std.time.epoch.isLeapYear(year)) .leap else .not_leap;
|
||||
var days: u32 = 0;
|
||||
var month: u4 = 0;
|
||||
while (month < maxMonth) : (month += 1) {
|
||||
days += std.time.epoch.getDaysInMonth(leapYear, @enumFromInt(month + 1));
|
||||
}
|
||||
return days;
|
||||
}
|
||||
|
||||
pub fn toEpoch(self: std.os.uefi.Time) u64 {
|
||||
var year: u16 = 0;
|
||||
var days: u32 = 0;
|
||||
|
||||
while (year < (self.year - 1971)) : (year += 1) {
|
||||
days += daysInYear(year + 1970, 12);
|
||||
}
|
||||
|
||||
days += daysInYear(self.year, @as(u4, @intCast(self.month)) - 1) + self.day;
|
||||
const hours = self.hour + (days * 24);
|
||||
const minutes = self.minute + (hours * 60);
|
||||
const seconds = self.second + (minutes * std.time.s_per_min);
|
||||
return self.nanosecond + (seconds * std.time.ns_per_s);
|
||||
}
|
||||
};
|
||||
|
||||
/// Capabilities of the clock device
|
||||
|
||||
@ -114,6 +114,13 @@ pub fn nanoTimestamp() i128 {
|
||||
return ns;
|
||||
}
|
||||
|
||||
if (builtin.os.tag == .uefi) {
|
||||
var value: std.os.uefi.Time = undefined;
|
||||
const status = std.os.uefi.system_table.runtime_services.getTime(&value, null);
|
||||
assert(status == .Success);
|
||||
return value.toEpoch();
|
||||
}
|
||||
|
||||
var ts: os.timespec = undefined;
|
||||
os.clock_gettime(os.CLOCK.REALTIME, &ts) catch |err| switch (err) {
|
||||
error.UnsupportedClock, error.Unexpected => return 0, // "Precision of timing depends on hardware and OS".
|
||||
@ -176,7 +183,7 @@ pub const Instant = struct {
|
||||
// true if we should use clock_gettime()
|
||||
const is_posix = switch (builtin.os.tag) {
|
||||
.wasi => builtin.link_libc,
|
||||
.windows => false,
|
||||
.windows, .uefi => false,
|
||||
else => true,
|
||||
};
|
||||
|
||||
@ -197,6 +204,13 @@ pub const Instant = struct {
|
||||
return Instant{ .timestamp = ns };
|
||||
}
|
||||
|
||||
if (builtin.os.tag == .uefi) {
|
||||
var value: std.os.uefi.Time = undefined;
|
||||
const status = std.os.uefi.system_table.runtime_services.getTime(&value, null);
|
||||
if (status != .Success) return error.Unsupported;
|
||||
return Instant{ .timestamp = value.toEpoch() };
|
||||
}
|
||||
|
||||
// On darwin, use UPTIME_RAW instead of MONOTONIC as it ticks while suspended.
|
||||
// On linux, use BOOTTIME instead of MONOTONIC as it ticks while suspended.
|
||||
// On freebsd derivatives, use MONOTONIC_FAST as currently there's no precision tradeoff.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user