authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-07 20:20:03-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-07 21:13:16-08:00
log4319c8924ed2a73abdc8f4caa80703d2949be810
tree4e8a0853d81b57990f8a55cf7f8e0b0ecfd3dfe1
parent6a5bb3ede36ab9dd7a5ce95e1339ca4e138886fc

std.Io.Threaded: clock_nanosleep is not linux-only

clock_nanosleep is specified by POSIX but not implemented on these hereby shamed operating systems: * macOS * OpenBSD (which defines TIMER_ABSTIME for some reason...?)

2 files changed, 21 insertions(+), 8 deletions(-)

lib/std/Io/Threaded.zig+6-8
...@@ -9664,14 +9664,12 @@ fn nowWasi(clock: Io.Clock) Io.Clock.Error!Io.Timestamp {...@@ -9664,14 +9664,12 @@ fn nowWasi(clock: Io.Clock) Io.Clock.Error!Io.Timestamp {
9664fn sleep(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {9664fn sleep(userdata: ?*anyopaque, timeout: Io.Timeout) Io.SleepError!void {
9665 const t: *Threaded = @ptrCast(@alignCast(userdata));9665 const t: *Threaded = @ptrCast(@alignCast(userdata));
9666 if (use_parking_sleep) return parking_sleep.sleep(timeout);9666 if (use_parking_sleep) return parking_sleep.sleep(timeout);
9667 switch (native_os) {9667 if (native_os == .wasi) return sleepWasi(t, timeout);
9668 .wasi => return sleepWasi(t, timeout),9668 if (@TypeOf(posix.system.clock_nanosleep) != void) return sleepPosix(timeout);
9669 .linux => return sleepLinux(timeout),9669 return sleepNanosleep(t, timeout);
9670 else => return sleepPosix(t, timeout),
9671 }
9672}9670}
96739671
9674fn sleepLinux(timeout: Io.Timeout) Io.SleepError!void {9672fn sleepPosix(timeout: Io.Timeout) Io.SleepError!void {
9675 const clock_id: posix.clockid_t = clockToPosix(switch (timeout) {9673 const clock_id: posix.clockid_t = clockToPosix(switch (timeout) {
9676 .none => .awake,9674 .none => .awake,
9677 .duration => |d| d.clock,9675 .duration => |d| d.clock,
...@@ -9685,7 +9683,7 @@ fn sleepLinux(timeout: Io.Timeout) Io.SleepError!void {...@@ -9685,7 +9683,7 @@ fn sleepLinux(timeout: Io.Timeout) Io.SleepError!void {
9685 var timespec: posix.timespec = timestampToPosix(deadline_nanoseconds);9683 var timespec: posix.timespec = timestampToPosix(deadline_nanoseconds);
9686 const syscall: Syscall = try .start();9684 const syscall: Syscall = try .start();
9687 while (true) {9685 while (true) {
9688 switch (std.os.linux.errno(std.os.linux.clock_nanosleep(clock_id, .{ .ABSTIME = switch (timeout) {9686 switch (posix.errno(posix.system.clock_nanosleep(clock_id, .{ .ABSTIME = switch (timeout) {
9689 .none, .duration => false,9687 .none, .duration => false,
9690 .deadline => true,9688 .deadline => true,
9691 } }, &timespec, &timespec))) {9689 } }, &timespec, &timespec))) {
...@@ -9737,7 +9735,7 @@ fn sleepWasi(t: *Threaded, timeout: Io.Timeout) Io.SleepError!void {...@@ -9737,7 +9735,7 @@ fn sleepWasi(t: *Threaded, timeout: Io.Timeout) Io.SleepError!void {
9737 syscall.finish();9735 syscall.finish();
9738}9736}
97399737
9740fn sleepPosix(t: *Threaded, timeout: Io.Timeout) Io.SleepError!void {9738fn sleepNanosleep(t: *Threaded, timeout: Io.Timeout) Io.SleepError!void {
9741 const t_io = ioBasic(t);9739 const t_io = ioBasic(t);
9742 const sec_type = @typeInfo(posix.timespec).@"struct".fields[0].type;9740 const sec_type = @typeInfo(posix.timespec).@"struct".fields[0].type;
9743 const nsec_type = @typeInfo(posix.timespec).@"struct".fields[1].type;9741 const nsec_type = @typeInfo(posix.timespec).@"struct".fields[1].type;
lib/std/c.zig+15
...@@ -11078,6 +11078,20 @@ pub extern "c" fn pthread_getthreadid_np() c_int;...@@ -11078,6 +11078,20 @@ pub extern "c" fn pthread_getthreadid_np() c_int;
11078pub extern "c" fn pthread_set_name_np(thread: pthread_t, name: [*:0]const u8) void;11078pub extern "c" fn pthread_set_name_np(thread: pthread_t, name: [*:0]const u8) void;
11079pub extern "c" fn pthread_get_name_np(thread: pthread_t, name: [*:0]u8, len: usize) void;11079pub extern "c" fn pthread_get_name_np(thread: pthread_t, name: [*:0]u8, len: usize) void;
1108011080
11081pub const TIMER = switch (native_os) {
11082 .linux, .emscripten => std.os.linux.TIMER,
11083 .openbsd, .netbsd, .wasi, .windows, .freebsd => packed struct(u32) {
11084 ABSTIME: bool,
11085 _: u31 = 0,
11086 },
11087 else => void,
11088};
11089
11090pub const clock_nanosleep = switch (native_os) {
11091 .linux, .emscripten, .netbsd, .wasi, .windows, .freebsd => private.clock_nanosleep,
11092 else => {},
11093};
11094
11081// OS-specific bits. These are protected from being used on the wrong OS by11095// OS-specific bits. These are protected from being used on the wrong OS by
11082// comptime assertions inside each OS-specific file.11096// comptime assertions inside each OS-specific file.
1108311097
...@@ -11467,6 +11481,7 @@ const private = struct {...@@ -11467,6 +11481,7 @@ const private = struct {
11467 extern "c" fn gettimeofday(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int;11481 extern "c" fn gettimeofday(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int;
11468 extern "c" fn msync(addr: *align(page_size) const anyopaque, len: usize, flags: c_int) c_int;11482 extern "c" fn msync(addr: *align(page_size) const anyopaque, len: usize, flags: c_int) c_int;
11469 extern "c" fn nanosleep(rqtp: *const timespec, rmtp: ?*timespec) c_int;11483 extern "c" fn nanosleep(rqtp: *const timespec, rmtp: ?*timespec) c_int;
11484 extern "c" fn clock_nanosleep(clockid: clockid_t, flags: TIMER, t: *const timespec, remain: ?*timespec) c_int;
11470 extern "c" fn pipe2(fds: *[2]fd_t, flags: O) c_int;11485 extern "c" fn pipe2(fds: *[2]fd_t, flags: O) c_int;
11471 extern "c" fn readdir(dir: *DIR) ?*dirent;11486 extern "c" fn readdir(dir: *DIR) ?*dirent;
11472 extern "c" fn realpath(noalias file_name: [*:0]const u8, noalias resolved_name: [*]u8) ?[*:0]u8;11487 extern "c" fn realpath(noalias file_name: [*:0]const u8, noalias resolved_name: [*]u8) ?[*:0]u8;