diff --git a/lib/std/c/freebsd.zig b/lib/std/c/freebsd.zig index a60f5de525ee..7ab1041ba3db 100644 --- a/lib/std/c/freebsd.zig +++ b/lib/std/c/freebsd.zig @@ -352,6 +352,38 @@ pub const Stat = extern struct { } }; +pub extern "c" fn timerfd_create(clockid: c_int, flags: c_int) c_int; + +pub extern "c" fn timerfd_settime( + fd: c_int, + flags: c_int, + new_value: *const itimerspec, + old_value: ?*itimerspec, +) c_int; + +pub extern "c" fn timerfd_gettime(fd: c_int, curr_value: *itimerspec) c_int; + +const TFD_TIMER = packed struct(u32) { + ABSTIME: bool = false, + CANCEL_ON_SET: bool = false, + _: u30 = 0, +}; + +pub const TFD = packed struct(u32) { + _0: u2 = 0, + NONBLOCK: bool = false, + _3: u17 = 0, + CLOEXEC: bool = false, + _: u11 = 0, + + pub const TIMER = TFD_TIMER; +}; + +pub const itimerspec = extern struct { + it_interval: timespec, + it_value: timespec, +}; + pub const timespec = extern struct { tv_sec: isize, tv_nsec: isize, diff --git a/lib/std/c/linux.zig b/lib/std/c/linux.zig index 1a3c63451502..436f42de3b00 100644 --- a/lib/std/c/linux.zig +++ b/lib/std/c/linux.zig @@ -52,6 +52,7 @@ pub const T = linux.T; pub const TCP = linux.TCP; pub const TCSA = linux.TCSA; pub const VDSO = linux.VDSO; +pub const TFD = linux.TFD; pub const W = linux.W; pub const W_OK = linux.W_OK; pub const X_OK = linux.X_OK; @@ -68,6 +69,7 @@ pub const fd_t = linux.fd_t; pub const gid_t = linux.gid_t; pub const ifreq = linux.ifreq; pub const ino_t = linux.ino_t; +pub const itimerspec = linux.itimerspec; pub const mcontext_t = linux.mcontext_t; pub const mode_t = linux.mode_t; pub const msghdr = linux.msghdr; @@ -75,6 +77,7 @@ pub const msghdr_const = linux.msghdr_const; pub const nfds_t = linux.nfds_t; pub const nlink_t = linux.nlink_t; pub const off_t = linux.off_t; +pub const perf_event_attr = linux.perf_event_attr; pub const pid_t = linux.pid_t; pub const pollfd = linux.pollfd; pub const rlim_t = linux.rlim_t; @@ -344,3 +347,15 @@ pub const dirent64 = struct { type: u8, name: [256]u8, }; + +// Neither glibc nor musl provide a wrapper function for this syscall +pub const perf_event_open = linux.perf_event_open; + +pub extern "c" fn timerfd_create(clockid: c_int, flags: c_int) c_int; +pub extern "c" fn timerfd_settime( + fd: c_int, + flags: c_int, + new_value: *const itimerspec, + old_value: ?*itimerspec, +) c_int; +pub extern "c" fn timerfd_gettime(fd: c_int, curr_value: *itimerspec) c_int; diff --git a/lib/std/posix.zig b/lib/std/posix.zig index 167c945abf87..1b463f19f395 100644 --- a/lib/std/posix.zig +++ b/lib/std/posix.zig @@ -3968,7 +3968,7 @@ pub const EpollCtlError = error{ FileDescriptorIncompatibleWithEpoll, } || UnexpectedError; -pub fn epoll_ctl(epfd: i32, op: u32, fd: i32, event: ?*linux.epoll_event) EpollCtlError!void { +pub fn epoll_ctl(epfd: i32, op: u32, fd: i32, event: ?*system.epoll_event) EpollCtlError!void { const rc = system.epoll_ctl(epfd, op, fd, event); switch (errno(rc)) { .SUCCESS => return, @@ -3988,7 +3988,7 @@ pub fn epoll_ctl(epfd: i32, op: u32, fd: i32, event: ?*linux.epoll_event) EpollC /// Waits for an I/O event on an epoll file descriptor. /// Returns the number of file descriptors ready for the requested I/O, /// or zero if no file descriptor became ready during the requested timeout milliseconds. -pub fn epoll_wait(epfd: i32, events: []linux.epoll_event, timeout: i32) usize { +pub fn epoll_wait(epfd: i32, events: []system.epoll_event, timeout: i32) usize { while (true) { // TODO get rid of the @intCast const rc = system.epoll_wait(epfd, events.ptr, @intCast(events.len), timeout); @@ -7142,13 +7142,13 @@ pub const PerfEventOpenError = error{ } || UnexpectedError; pub fn perf_event_open( - attr: *linux.perf_event_attr, + attr: *system.perf_event_attr, pid: pid_t, cpu: i32, group_fd: fd_t, flags: usize, ) PerfEventOpenError!fd_t { - const rc = linux.perf_event_open(attr, pid, cpu, group_fd, flags); + const rc = system.perf_event_open(attr, pid, cpu, group_fd, flags); switch (errno(rc)) { .SUCCESS => return @intCast(rc), .@"2BIG" => return error.TooBig, @@ -7171,6 +7171,8 @@ pub fn perf_event_open( } } +pub const TFD = system.TFD; + pub const TimerFdCreateError = error{ AccessDenied, ProcessFdQuotaExceeded, @@ -7182,8 +7184,8 @@ pub const TimerFdCreateError = error{ pub const TimerFdGetError = error{InvalidHandle} || UnexpectedError; pub const TimerFdSetError = TimerFdGetError || error{Canceled}; -pub fn timerfd_create(clokid: i32, flags: linux.TFD) TimerFdCreateError!fd_t { - const rc = linux.timerfd_create(clokid, flags); +pub fn timerfd_create(clokid: i32, flags: system.TFD) TimerFdCreateError!fd_t { + const rc = system.timerfd_create(clokid, @bitCast(flags)); return switch (errno(rc)) { .SUCCESS => @intCast(rc), .INVAL => unreachable, @@ -7196,13 +7198,15 @@ pub fn timerfd_create(clokid: i32, flags: linux.TFD) TimerFdCreateError!fd_t { }; } +pub const itimerspec = system.itimerspec; + pub fn timerfd_settime( fd: i32, - flags: linux.TFD.TIMER, - new_value: *const linux.itimerspec, - old_value: ?*linux.itimerspec, + flags: system.TFD.TIMER, + new_value: *const itimerspec, + old_value: ?*itimerspec, ) TimerFdSetError!void { - const rc = linux.timerfd_settime(fd, flags, new_value, old_value); + const rc = system.timerfd_settime(fd, @bitCast(flags), new_value, old_value); return switch (errno(rc)) { .SUCCESS => {}, .BADF => error.InvalidHandle, @@ -7213,9 +7217,9 @@ pub fn timerfd_settime( }; } -pub fn timerfd_gettime(fd: i32) TimerFdGetError!linux.itimerspec { - var curr_value: linux.itimerspec = undefined; - const rc = linux.timerfd_gettime(fd, &curr_value); +pub fn timerfd_gettime(fd: i32) TimerFdGetError!itimerspec { + var curr_value: itimerspec = undefined; + const rc = system.timerfd_gettime(fd, &curr_value); return switch (errno(rc)) { .SUCCESS => return curr_value, .BADF => error.InvalidHandle,