Skip to content

Commit 6080f2d

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 6f60c8e commit 6080f2d

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
@@ -644,7 +644,13 @@ pub fn futimens(fd: i32, times: ?*const [2]timespec) usize {
644644
}
645645

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

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

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

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

704729
/// Given an array of `futex2_waitone`, wait on each uaddr.
@@ -1054,28 +1079,32 @@ pub fn munlockall() usize {
10541079
}
10551080

10561081
pub fn poll(fds: [*]pollfd, n: nfds_t, timeout: i32) usize {
1057-
if (@hasField(SYS, "poll")) {
1058-
return syscall3(.poll, @intFromPtr(fds), n, @as(u32, @bitCast(timeout)));
1059-
} else {
1060-
return syscall5(
1061-
.ppoll,
1062-
@intFromPtr(fds),
1082+
return if (@hasField(SYS, "poll"))
1083+
return syscall3(.poll, @intFromPtr(fds), n, @as(u32, @bitCast(timeout)))
1084+
else
1085+
ppoll(
1086+
fds,
10631087
n,
1064-
@intFromPtr(if (timeout >= 0)
1065-
&timespec{
1088+
if (timeout >= 0)
1089+
@constCast(&timespec{
10661090
.sec = @divTrunc(timeout, 1000),
10671091
.nsec = @rem(timeout, 1000) * 1000000,
1068-
}
1092+
})
10691093
else
1070-
null),
1071-
0,
1072-
NSIG / 8,
1094+
null,
1095+
null,
10731096
);
1074-
}
10751097
}
10761098

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

10811110
pub fn read(fd: i32, buf: [*]u8, count: usize) usize {
@@ -1599,7 +1628,11 @@ pub fn clock_gettime(clk_id: clockid_t, tp: *timespec) usize {
15991628
}
16001629
}
16011630
}
1602-
return syscall2(.clock_gettime, @intFromEnum(clk_id), @intFromPtr(tp));
1631+
return syscall2(
1632+
if (@hasField(SYS, "clock_gettime")) .clock_gettime else .clock_gettime64,
1633+
@intFromEnum(clk_id),
1634+
@intFromPtr(tp),
1635+
);
16031636
}
16041637

16051638
fn init_vdso_clock_gettime(clk: clockid_t, ts: *timespec) callconv(.c) usize {
@@ -1613,16 +1646,24 @@ fn init_vdso_clock_gettime(clk: clockid_t, ts: *timespec) callconv(.c) usize {
16131646
}
16141647

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

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

16231664
pub fn clock_nanosleep(clockid: clockid_t, flags: TIMER, request: *const timespec, remain: ?*timespec) usize {
16241665
return syscall4(
1625-
.clock_nanosleep,
1666+
if (@hasField(SYS, "clock_nanosleep")) .clock_nanosleep else .clock_nanosleep_time64,
16261667
@intFromEnum(clockid),
16271668
@as(u32, @bitCast(flags)),
16281669
@intFromPtr(request),
@@ -2021,7 +2062,7 @@ pub fn recvmsg(fd: i32, msg: *msghdr, flags: u32) usize {
20212062

20222063
pub fn recvmmsg(fd: i32, msgvec: ?[*]mmsghdr, vlen: u32, flags: u32, timeout: ?*timespec) usize {
20232064
return syscall5(
2024-
.recvmmsg,
2065+
if (@hasField(SYS, "recvmmsg")) .recvmmsg else .recvmmsg_time64,
20252066
@as(usize, @bitCast(@as(isize, fd))),
20262067
@intFromPtr(msgvec),
20272068
vlen,
@@ -2370,11 +2411,21 @@ pub const itimerspec = extern struct {
23702411
};
23712412

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

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

23802431
// Flags for the 'setitimer' system call

0 commit comments

Comments
 (0)