aboutsummaryrefslogtreecommitdiff
path: root/libcxx/src
diff options
context:
space:
mode:
authorPetr Hosek <phosek@google.com>2024-12-17 08:16:55 -0800
committerGitHub <noreply@github.com>2024-12-17 08:16:55 -0800
commitedf9439e00971b55bae19e40ef6a8e132645a56a (patch)
tree57751d1995c6b05245ac546764ddcfedd65bbb25 /libcxx/src
parent62bd10f7d18ca6f544286767cae2c9026d493888 (diff)
downloadllvm-edf9439e00971b55bae19e40ef6a8e132645a56a.zip
llvm-edf9439e00971b55bae19e40ef6a8e132645a56a.tar.gz
llvm-edf9439e00971b55bae19e40ef6a8e132645a56a.tar.bz2
[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.
Diffstat (limited to 'libcxx/src')
-rw-r--r--libcxx/src/chrono.cpp22
-rw-r--r--libcxx/src/filesystem/filesystem_clock.cpp10
2 files changed, 32 insertions, 0 deletions
diff --git a/libcxx/src/chrono.cpp b/libcxx/src/chrono.cpp
index 3510569..dbc0f61 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 d174ecd..e1f8870 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;