[libc-commits] [libc] [libc] Enable setitimer and getitimer functions on riscv (PR #139182)

Mikhail R. Gadelha via libc-commits libc-commits at lists.llvm.org
Thu May 8 17:49:55 PDT 2025


https://github.com/mikhailramalho updated https://github.com/llvm/llvm-project/pull/139182

>From a994303c8cfb98a9280c44756e5421e10fd1039f Mon Sep 17 00:00:00 2001
From: "Mikhail R. Gadelha" <mikhail at igalia.com>
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<long>(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<long>(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<long>(SYS_getitimer, which, curr_value);
+  }
+
   // On failure, return -1 and set errno.
   if (ret < 0) {
     libc_errno = static_cast<int>(-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<long>(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<long>(new_value->it_interval.tv_sec),
+                           new_value->it_interval.tv_usec,
+                           static_cast<long>(new_value->it_value.tv_sec),
+                           new_value->it_value.tv_usec};
+    long old_value32[4];
+
+    ret = LIBC_NAMESPACE::syscall_impl<long>(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<long>(SYS_setitimer, which, new_value,
+                                             old_value);
+  }
+
   // On failure, return -1 and set errno.
   if (ret < 0) {
     libc_errno = static_cast<int>(-ret);

>From 2bf2ceaa62a89114889e386838e024964af6be74 Mon Sep 17 00:00:00 2001
From: "Mikhail R. Gadelha" <mikhail at igalia.com>
Date: Thu, 8 May 2025 21:49:41 -0300
Subject: [PATCH 2/2] Code style

Signed-off-by: Mikhail R. Gadelha <mikhail at igalia.com>
---
 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<long>(SYS_getitimer, which, curr_value32);
+    ret =
+        LIBC_NAMESPACE::syscall_impl<long>(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<long>(SYS_getitimer, which, curr_value);
+    ret = LIBC_NAMESPACE::syscall_impl<long>(SYS_getitimer, which, curr_value);
   }
 
   // On failure, return -1 and set errno.



More information about the libc-commits mailing list