Skip to content

Commit 7f49b6c

Browse files
Linux: Use time64 syscalls when available
Newer 32-bit Linux targets like 32-bit RISC-V only use the 64-bit time ABI, with these syscalls having `time64` as their suffix. This is a stopgap solution in favor of a full audit of `std.os.linux` to prepare for #4726. See also #21440 for prior art.
1 parent 680aac8 commit 7f49b6c

File tree

1 file changed

+76
-25
lines changed

1 file changed

+76
-25
lines changed

lib/std/os/linux.zig

Lines changed: 76 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,13 @@ pub fn futimens(fd: i32, times: ?*const [2]timespec) usize {
643643
}
644644

645645
pub fn utimensat(dirfd: i32, path: ?[*:0]const u8, times: ?*const [2]timespec, flags: u32) usize {
646-
return syscall4(.utimensat, @as(usize, @bitCast(@as(isize, dirfd))), @intFromPtr(path), @intFromPtr(times), flags);
646+
return syscall4(
647+
if (@hasField(SYS, "utimensat")) .utimensat else .utimensat_time64,
648+
@as(usize, @bitCast(@as(isize, dirfd))),
649+
@intFromPtr(path),
650+
@intFromPtr(times),
651+
flags,
652+
);
647653
}
648654

649655
pub fn fallocate(fd: i32, mode: i32, offset: i64, length: i64) usize {
@@ -685,19 +691,38 @@ pub const futex_param4 = extern union {
685691
/// The futex_op parameter is a sub-command and flags. The sub-command
686692
/// defines which of the subsequent paramters are relevant.
687693
pub fn futex(uaddr: *const anyopaque, futex_op: FUTEX_OP, val: u32, val2timeout: futex_param4, uaddr2: ?*const anyopaque, val3: u32) usize {
688-
return syscall6(.futex, @intFromPtr(uaddr), @as(u32, @bitCast(futex_op)), val, @intFromPtr(val2timeout.timeout), @intFromPtr(uaddr2), val3);
694+
return syscall6(
695+
if (@hasField(SYS, "futex")) .futex else .futex_time64,
696+
@intFromPtr(uaddr),
697+
@as(u32, @bitCast(futex_op)),
698+
val,
699+
@intFromPtr(val2timeout.timeout),
700+
@intFromPtr(uaddr2),
701+
val3,
702+
);
689703
}
690704

691705
/// Three-argument variation of the v1 futex call. Only suitable for a
692706
/// futex_op that ignores the remaining arguments (e.g., FUTUX_OP.WAKE).
693707
pub fn futex_3arg(uaddr: *const anyopaque, futex_op: FUTEX_OP, val: u32) usize {
694-
return syscall3(.futex, @intFromPtr(uaddr), @as(u32, @bitCast(futex_op)), val);
708+
return syscall3(
709+
if (@hasField(SYS, "futex")) .futex else .futex_time64,
710+
@intFromPtr(uaddr),
711+
@as(u32, @bitCast(futex_op)),
712+
val,
713+
);
695714
}
696715

697716
/// Four-argument variation on the v1 futex call. Only suitable for
698717
/// futex_op that ignores the remaining arguments (e.g., FUTEX_OP.WAIT).
699718
pub fn futex_4arg(uaddr: *const anyopaque, futex_op: FUTEX_OP, val: u32, timeout: ?*const timespec) usize {
700-
return syscall4(.futex, @intFromPtr(uaddr), @as(u32, @bitCast(futex_op)), val, @intFromPtr(timeout));
719+
return syscall4(
720+
if (@hasField(SYS, "futex")) .futex else .futex_time64,
721+
@intFromPtr(uaddr),
722+
@as(u32, @bitCast(futex_op)),
723+
val,
724+
@intFromPtr(timeout),
725+
);
701726
}
702727

703728
/// Given an array of `futex2_waitone`, wait on each uaddr.
@@ -1053,28 +1078,32 @@ pub fn munlockall() usize {
10531078
}
10541079

10551080
pub fn poll(fds: [*]pollfd, n: nfds_t, timeout: i32) usize {
1056-
if (@hasField(SYS, "poll")) {
1057-
return syscall3(.poll, @intFromPtr(fds), n, @as(u32, @bitCast(timeout)));
1058-
} else {
1059-
return syscall5(
1060-
.ppoll,
1061-
@intFromPtr(fds),
1081+
return if (@hasField(SYS, "poll"))
1082+
return syscall3(.poll, @intFromPtr(fds), n, @as(u32, @bitCast(timeout)))
1083+
else
1084+
ppoll(
1085+
fds,
10621086
n,
1063-
@intFromPtr(if (timeout >= 0)
1064-
&timespec{
1087+
if (timeout >= 0)
1088+
@constCast(&timespec{
10651089
.sec = @divTrunc(timeout, 1000),
10661090
.nsec = @rem(timeout, 1000) * 1000000,
1067-
}
1091+
})
10681092
else
1069-
null),
1070-
0,
1071-
NSIG / 8,
1093+
null,
1094+
null,
10721095
);
1073-
}
10741096
}
10751097

10761098
pub fn ppoll(fds: [*]pollfd, n: nfds_t, timeout: ?*timespec, sigmask: ?*const sigset_t) usize {
1077-
return syscall5(.ppoll, @intFromPtr(fds), n, @intFromPtr(timeout), @intFromPtr(sigmask), NSIG / 8);
1099+
return syscall5(
1100+
if (@hasField(SYS, "ppoll")) .ppoll else .ppoll_time64,
1101+
@intFromPtr(fds),
1102+
n,
1103+
@intFromPtr(timeout),
1104+
@intFromPtr(sigmask),
1105+
NSIG / 8,
1106+
);
10781107
}
10791108

10801109
pub fn read(fd: i32, buf: [*]u8, count: usize) usize {
@@ -1598,7 +1627,11 @@ pub fn clock_gettime(clk_id: clockid_t, tp: *timespec) usize {
15981627
}
15991628
}
16001629
}
1601-
return syscall2(.clock_gettime, @intFromEnum(clk_id), @intFromPtr(tp));
1630+
return syscall2(
1631+
if (@hasField(SYS, "clock_gettime")) .clock_gettime else .clock_gettime64,
1632+
@intFromEnum(clk_id),
1633+
@intFromPtr(tp),
1634+
);
16021635
}
16031636

16041637
fn init_vdso_clock_gettime(clk: clockid_t, ts: *timespec) callconv(.c) usize {
@@ -1612,16 +1645,24 @@ fn init_vdso_clock_gettime(clk: clockid_t, ts: *timespec) callconv(.c) usize {
16121645
}
16131646

16141647
pub fn clock_getres(clk_id: i32, tp: *timespec) usize {
1615-
return syscall2(.clock_getres, @as(usize, @bitCast(@as(isize, clk_id))), @intFromPtr(tp));
1648+
return syscall2(
1649+
if (@hasField(SYS, "clock_getres")) .clock_getres else .clock_getres_time64,
1650+
@as(usize, @bitCast(@as(isize, clk_id))),
1651+
@intFromPtr(tp),
1652+
);
16161653
}
16171654

16181655
pub fn clock_settime(clk_id: i32, tp: *const timespec) usize {
1619-
return syscall2(.clock_settime, @as(usize, @bitCast(@as(isize, clk_id))), @intFromPtr(tp));
1656+
return syscall2(
1657+
if (@hasField(SYS, "clock_settime")) .clock_settime else .clock_settime64,
1658+
@as(usize, @bitCast(@as(isize, clk_id))),
1659+
@intFromPtr(tp),
1660+
);
16201661
}
16211662

16221663
pub fn clock_nanosleep(clockid: clockid_t, flags: TIMER, request: *const timespec, remain: ?*timespec) usize {
16231664
return syscall4(
1624-
.clock_nanosleep,
1665+
if (@hasField(SYS, "clock_nanosleep")) .clock_nanosleep else .clock_nanosleep_time64,
16251666
@intFromEnum(clockid),
16261667
@as(u32, @bitCast(flags)),
16271668
@intFromPtr(request),
@@ -2020,7 +2061,7 @@ pub fn recvmsg(fd: i32, msg: *msghdr, flags: u32) usize {
20202061

20212062
pub fn recvmmsg(fd: i32, msgvec: ?[*]mmsghdr, vlen: u32, flags: u32, timeout: ?*timespec) usize {
20222063
return syscall5(
2023-
.recvmmsg,
2064+
if (@hasField(SYS, "recvmmsg")) .recvmmsg else .recvmmsg_time64,
20242065
@as(usize, @bitCast(@as(isize, fd))),
20252066
@intFromPtr(msgvec),
20262067
vlen,
@@ -2369,11 +2410,21 @@ pub const itimerspec = extern struct {
23692410
};
23702411

23712412
pub fn timerfd_gettime(fd: i32, curr_value: *itimerspec) usize {
2372-
return syscall2(.timerfd_gettime, @bitCast(@as(isize, fd)), @intFromPtr(curr_value));
2413+
return syscall2(
2414+
if (@hasField(SYS, "timerfd_gettime")) .timerfd_gettime else .timerfd_gettime64,
2415+
@bitCast(@as(isize, fd)),
2416+
@intFromPtr(curr_value),
2417+
);
23732418
}
23742419

23752420
pub fn timerfd_settime(fd: i32, flags: TFD.TIMER, new_value: *const itimerspec, old_value: ?*itimerspec) usize {
2376-
return syscall4(.timerfd_settime, @bitCast(@as(isize, fd)), @as(u32, @bitCast(flags)), @intFromPtr(new_value), @intFromPtr(old_value));
2421+
return syscall4(
2422+
if (@hasField(SYS, "timerfd_settime")) .timerfd_settime else .timerfd_settime64,
2423+
@bitCast(@as(isize, fd)),
2424+
@as(u32, @bitCast(flags)),
2425+
@intFromPtr(new_value),
2426+
@intFromPtr(old_value),
2427+
);
23772428
}
23782429

23792430
// Flags for the 'setitimer' system call

0 commit comments

Comments
 (0)