From a994303c8cfb98a9280c44756e5421e10fd1039f Mon Sep 17 00:00:00 2001 From: "Mikhail R. Gadelha" Date: Thu, 8 May 2025 11:28:08 -0300 Subject: [PATCH 1/2] [libc] Enable setitimer and getitimer functions on riscv These functions don't have a _time64 variant, so we can't use time_t directly (since our time_t is an uint64_t). The workaround is to use longs when doing the syscall and write back when necessary. --- libc/config/linux/riscv/entrypoints.txt | 4 ++-- libc/src/sys/time/linux/getitimer.cpp | 18 +++++++++++++++-- libc/src/sys/time/linux/setitimer.cpp | 26 +++++++++++++++++++++++-- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt index 30d9d00dfefc9..effcd45de79bc 100644 --- a/libc/config/linux/riscv/entrypoints.txt +++ b/libc/config/linux/riscv/entrypoints.txt @@ -371,8 +371,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.sys.uio.readv # sys/time.h entrypoints - # libc.src.sys.time.setitimer - # libc.src.sys.time.getitimer + libc.src.sys.time.setitimer + libc.src.sys.time.getitimer ) if(LLVM_LIBC_INCLUDE_SCUDO) diff --git a/libc/src/sys/time/linux/getitimer.cpp b/libc/src/sys/time/linux/getitimer.cpp index bbdbaa57dfd30..180e95bef7ace 100644 --- a/libc/src/sys/time/linux/getitimer.cpp +++ b/libc/src/sys/time/linux/getitimer.cpp @@ -16,8 +16,22 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, getitimer, (int which, struct itimerval *curr_value)) { - long ret = - LIBC_NAMESPACE::syscall_impl(SYS_getitimer, which, curr_value); + long ret = 0; + if constexpr (sizeof(time_t) > sizeof(long)) { + // There is no SYS_getitimer_time64 call, so we can't use time_t directly. + long curr_value32[4]; + ret = LIBC_NAMESPACE::syscall_impl(SYS_getitimer, which, curr_value32); + if (!ret) { + curr_value->it_interval.tv_sec = curr_value32[0]; + curr_value->it_interval.tv_usec = curr_value32[1]; + curr_value->it_value.tv_sec = curr_value32[2]; + curr_value->it_value.tv_usec = curr_value32[3]; + } + } else { + ret = + LIBC_NAMESPACE::syscall_impl(SYS_getitimer, which, curr_value); + } + // On failure, return -1 and set errno. if (ret < 0) { libc_errno = static_cast(-ret); diff --git a/libc/src/sys/time/linux/setitimer.cpp b/libc/src/sys/time/linux/setitimer.cpp index b50356004701d..def04a4740118 100644 --- a/libc/src/sys/time/linux/setitimer.cpp +++ b/libc/src/sys/time/linux/setitimer.cpp @@ -17,8 +17,30 @@ namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, setitimer, (int which, const struct itimerval *new_value, struct itimerval *old_value)) { - long ret = LIBC_NAMESPACE::syscall_impl(SYS_setitimer, which, new_value, - old_value); + long ret = 0; + if constexpr (sizeof(time_t) > sizeof(long)) { + // There is no SYS_setitimer_time64 call, so we can't use time_t directly, + // and need to convert it to long first. + long new_value32[4] = {static_cast(new_value->it_interval.tv_sec), + new_value->it_interval.tv_usec, + static_cast(new_value->it_value.tv_sec), + new_value->it_value.tv_usec}; + long old_value32[4]; + + ret = LIBC_NAMESPACE::syscall_impl(SYS_setitimer, which, new_value32, + old_value32); + + if (!ret && old_value) { + old_value->it_interval.tv_sec = old_value32[0]; + old_value->it_interval.tv_usec = old_value32[1]; + old_value->it_value.tv_sec = old_value32[2]; + old_value->it_value.tv_usec = old_value32[3]; + } + } else { + ret = LIBC_NAMESPACE::syscall_impl(SYS_setitimer, which, new_value, + old_value); + } + // On failure, return -1 and set errno. if (ret < 0) { libc_errno = static_cast(-ret); From 2bf2ceaa62a89114889e386838e024964af6be74 Mon Sep 17 00:00:00 2001 From: "Mikhail R. Gadelha" Date: Thu, 8 May 2025 21:49:41 -0300 Subject: [PATCH 2/2] Code style Signed-off-by: Mikhail R. Gadelha --- libc/src/sys/time/linux/getitimer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libc/src/sys/time/linux/getitimer.cpp b/libc/src/sys/time/linux/getitimer.cpp index 180e95bef7ace..fec06aa4086e9 100644 --- a/libc/src/sys/time/linux/getitimer.cpp +++ b/libc/src/sys/time/linux/getitimer.cpp @@ -20,7 +20,8 @@ LLVM_LIBC_FUNCTION(int, getitimer, (int which, struct itimerval *curr_value)) { if constexpr (sizeof(time_t) > sizeof(long)) { // There is no SYS_getitimer_time64 call, so we can't use time_t directly. long curr_value32[4]; - ret = LIBC_NAMESPACE::syscall_impl(SYS_getitimer, which, curr_value32); + ret = + LIBC_NAMESPACE::syscall_impl(SYS_getitimer, which, curr_value32); if (!ret) { curr_value->it_interval.tv_sec = curr_value32[0]; curr_value->it_interval.tv_usec = curr_value32[1]; @@ -28,8 +29,7 @@ LLVM_LIBC_FUNCTION(int, getitimer, (int which, struct itimerval *curr_value)) { curr_value->it_value.tv_usec = curr_value32[3]; } } else { - ret = - LIBC_NAMESPACE::syscall_impl(SYS_getitimer, which, curr_value); + ret = LIBC_NAMESPACE::syscall_impl(SYS_getitimer, which, curr_value); } // On failure, return -1 and set errno.