diff --git a/lib/std/c/linux.zig b/lib/std/c/linux.zig index 6c3275274c64..397f0945bcf8 100644 --- a/lib/std/c/linux.zig +++ b/lib/std/c/linux.zig @@ -51,6 +51,7 @@ pub const Sigaction = linux.Sigaction; pub const T = linux.T; pub const TCP = linux.TCP; pub const TCSA = linux.TCSA; +pub const TFD = linux.TFD; pub const VDSO = linux.VDSO; pub const W = linux.W; pub const W_OK = linux.W_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,12 @@ pub const dirent64 = extern struct { type: u8, name: [256]u8, }; + +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..57eae4bbd66f 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,32 +7142,35 @@ 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); - switch (errno(rc)) { - .SUCCESS => return @intCast(rc), - .@"2BIG" => return error.TooBig, - .ACCES => return error.PermissionDenied, - .BADF => unreachable, // group_fd file descriptor is not valid. - .BUSY => return error.DeviceBusy, - .FAULT => unreachable, // Segmentation fault. - .INVAL => unreachable, // Bad attr settings. - .INTR => unreachable, // Mixed perf and ftrace handling for a uprobe. - .MFILE => return error.ProcessResources, - .NODEV => return error.EventRequiresUnsupportedCpuFeature, - .NOENT => unreachable, // Invalid type setting. - .NOSPC => return error.TooManyBreakpoints, - .NOSYS => return error.SampleStackNotSupported, - .OPNOTSUPP => return error.EventNotSupported, - .OVERFLOW => return error.SampleMaxStackOverflow, - .PERM => return error.PermissionDenied, - .SRCH => return error.ProcessNotFound, - else => |err| return unexpectedErrno(err), + if (native_os == .linux) { + // There is no syscall wrapper for this function exposed by libcs + const rc = linux.perf_event_open(attr, pid, cpu, group_fd, flags); + switch (errno(rc)) { + .SUCCESS => return @intCast(rc), + .@"2BIG" => return error.TooBig, + .ACCES => return error.PermissionDenied, + .BADF => unreachable, // group_fd file descriptor is not valid. + .BUSY => return error.DeviceBusy, + .FAULT => unreachable, // Segmentation fault. + .INVAL => unreachable, // Bad attr settings. + .INTR => unreachable, // Mixed perf and ftrace handling for a uprobe. + .MFILE => return error.ProcessResources, + .NODEV => return error.EventRequiresUnsupportedCpuFeature, + .NOENT => unreachable, // Invalid type setting. + .NOSPC => return error.TooManyBreakpoints, + .NOSYS => return error.SampleStackNotSupported, + .OPNOTSUPP => return error.EventNotSupported, + .OVERFLOW => return error.SampleMaxStackOverflow, + .PERM => return error.PermissionDenied, + .SRCH => return error.ProcessNotFound, + else => |err| return unexpectedErrno(err), + } } } @@ -7182,8 +7185,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, @@ -7198,11 +7201,11 @@ pub fn timerfd_create(clokid: i32, flags: linux.TFD) TimerFdCreateError!fd_t { 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 system.itimerspec, + old_value: ?*system.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 +7216,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!system.itimerspec { + var curr_value: system.itimerspec = undefined; + const rc = system.timerfd_gettime(fd, &curr_value); return switch (errno(rc)) { .SUCCESS => return curr_value, .BADF => error.InvalidHandle,