[libc-commits] [libc] [libc] Unify gettime implmenetations (PR #65383)

Mikhail R. Gadelha via libc-commits libc-commits at lists.llvm.org
Tue Sep 5 11:24:40 PDT 2023


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

>From fc68eebf828921495e85a1e462e488907b3f46eb Mon Sep 17 00:00:00 2001
From: "Mikhail R. Gadelha" <mikhail at igalia.com>
Date: Mon, 4 Sep 2023 11:45:33 -0300
Subject: [PATCH] [libc] Unify gettime implmenetations

Similar to D159208, this patch unifies the calls to a syscall, in this
patch it is the syscall SYS_clock_gettime/SYS_clock_gettime64.

This patch also fixes calls to SYS_clock_gettime64 by creating a timespec64
object, passing it to the syscall and rewriting the timespec given by
the caller with timespec64 object's contents. This fixes cases where
timespec has a 4 bytes long time_t member, but SYS_clock_gettime is not
available (e.g., rv32).
---
 libc/src/time/clock_gettime.cpp | 20 +++++---------------
 libc/src/time/gettimeofday.cpp  | 26 ++++++++++----------------
 libc/src/time/linux/clock.cpp   | 18 +++++-------------
 libc/src/time/linux/time.cpp    | 15 ++++-----------
 4 files changed, 24 insertions(+), 55 deletions(-)

diff --git a/libc/src/time/clock_gettime.cpp b/libc/src/time/clock_gettime.cpp
index 94818c03768cc98..33ec04eb352743e 100644
--- a/libc/src/time/clock_gettime.cpp
+++ b/libc/src/time/clock_gettime.cpp
@@ -11,6 +11,7 @@
 #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
 #include "src/__support/common.h"
 #include "src/errno/libc_errno.h"
+#include "src/time/linux/clockGetTimeImpl.h"
 
 #include <sys/syscall.h> // For syscall numbers.
 #include <time.h>
@@ -19,26 +20,15 @@ namespace __llvm_libc {
 
 // TODO(michaelrj): Move this into time/linux with the other syscalls.
 LLVM_LIBC_FUNCTION(int, clock_gettime,
-                   (clockid_t clockid, struct timespec *tp)) {
-#if SYS_clock_gettime
-  int ret = __llvm_libc::syscall_impl<int>(SYS_clock_gettime,
-                                           static_cast<long>(clockid),
-                                           reinterpret_cast<long>(tp));
-#elif defined(SYS_clock_gettime64)
-  int ret = __llvm_libc::syscall_impl<int>(SYS_clock_gettime64,
-                                           static_cast<long>(clockid),
-                                           reinterpret_cast<long>(tp));
-#else
-#error "SYS_clock_gettime and SYS_clock_gettime64 syscalls not available."
-#endif
+                   (clockid_t clockid, struct timespec *ts)) {
+  auto result = internal::clock_gettimeimpl(clockid, ts);
 
   // A negative return value indicates an error with the magnitude of the
   // value being the error code.
-  if (ret < 0) {
-    libc_errno = -ret;
+  if (!result.has_value()) {
+    libc_errno = result.error();
     return -1;
   }
-
   return 0;
 }
 
diff --git a/libc/src/time/gettimeofday.cpp b/libc/src/time/gettimeofday.cpp
index 8d44e630cc13b32..2df6429974164a9 100644
--- a/libc/src/time/gettimeofday.cpp
+++ b/libc/src/time/gettimeofday.cpp
@@ -11,6 +11,7 @@
 #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
 #include "src/__support/common.h"
 #include "src/errno/libc_errno.h"
+#include "src/time/linux/clockGetTimeImpl.h"
 
 #include <sys/syscall.h> // For syscall numbers.
 
@@ -21,26 +22,19 @@ LLVM_LIBC_FUNCTION(int, gettimeofday,
                    (struct timeval * tv, [[maybe_unused]] void *unused)) {
   if (tv == nullptr)
     return 0;
-  struct timespec tp;
-#if SYS_clock_gettime
-  int ret = __llvm_libc::syscall_impl<int>(SYS_clock_gettime,
-                                           static_cast<long>(CLOCK_REALTIME),
-                                           reinterpret_cast<long>(&tp));
-#elif defined(SYS_clock_gettime64)
-  int ret = __llvm_libc::syscall_impl<int>(SYS_clock_gettime64,
-                                           static_cast<long>(CLOCK_REALTIME),
-                                           reinterpret_cast<long>(&tp));
-#else
-#error "SYS_clock_gettime and SYS_clock_gettime64 syscalls not available."
-#endif
+
+  struct timespec ts;
+  auto result = internal::clock_gettimeimpl(CLOCK_REALTIME, &ts);
+
   // A negative return value indicates an error with the magnitude of the
   // value being the error code.
-  if (ret < 0) {
-    libc_errno = -ret;
+  if (!result.has_value()) {
+    libc_errno = result.error();
     return -1;
   }
-  tv->tv_sec = tp.tv_sec;
-  tv->tv_usec = static_cast<suseconds_t>(tp.tv_nsec / 1000);
+
+  tv->tv_sec = ts.tv_sec;
+  tv->tv_usec = static_cast<suseconds_t>(ts.tv_nsec / 1000);
   return 0;
 }
 
diff --git a/libc/src/time/linux/clock.cpp b/libc/src/time/linux/clock.cpp
index 2b19f8e9c54cea7..cf27f5c2995712a 100644
--- a/libc/src/time/linux/clock.cpp
+++ b/libc/src/time/linux/clock.cpp
@@ -12,6 +12,7 @@
 #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
 #include "src/__support/common.h"
 #include "src/errno/libc_errno.h"
+#include "src/time/linux/clockGetTimeImpl.h"
 
 #include <sys/syscall.h> // For syscall numbers.
 #include <time.h>
@@ -20,19 +21,10 @@ namespace __llvm_libc {
 
 LLVM_LIBC_FUNCTION(clock_t, clock, ()) {
   struct timespec ts;
-#if SYS_clock_gettime
-  int ret = __llvm_libc::syscall_impl<int>(
-      SYS_clock_gettime, CLOCK_PROCESS_CPUTIME_ID, reinterpret_cast<long>(&ts));
-#elif defined(SYS_clock_gettime64)
-  int ret = __llvm_libc::syscall_impl<int>(SYS_clock_gettime64,
-                                           CLOCK_PROCESS_CPUTIME_ID,
-                                           reinterpret_cast<long>(&ts));
-#else
-#error "SYS_clock_gettime and SYS_clock_gettime64 syscalls not available."
-#endif
-  if (ret < 0) {
-    libc_errno = -ret;
-    return clock_t(-1);
+  auto result = internal::clock_gettimeimpl(CLOCK_PROCESS_CPUTIME_ID, &ts);
+  if (!result.has_value()) {
+    libc_errno = result.error();
+    return -1;
   }
 
   // The above syscall gets the CPU time in seconds plus nanoseconds.
diff --git a/libc/src/time/linux/time.cpp b/libc/src/time/linux/time.cpp
index 34cca42adf5baf4..4dbcabc8963510a 100644
--- a/libc/src/time/linux/time.cpp
+++ b/libc/src/time/linux/time.cpp
@@ -11,6 +11,7 @@
 #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
 #include "src/__support/common.h"
 #include "src/errno/libc_errno.h"
+#include "src/time/linux/clockGetTimeImpl.h"
 
 #include <sys/syscall.h> // For syscall numbers.
 #include <time.h>
@@ -20,17 +21,9 @@ namespace __llvm_libc {
 LLVM_LIBC_FUNCTION(time_t, time, (time_t * tp)) {
   // TODO: Use the Linux VDSO to fetch the time and avoid the syscall.
   struct timespec ts;
-#if SYS_clock_gettime
-  int ret = __llvm_libc::syscall_impl<int>(SYS_clock_gettime, CLOCK_REALTIME,
-                                           reinterpret_cast<long>(&ts));
-#elif defined(SYS_clock_gettime64)
-  int ret = __llvm_libc::syscall_impl<int>(SYS_clock_gettime64, CLOCK_REALTIME,
-                                           reinterpret_cast<long>(&ts));
-#else
-#error "SYS_clock_gettime and SYS_clock_gettime64 syscalls not available."
-#endif
-  if (ret < 0) {
-    libc_errno = -ret;
+  auto result = internal::clock_gettimeimpl(CLOCK_REALTIME, &ts);
+  if (!result.has_value()) {
+    libc_errno = result.error();
     return -1;
   }
 



More information about the libc-commits mailing list