[libc-commits] [libc] 123bf08 - [libc] Unify gettime implementations (#65383)

via libc-commits libc-commits at lists.llvm.org
Fri Sep 8 09:41:33 PDT 2023


Author: Mikhail R. Gadelha
Date: 2023-09-08T12:41:29-04:00
New Revision: 123bf084029e4d35420a95e47ddd332d24c23a6d

URL: https://github.com/llvm/llvm-project/commit/123bf084029e4d35420a95e47ddd332d24c23a6d
DIFF: https://github.com/llvm/llvm-project/commit/123bf084029e4d35420a95e47ddd332d24c23a6d.diff

LOG: [libc] Unify gettime implementations (#65383)

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).

Added: 
    libc/src/time/linux/clockGetTimeImpl.h
    libc/src/time/linux/clock_gettime.cpp
    libc/src/time/linux/gettimeofday.cpp

Modified: 
    libc/src/time/CMakeLists.txt
    libc/src/time/linux/CMakeLists.txt
    libc/src/time/linux/clock.cpp
    libc/src/time/linux/time.cpp

Removed: 
    libc/src/time/clock_gettime.cpp
    libc/src/time/gettimeofday.cpp


################################################################################
diff  --git a/libc/src/time/CMakeLists.txt b/libc/src/time/CMakeLists.txt
index 5a0b3ab31cf0f88..210f3b23432b49f 100644
--- a/libc/src/time/CMakeLists.txt
+++ b/libc/src/time/CMakeLists.txt
@@ -35,19 +35,6 @@ add_entrypoint_object(
     libc.include.time
 )
 
-add_entrypoint_object(
-  clock_gettime
-  SRCS
-    clock_gettime.cpp
-  HDRS
-    clock_gettime.h
-  DEPENDS
-    libc.include.time
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
-    libc.src.errno.errno
-)
-
 add_entrypoint_object(
   
diff time
   SRCS
@@ -58,20 +45,6 @@ add_entrypoint_object(
     libc.include.time
 )
 
-add_entrypoint_object(
-  gettimeofday
-  SRCS
-    gettimeofday.cpp
-  HDRS
-    gettimeofday.h
-  DEPENDS
-    .clock_gettime
-    libc.include.time
-    libc.include.sys_syscall
-    libc.src.__support.OSUtil.osutil
-    libc.src.errno.errno
-)
-
 add_entrypoint_object(
   gmtime
   SRCS
@@ -126,3 +99,17 @@ add_entrypoint_object(
   DEPENDS
     .${LIBC_TARGET_OS}.nanosleep
 )
+
+add_entrypoint_object(
+  clock_gettime
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.clock_gettime
+)
+
+add_entrypoint_object(
+  gettimeofday
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.gettimeofday
+)

diff  --git a/libc/src/time/linux/CMakeLists.txt b/libc/src/time/linux/CMakeLists.txt
index 8b4976847f82af3..df79bf5986261cf 100644
--- a/libc/src/time/linux/CMakeLists.txt
+++ b/libc/src/time/linux/CMakeLists.txt
@@ -38,3 +38,29 @@ add_entrypoint_object(
     libc.src.__support.OSUtil.osutil
     libc.src.errno.errno
 )
+
+add_entrypoint_object(
+  clock_gettime
+  SRCS
+    clock_gettime.cpp
+  HDRS
+    ../clock_gettime.h
+  DEPENDS
+    libc.include.time
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
+)
+
+add_entrypoint_object(
+  gettimeofday
+  SRCS
+    gettimeofday.cpp
+  HDRS
+    ../gettimeofday.h
+  DEPENDS
+    libc.include.time
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
+)

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/clock_gettime.cpp b/libc/src/time/linux/clockGetTimeImpl.h
similarity index 63%
rename from libc/src/time/clock_gettime.cpp
rename to libc/src/time/linux/clockGetTimeImpl.h
index 94818c03768cc98..a5b7d659c7c14c2 100644
--- a/libc/src/time/clock_gettime.cpp
+++ b/libc/src/time/linux/clockGetTimeImpl.h
@@ -1,4 +1,4 @@
-//===---------- Linux implementation of the POSIX clock_gettime function --===//
+//===- Linux implementation of the POSIX clock_gettime function -*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,40 +6,42 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/time/clock_gettime.h"
+#ifndef LLVM_LIBC_SRC_TIME_LINUX_CLOCKGETTIMEIMPL_H
+#define LLVM_LIBC_SRC_TIME_LINUX_CLOCKGETTIMEIMPL_H
 
 #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
 #include "src/__support/common.h"
+#include "src/__support/error_or.h"
 #include "src/errno/libc_errno.h"
 
 #include <sys/syscall.h> // For syscall numbers.
 #include <time.h>
 
 namespace __llvm_libc {
+namespace internal {
 
-// TODO(michaelrj): Move this into time/linux with the other syscalls.
-LLVM_LIBC_FUNCTION(int, clock_gettime,
-                   (clockid_t clockid, struct timespec *tp)) {
+LIBC_INLINE ErrorOr<int> clock_gettimeimpl(clockid_t clockid,
+                                           struct timespec *ts) {
 #if SYS_clock_gettime
   int ret = __llvm_libc::syscall_impl<int>(SYS_clock_gettime,
                                            static_cast<long>(clockid),
-                                           reinterpret_cast<long>(tp));
+                                           reinterpret_cast<long>(ts));
 #elif defined(SYS_clock_gettime64)
+  struct timespec64 ts64;
   int ret = __llvm_libc::syscall_impl<int>(SYS_clock_gettime64,
                                            static_cast<long>(clockid),
-                                           reinterpret_cast<long>(tp));
+                                           reinterpret_cast<long>(&ts64));
+  ts->tv_sec = static_cast<time_t>(ts64.tv_sec);
+  ts->tv_nsec = static_cast<long>(ts64.tv_nsec);
 #else
 #error "SYS_clock_gettime and SYS_clock_gettime64 syscalls not available."
 #endif
-
-  // A negative return value indicates an error with the magnitude of the
-  // value being the error code.
-  if (ret < 0) {
-    libc_errno = -ret;
-    return -1;
-  }
-
-  return 0;
+  if (ret < 0)
+    return Error(-ret);
+  return ret;
 }
 
+} // namespace internal
 } // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_TIME_LINUX_CLOCKGETTIMEIMPL_H

diff  --git a/libc/src/time/linux/clock_gettime.cpp b/libc/src/time/linux/clock_gettime.cpp
new file mode 100644
index 000000000000000..33ec04eb352743e
--- /dev/null
+++ b/libc/src/time/linux/clock_gettime.cpp
@@ -0,0 +1,35 @@
+//===---------- Linux implementation of the POSIX clock_gettime function --===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/time/clock_gettime.h"
+
+#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>
+
+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 *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 (!result.has_value()) {
+    libc_errno = result.error();
+    return -1;
+  }
+  return 0;
+}
+
+} // namespace __llvm_libc

diff  --git a/libc/src/time/gettimeofday.cpp b/libc/src/time/linux/gettimeofday.cpp
similarity index 58%
rename from libc/src/time/gettimeofday.cpp
rename to libc/src/time/linux/gettimeofday.cpp
index 8d44e630cc13b32..2df6429974164a9 100644
--- a/libc/src/time/gettimeofday.cpp
+++ b/libc/src/time/linux/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/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