Skip to content

Commit edf9439

Browse files
authored
[libcxx] Support for using timespec_get (llvm#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 llvm#116102, but in the future this can be expanded to other platforms. Related to llvm#84879.
1 parent 62bd10f commit edf9439

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

clang/cmake/caches/Fuchsia-stage2.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ foreach(target armv6m-none-eabi;armv7m-none-eabi;armv8m.main-none-eabi;armv8.1m.
333333
foreach(lang C;CXX;ASM)
334334
# TODO: The preprocessor defines workaround various issues in libc and libc++ integration.
335335
# These should be addressed and removed over time.
336-
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")
336+
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")
337337
if(NOT ${target} STREQUAL "aarch64-none-elf")
338338
set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "${RUNTIMES_${target}_CMAKE_${lang}_local_flags} -mthumb")
339339
endif()
@@ -394,7 +394,7 @@ foreach(target riscv32-unknown-elf)
394394
foreach(lang C;CXX;ASM)
395395
# TODO: The preprocessor defines workaround various issues in libc and libc++ integration.
396396
# These should be addressed and removed over time.
397-
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 "")
397+
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 "")
398398
endforeach()
399399
foreach(type SHARED;MODULE;EXE)
400400
set(RUNTIMES_${target}_CMAKE_${type}_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "")

libcxx/src/chrono.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@
3131
# include <sys/time.h> // for gettimeofday and timeval
3232
#endif
3333

34+
#if defined(__LLVM_LIBC__)
35+
# define _LIBCPP_HAS_TIMESPEC_GET
36+
#endif
37+
3438
// OpenBSD and GPU do not have a fully conformant suite of POSIX timers, but
3539
// it does have clock_gettime and CLOCK_MONOTONIC which is all we need.
3640
#if defined(__APPLE__) || defined(__gnu_hurd__) || defined(__OpenBSD__) || defined(__AMDGPU__) || \
@@ -115,6 +119,15 @@ static system_clock::time_point __libcpp_system_clock_now() {
115119
return system_clock::time_point(duration_cast<system_clock::duration>(d - nt_to_unix_epoch));
116120
}
117121

122+
#elif defined(_LIBCPP_HAS_TIMESPEC_GET)
123+
124+
static system_clock::time_point __libcpp_system_clock_now() {
125+
struct timespec ts;
126+
if (timespec_get(&ts, TIME_UTC) != TIME_UTC)
127+
__throw_system_error(errno, "timespec_get(TIME_UTC) failed");
128+
return system_clock::time_point(seconds(ts.tv_sec) + microseconds(ts.tv_nsec / 1000));
129+
}
130+
118131
#elif defined(_LIBCPP_HAS_CLOCK_GETTIME)
119132

120133
static system_clock::time_point __libcpp_system_clock_now() {
@@ -216,6 +229,15 @@ static steady_clock::time_point __libcpp_steady_clock_now() noexcept {
216229
return steady_clock::time_point(nanoseconds(_zx_clock_get_monotonic()));
217230
}
218231

232+
# elif defined(_LIBCPP_HAS_TIMESPEC_GET)
233+
234+
static steady_clock::time_point __libcpp_steady_clock_now() {
235+
struct timespec ts;
236+
if (timespec_get(&ts, TIME_MONOTONIC) != TIME_MONOTONIC)
237+
__throw_system_error(errno, "timespec_get(TIME_MONOTONIC) failed");
238+
return steady_clock::time_point(seconds(ts.tv_sec) + microseconds(ts.tv_nsec / 1000));
239+
}
240+
219241
# elif defined(_LIBCPP_HAS_CLOCK_GETTIME)
220242

221243
static steady_clock::time_point __libcpp_steady_clock_now() {

libcxx/src/filesystem/filesystem_clock.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
# include <sys/time.h> // for gettimeofday and timeval
3131
#endif
3232

33+
#if defined(__LLVM_LIBC__)
34+
# define _LIBCPP_HAS_TIMESPEC_GET
35+
#endif
36+
3337
#if defined(__APPLE__) || defined(__gnu_hurd__) || defined(__AMDGPU__) || defined(__NVPTX__) || \
3438
(defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0)
3539
# define _LIBCPP_HAS_CLOCK_GETTIME
@@ -50,6 +54,12 @@ _FilesystemClock::time_point _FilesystemClock::now() noexcept {
5054
GetSystemTimeAsFileTime(&time);
5155
detail::TimeSpec tp = detail::filetime_to_timespec(time);
5256
return time_point(__secs(tp.tv_sec) + chrono::duration_cast<duration>(__nsecs(tp.tv_nsec)));
57+
#elif defined(_LIBCPP_HAS_TIMESPEC_GET)
58+
typedef chrono::duration<rep, nano> __nsecs;
59+
struct timespec ts;
60+
if (timespec_get(&ts, TIME_UTC) != TIME_UTC)
61+
__throw_system_error(errno, "timespec_get(TIME_UTC) failed");
62+
return time_point(__secs(ts.tv_sec) + chrono::duration_cast<duration>(__nsecs(ts.tv_nsec)));
5363
#elif defined(_LIBCPP_HAS_CLOCK_GETTIME)
5464
typedef chrono::duration<rep, nano> __nsecs;
5565
struct timespec tp;

0 commit comments

Comments
 (0)