[libcxx-commits] [libcxx] edf9439 - [libcxx] Support for using timespec_get (#117362)

via libcxx-commits libcxx-commits at lists.llvm.org
Tue Dec 17 08:17:02 PST 2024


Author: Petr Hosek
Date: 2024-12-17T08:16:55-08:00
New Revision: edf9439e00971b55bae19e40ef6a8e132645a56a

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

LOG: [libcxx] Support for using timespec_get (#117362)

clock_gettime is a POSIX API that may not be available on platforms like
baremetal; timespec_get is the C11 equivalent. This change adds support
for using timespec_get instead of clock_gettime to improve compatibility
with non-POSIX platforms. For now, this is only enabled with LLVM libc
which implemented timespec_get in #116102, but in the future this can be
expanded to other platforms.

Related to #84879.

Added: 
    

Modified: 
    clang/cmake/caches/Fuchsia-stage2.cmake
    libcxx/src/chrono.cpp
    libcxx/src/filesystem/filesystem_clock.cpp

Removed: 
    


################################################################################
diff  --git a/clang/cmake/caches/Fuchsia-stage2.cmake b/clang/cmake/caches/Fuchsia-stage2.cmake
index 8e161f868d4af2..e799900094df37 100644
--- a/clang/cmake/caches/Fuchsia-stage2.cmake
+++ b/clang/cmake/caches/Fuchsia-stage2.cmake
@@ -333,7 +333,7 @@ foreach(target armv6m-none-eabi;armv7m-none-eabi;armv8m.main-none-eabi;armv8.1m.
   foreach(lang C;CXX;ASM)
     # TODO: The preprocessor defines workaround various issues in libc and libc++ integration.
     # These should be addressed and removed over time.
-    set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "--target=${target} -Wno-atomic-alignment \"-Dvfprintf(stream, format, vlist)=vprintf(format, vlist)\" \"-Dfprintf(stream, format, ...)=printf(format)\" \"-Dgettimeofday(tv, tz)\" -D_LIBCPP_PRINT=1")
+    set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "--target=${target} -Wno-atomic-alignment \"-Dvfprintf(stream, format, vlist)=vprintf(format, vlist)\" \"-Dfprintf(stream, format, ...)=printf(format)\" -D_LIBCPP_PRINT=1")
     if(NOT ${target} STREQUAL "aarch64-none-elf")
       set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "${RUNTIMES_${target}_CMAKE_${lang}_local_flags} -mthumb")
     endif()
@@ -394,7 +394,7 @@ foreach(target riscv32-unknown-elf)
   foreach(lang C;CXX;ASM)
     # TODO: The preprocessor defines workaround various issues in libc and libc++ integration.
     # These should be addressed and removed over time.
-    set(RUNTIMES_${target}_CMAKE_${lang}_FLAGS "--target=${target} -march=rv32imafc -mabi=ilp32f -Wno-atomic-alignment \"-Dvfprintf(stream, format, vlist)=vprintf(format, vlist)\" \"-Dfprintf(stream, format, ...)=printf(format)\" \"-Dgettimeofday(tv, tz)\" -D_LIBCPP_PRINT=1" CACHE STRING "")
+    set(RUNTIMES_${target}_CMAKE_${lang}_FLAGS "--target=${target} -march=rv32imafc -mabi=ilp32f -Wno-atomic-alignment \"-Dvfprintf(stream, format, vlist)=vprintf(format, vlist)\" \"-Dfprintf(stream, format, ...)=printf(format)\" -D_LIBCPP_PRINT=1" CACHE STRING "")
   endforeach()
   foreach(type SHARED;MODULE;EXE)
     set(RUNTIMES_${target}_CMAKE_${type}_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "")

diff  --git a/libcxx/src/chrono.cpp b/libcxx/src/chrono.cpp
index 35105693b9f900..dbc0f617b4fc66 100644
--- a/libcxx/src/chrono.cpp
+++ b/libcxx/src/chrono.cpp
@@ -31,6 +31,10 @@
 #  include <sys/time.h> // for gettimeofday and timeval
 #endif
 
+#if defined(__LLVM_LIBC__)
+#  define _LIBCPP_HAS_TIMESPEC_GET
+#endif
+
 // OpenBSD and GPU do not have a fully conformant suite of POSIX timers, but
 // it does have clock_gettime and CLOCK_MONOTONIC which is all we need.
 #if defined(__APPLE__) || defined(__gnu_hurd__) || defined(__OpenBSD__) || defined(__AMDGPU__) ||                      \
@@ -115,6 +119,15 @@ static system_clock::time_point __libcpp_system_clock_now() {
   return system_clock::time_point(duration_cast<system_clock::duration>(d - nt_to_unix_epoch));
 }
 
+#elif defined(_LIBCPP_HAS_TIMESPEC_GET)
+
+static system_clock::time_point __libcpp_system_clock_now() {
+  struct timespec ts;
+  if (timespec_get(&ts, TIME_UTC) != TIME_UTC)
+    __throw_system_error(errno, "timespec_get(TIME_UTC) failed");
+  return system_clock::time_point(seconds(ts.tv_sec) + microseconds(ts.tv_nsec / 1000));
+}
+
 #elif defined(_LIBCPP_HAS_CLOCK_GETTIME)
 
 static system_clock::time_point __libcpp_system_clock_now() {
@@ -216,6 +229,15 @@ static steady_clock::time_point __libcpp_steady_clock_now() noexcept {
   return steady_clock::time_point(nanoseconds(_zx_clock_get_monotonic()));
 }
 
+#  elif defined(_LIBCPP_HAS_TIMESPEC_GET)
+
+static steady_clock::time_point __libcpp_steady_clock_now() {
+  struct timespec ts;
+  if (timespec_get(&ts, TIME_MONOTONIC) != TIME_MONOTONIC)
+    __throw_system_error(errno, "timespec_get(TIME_MONOTONIC) failed");
+  return steady_clock::time_point(seconds(ts.tv_sec) + microseconds(ts.tv_nsec / 1000));
+}
+
 #  elif defined(_LIBCPP_HAS_CLOCK_GETTIME)
 
 static steady_clock::time_point __libcpp_steady_clock_now() {

diff  --git a/libcxx/src/filesystem/filesystem_clock.cpp b/libcxx/src/filesystem/filesystem_clock.cpp
index d174ecdc9e1060..e1f88707220187 100644
--- a/libcxx/src/filesystem/filesystem_clock.cpp
+++ b/libcxx/src/filesystem/filesystem_clock.cpp
@@ -30,6 +30,10 @@
 #  include <sys/time.h> // for gettimeofday and timeval
 #endif
 
+#if defined(__LLVM_LIBC__)
+#  define _LIBCPP_HAS_TIMESPEC_GET
+#endif
+
 #if defined(__APPLE__) || defined(__gnu_hurd__) || defined(__AMDGPU__) || defined(__NVPTX__) ||                        \
     (defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0)
 #  define _LIBCPP_HAS_CLOCK_GETTIME
@@ -50,6 +54,12 @@ _FilesystemClock::time_point _FilesystemClock::now() noexcept {
   GetSystemTimeAsFileTime(&time);
   detail::TimeSpec tp = detail::filetime_to_timespec(time);
   return time_point(__secs(tp.tv_sec) + chrono::duration_cast<duration>(__nsecs(tp.tv_nsec)));
+#elif defined(_LIBCPP_HAS_TIMESPEC_GET)
+  typedef chrono::duration<rep, nano> __nsecs;
+  struct timespec ts;
+  if (timespec_get(&ts, TIME_UTC) != TIME_UTC)
+    __throw_system_error(errno, "timespec_get(TIME_UTC) failed");
+  return time_point(__secs(ts.tv_sec) + chrono::duration_cast<duration>(__nsecs(ts.tv_nsec)));
 #elif defined(_LIBCPP_HAS_CLOCK_GETTIME)
   typedef chrono::duration<rep, nano> __nsecs;
   struct timespec tp;


        


More information about the libcxx-commits mailing list