diff options
| author | flysand7 <yyakut.ac@gmail.com> | 2023-11-24 09:25:12 +1100 |
|---|---|---|
| committer | flysand7 <yyakut.ac@gmail.com> | 2023-11-24 09:39:36 +1100 |
| commit | 03282c1234ea24e772c61fcb7b1b0a80245f78d8 (patch) | |
| tree | 664333a09c03dfe99a348d7a1a43d594bf59f19b /core/sys/linux | |
| parent | 4e145cf69c151a87ad2f2a1e34bf96cf2a70b52e (diff) | |
[sys/linux]: Add epoll syscalls
Diffstat (limited to 'core/sys/linux')
| -rw-r--r-- | core/sys/linux/bits.odin | 31 | ||||
| -rw-r--r-- | core/sys/linux/sys.odin | 71 | ||||
| -rw-r--r-- | core/sys/linux/types.odin | 17 |
3 files changed, 109 insertions, 10 deletions
diff --git a/core/sys/linux/bits.odin b/core/sys/linux/bits.odin index fa2470c78..946f32928 100644 --- a/core/sys/linux/bits.odin +++ b/core/sys/linux/bits.odin @@ -1727,3 +1727,34 @@ Clock_Id :: enum { ITimer_Flags_Bits :: enum { ABSTIME = 1, } + +/* + Bits for epoll_create(2) flags. +*/ +EPoll_Flags_Bits :: enum { + FDCLOEXEC = 19, +} + +EPoll_Event_Kind :: enum u32 { + IN = 0x001, + PRI = 0x002, + OUT = 0x004, + RDNORM = 0x040, + RDBAND = 0x080, + WRNORM = 0x100, + WRBAND = 0x200, + MSG = 0x400, + ERR = 0x008, + HUP = 0x010, + RDHUP = 0x2000, + EXCLUSIVE = 1<<28, + WAKEUP = 1<<29, + ONESHOT = 1<<30, + ET = 1<<31, +} + +EPoll_Ctl_Opcode :: enum i32 { + ADD = 1, + DEL = 2, + MOD = 3, +} diff --git a/core/sys/linux/sys.odin b/core/sys/linux/sys.odin index 9ffca616c..d7aaed0b5 100644 --- a/core/sys/linux/sys.odin +++ b/core/sys/linux/sys.odin @@ -2304,11 +2304,22 @@ futex :: proc { // TODO(flysand): lookup_dcookie -// TODO(flysand): epoll_create - -// TODO(flysand): epoll_ctl_old - -// TODO(flysand): epoll_wait_old +/* + Open an epoll file descriptor. + + The `size` argument is ignored but must be greater than zero. + + Available since Linux 2.6. +*/ +epoll_create :: proc(size: i32 = 1) -> (Fd, Errno) { + when ODIN_ARCH != .arm64 { + ret := syscall(SYS_epoll_create) + return errno_unwrap(ret, Fd) + } else { + ret := syscall(SYS_epoll_create1, i32(0)) + return errno_unwrap(ret, Fd) + } +} // TODO(flysand): remap_file_pages @@ -2387,9 +2398,32 @@ exit_group :: proc "contextless" (code: i32) -> ! { unreachable() } -// TODO(flysand): epoll_wait +/* + Wait for an I/O event on an epoll file descriptor. + + `timeout` is specified in milliseconds. + + Available since Linux 2.6. +*/ +epoll_wait :: proc(epfd: Fd, events: [^]EPoll_Event, count: i32, timeout: i32) -> (i32, Errno) { + when ODIN_ARCH != .arm64 { + ret := syscall(SYS_epoll_wait, epfd, events, count, timeout) + return errno_unwrap(ret, i32) + } else { + // Convert milliseconds to nanosecond timespec + ret := syscall(SYS_epoll_pwait, epfd, events, count, timeout, nil) + return errno_unwrap(ret, i32) + } +} -// TODO(flysand): epoll_ctl +/* + Control interface for an epoll file descriptor. + Available since Linux 2.6. +*/ +epoll_ctl :: proc(epfd: Fd, op: EPoll_Ctl_Opcode, fd: Fd, event: ^EPoll_Event) -> (Errno) { + ret := syscall(SYS_epoll_ctl, epfd, op, fd, event) + return Errno(-ret) +} /* Send a signal to a specific thread in a thread group. @@ -2622,7 +2656,14 @@ utimensat :: proc "contextless" (dirfd: Fd, name: cstring, utimes: [^]Time_Spec, return Errno(-ret) } -// TODO(flysand): epoll_pwait +/* + Wait for an I/O event on an epoll file descriptor. + Available since Linux 2.6. +*/ +epoll_pwait :: proc(epfd: Fd, events: [^]EPoll_Event, count: i32, timeout: i32, sigmask: ^Sig_Set) -> (i32, Errno) { + ret := syscall(SYS_epoll_pwait, epfd, events, count, timeout, sigmask) + return errno_unwrap(ret, i32) +} // TODO(flysand): signalfd @@ -2642,7 +2683,10 @@ utimensat :: proc "contextless" (dirfd: Fd, name: cstring, utimes: [^]Time_Spec, // TODO(flysand): eventfd2 -// TODO(flysand): epoll_create1 +epoll_create1 :: proc(flags: EPoll_Flags) -> (Fd, Errno) { + ret := syscall(SYS_epoll_create1, transmute(i32) flags) + return errno_unwrap(ret, Fd) +} /* Adjust an existing file descriptor to point to the same file as `old`. @@ -2859,7 +2903,14 @@ faccessat2 :: proc "contextless" (dirfd: Fd, name: cstring, mode: Mode = F_OK, f // TODO(flysand): process_madvise -// TODO(flysand): epoll_pwait2 +/* + Wait for an I/O event on an epoll file descriptor. + Available since Linux 2.6. +*/ +epoll_pwait2 :: proc(epfd: Fd, events: [^]EPoll_Event, count: i32, timeout: ^Time_Spec, sigmask: ^Sig_Set) -> (i32, Errno) { + ret := syscall(SYS_epoll_pwait2, epfd, events, count, timeout, sigmask) + return errno_unwrap(ret, i32) +} // TODO(flysand): mount_setattr diff --git a/core/sys/linux/types.odin b/core/sys/linux/types.odin index 997c9592b..22d698353 100644 --- a/core/sys/linux/types.odin +++ b/core/sys/linux/types.odin @@ -1220,3 +1220,20 @@ PTrace_Note_Type :: enum { Flags for splice(2) and tee(2) syscalls. */ Splice_Flags :: bit_set[Splice_Flags_Bits; u32] + +/* + Flags for epoll_create(2) syscall. +*/ +EPoll_Flags :: bit_set[EPoll_Flags_Bits; i32] + +EPoll_Data :: struct #raw_union { + ptr: rawptr, + fd: Fd, + u32: u32, + u64: u64, +} + +EPoll_Event :: struct #packed { + events: EPoll_Event_Kind, + data: EPoll_Data, +} |