[libc-commits] [libc] [libc] implement clock_gettime using vDSO (PR #108458)

Schrodinger ZHU Yifan via libc-commits libc-commits at lists.llvm.org
Fri Sep 13 07:48:43 PDT 2024


https://github.com/SchrodingerZhu updated https://github.com/llvm/llvm-project/pull/108458

>From 8d419972fc1cb717084f51a20dd4cee22cdefadf Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Thu, 12 Sep 2024 17:55:03 -0400
Subject: [PATCH 1/2] [libc] implement clock_gettime using vDSO

---
 libc/src/__support/macros/optimization.h      | 7 ++++---
 libc/src/__support/time/linux/CMakeLists.txt  | 1 +
 libc/src/__support/time/linux/clock_gettime.h | 9 +++++++++
 3 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/libc/src/__support/macros/optimization.h b/libc/src/__support/macros/optimization.h
index 5ffd474d35c54d..af9954151ed88c 100644
--- a/libc/src/__support/macros/optimization.h
+++ b/libc/src/__support/macros/optimization.h
@@ -10,7 +10,7 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_OPTIMIZATION_H
 #define LLVM_LIBC_SRC___SUPPORT_MACROS_OPTIMIZATION_H
 
-#include "src/__support/macros/attributes.h"          // LIBC_INLINE
+#include "src/__support/macros/attributes.h" // LIBC_INLINE
 #include "src/__support/macros/config.h"
 #include "src/__support/macros/properties/compiler.h" // LIBC_COMPILER_IS_CLANG
 
@@ -24,9 +24,10 @@ LIBC_INLINE constexpr bool expects_bool_condition(T value, T expected) {
 }
 } // namespace details
 } // namespace LIBC_NAMESPACE_DECL
-#define LIBC_LIKELY(x) LIBC_NAMESPACE::details::expects_bool_condition(x, true)
+#define LIBC_LIKELY(x)                                                         \
+  LIBC_NAMESPACE::details::expects_bool_condition(!!(x), true)
 #define LIBC_UNLIKELY(x)                                                       \
-  LIBC_NAMESPACE::details::expects_bool_condition(x, false)
+  LIBC_NAMESPACE::details::expects_bool_condition(!!(x), false)
 
 #if defined(LIBC_COMPILER_IS_CLANG)
 #define LIBC_LOOP_NOUNROLL _Pragma("nounroll")
diff --git a/libc/src/__support/time/linux/CMakeLists.txt b/libc/src/__support/time/linux/CMakeLists.txt
index 1b41c7cb0a98a9..4297a029866685 100644
--- a/libc/src/__support/time/linux/CMakeLists.txt
+++ b/libc/src/__support/time/linux/CMakeLists.txt
@@ -9,6 +9,7 @@ add_header_library(
     libc.src.__support.common
     libc.src.__support.error_or
     libc.src.__support.OSUtil.osutil
+    libc.src.__support.OSUtil.vdso
 )
 
 add_header_library(
diff --git a/libc/src/__support/time/linux/clock_gettime.h b/libc/src/__support/time/linux/clock_gettime.h
index eca1ba70de5924..71f77594352613 100644
--- a/libc/src/__support/time/linux/clock_gettime.h
+++ b/libc/src/__support/time/linux/clock_gettime.h
@@ -11,6 +11,8 @@
 
 #include "hdr/types/clockid_t.h"
 #include "hdr/types/struct_timespec.h"
+#include "src/__support/OSUtil/linux/vdso.h"
+#include "src/__support/OSUtil/linux/x86_64/vdso.h"
 #include "src/__support/OSUtil/syscall.h"
 #include "src/__support/common.h"
 #include "src/__support/error_or.h"
@@ -20,11 +22,18 @@
 namespace LIBC_NAMESPACE_DECL {
 namespace internal {
 LIBC_INLINE ErrorOr<int> clock_gettime(clockid_t clockid, timespec *ts) {
+  using namespace vdso;
 #if SYS_clock_gettime
+  TypedSymbol<VDSOSym::ClockGetTime> clock_gettime;
+  if (LIBC_LIKELY(clock_gettime))
+    return clock_gettime(clockid, ts);
   int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_gettime,
                                               static_cast<long>(clockid),
                                               reinterpret_cast<long>(ts));
 #elif defined(SYS_clock_gettime64)
+  TypedSymbol<VDSOSym::ClockGetTime64> clock_gettime64;
+  if (LIBC_LIKELY(clock_gettime64))
+    return clock_gettime64(clockid, ts);
   static_assert(
       sizeof(time_t) == sizeof(int64_t),
       "SYS_clock_gettime64 requires struct timespec with 64-bit members.");

>From 043dae517043eaa029eb21c6a8a2ace543c558d8 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Fri, 13 Sep 2024 10:48:25 -0400
Subject: [PATCH 2/2] fix

---
 libc/src/__support/macros/optimization.h      |  7 ++--
 libc/src/__support/time/linux/clock_gettime.h | 38 ++++++++++++-------
 2 files changed, 28 insertions(+), 17 deletions(-)

diff --git a/libc/src/__support/macros/optimization.h b/libc/src/__support/macros/optimization.h
index af9954151ed88c..5ffd474d35c54d 100644
--- a/libc/src/__support/macros/optimization.h
+++ b/libc/src/__support/macros/optimization.h
@@ -10,7 +10,7 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_OPTIMIZATION_H
 #define LLVM_LIBC_SRC___SUPPORT_MACROS_OPTIMIZATION_H
 
-#include "src/__support/macros/attributes.h" // LIBC_INLINE
+#include "src/__support/macros/attributes.h"          // LIBC_INLINE
 #include "src/__support/macros/config.h"
 #include "src/__support/macros/properties/compiler.h" // LIBC_COMPILER_IS_CLANG
 
@@ -24,10 +24,9 @@ LIBC_INLINE constexpr bool expects_bool_condition(T value, T expected) {
 }
 } // namespace details
 } // namespace LIBC_NAMESPACE_DECL
-#define LIBC_LIKELY(x)                                                         \
-  LIBC_NAMESPACE::details::expects_bool_condition(!!(x), true)
+#define LIBC_LIKELY(x) LIBC_NAMESPACE::details::expects_bool_condition(x, true)
 #define LIBC_UNLIKELY(x)                                                       \
-  LIBC_NAMESPACE::details::expects_bool_condition(!!(x), false)
+  LIBC_NAMESPACE::details::expects_bool_condition(x, false)
 
 #if defined(LIBC_COMPILER_IS_CLANG)
 #define LIBC_LOOP_NOUNROLL _Pragma("nounroll")
diff --git a/libc/src/__support/time/linux/clock_gettime.h b/libc/src/__support/time/linux/clock_gettime.h
index 71f77594352613..517cca91391a74 100644
--- a/libc/src/__support/time/linux/clock_gettime.h
+++ b/libc/src/__support/time/linux/clock_gettime.h
@@ -12,34 +12,46 @@
 #include "hdr/types/clockid_t.h"
 #include "hdr/types/struct_timespec.h"
 #include "src/__support/OSUtil/linux/vdso.h"
-#include "src/__support/OSUtil/linux/x86_64/vdso.h"
 #include "src/__support/OSUtil/syscall.h"
 #include "src/__support/common.h"
 #include "src/__support/error_or.h"
 #include "src/__support/macros/config.h"
 #include <sys/syscall.h>
 
+#if defined(SYS_clock_gettime64)
+#include <linux/time_types.h>
+#endif
+
 namespace LIBC_NAMESPACE_DECL {
 namespace internal {
 LIBC_INLINE ErrorOr<int> clock_gettime(clockid_t clockid, timespec *ts) {
   using namespace vdso;
-#if SYS_clock_gettime
+  int ret;
+#if defined(SYS_clock_gettime)
   TypedSymbol<VDSOSym::ClockGetTime> clock_gettime;
-  if (LIBC_LIKELY(clock_gettime))
-    return clock_gettime(clockid, ts);
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_gettime,
-                                              static_cast<long>(clockid),
-                                              reinterpret_cast<long>(ts));
+  if (LIBC_LIKELY(clock_gettime != nullptr))
+    ret = clock_gettime(clockid, ts);
+  else
+    ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_gettime,
+                                            static_cast<long>(clockid),
+                                            reinterpret_cast<long>(ts));
 #elif defined(SYS_clock_gettime64)
-  TypedSymbol<VDSOSym::ClockGetTime64> clock_gettime64;
-  if (LIBC_LIKELY(clock_gettime64))
-    return clock_gettime64(clockid, ts);
   static_assert(
       sizeof(time_t) == sizeof(int64_t),
       "SYS_clock_gettime64 requires struct timespec with 64-bit members.");
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_gettime64,
-                                              static_cast<long>(clockid),
-                                              reinterpret_cast<long>(ts));
+
+  TypedSymbol<VDSOSym::ClockGetTime64> clock_gettime64;
+  __kernel_timespec ts64{};
+  if (LIBC_LIKELY(clock_gettime64 != nullptr))
+    ret = clock_gettime64(clockid, &ts64);
+  else
+    ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_gettime64,
+                                            static_cast<long>(clockid),
+                                            reinterpret_cast<long>(&ts64));
+  if (ret == 0) {
+    ts->tv_sec = static_cast<decltype(ts->tv_sec)>(ts64.tv_sec);
+    ts->tv_nsec = static_cast<decltype(ts->tv_nsec)>(ts64.tv_nsec);
+  }
 #else
 #error "SYS_clock_gettime and SYS_clock_gettime64 syscalls not available."
 #endif



More information about the libc-commits mailing list