From f35015575ef7ef5b493cf217f5e9c7152d6b6658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sat, 31 Aug 2024 03:28:50 +0200 Subject: [PATCH] std.time: Use clock_nanosleep() to implement sleep() on Linux. This fixes the function for riscv32 where the old nanosleep() is not available. clock_nanosleep() has been available since Linux 2.6 and glibc 2.1 anyway. --- lib/std/time.zig | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/lib/std/time.zig b/lib/std/time.zig index 34e544a28b..a80a2477ac 100644 --- a/lib/std/time.zig +++ b/lib/std/time.zig @@ -50,6 +50,34 @@ pub fn sleep(nanoseconds: u64) void { const s = nanoseconds / ns_per_s; const ns = nanoseconds % ns_per_s; + + // Newer kernel ports don't have old `nanosleep()` and `clock_nanosleep()` has been around + // since Linux 2.6 and glibc 2.1 anyway. + if (builtin.os.tag == .linux) { + const linux = std.os.linux; + + var req: linux.timespec = .{ + .sec = std.math.cast(linux.time_t, s) orelse std.math.maxInt(linux.time_t), + .nsec = std.math.cast(linux.time_t, ns) orelse std.math.maxInt(linux.time_t), + }; + var rem: linux.timespec = undefined; + + while (true) { + switch (linux.E.init(linux.clock_nanosleep(.MONOTONIC, .{ .ABSTIME = false }, &req, &rem))) { + .SUCCESS => return, + .INTR => { + req = rem; + continue; + }, + .FAULT, + .INVAL, + .OPNOTSUPP, + => unreachable, + else => return, + } + } + } + posix.nanosleep(s, ns); }