https://github.com/petrhosek updated https://github.com/llvm/llvm-project/pull/117362
>From f9f2fb604d49496fbbc65948d657de7f2638123c Mon Sep 17 00:00:00 2001 From: Petr Hosek <pho...@google.com> Date: Fri, 22 Nov 2024 10:47:06 -0800 Subject: [PATCH 1/2] [libcxx] Support for using timespec_get 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. --- clang/cmake/caches/Fuchsia-stage2.cmake | 4 ++-- libcxx/src/chrono.cpp | 22 ++++++++++++++++++++++ libcxx/src/filesystem/filesystem_clock.cpp | 10 ++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake b/clang/cmake/caches/Fuchsia-stage2.cmake index 5af98c7b3b3fba..9355f2dfa8ee84 100644 --- a/clang/cmake/caches/Fuchsia-stage2.cmake +++ b/clang/cmake/caches/Fuchsia-stage2.cmake @@ -329,7 +329,7 @@ foreach(target armv6m-none-eabi;armv7m-none-eabi;armv8m.main-none-eabi) 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} -mthumb -Wno-atomic-alignment \"-Dvfprintf(stream, format, vlist)=vprintf(format, vlist)\" \"-Dfprintf(stream, format, ...)=printf(format)\" \"-Dtimeval=struct timeval{int tv_sec; int tv_usec;}\" \"-Dgettimeofday(tv, tz)\" -D_LIBCPP_PRINT=1") + set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "--target=${target} -mthumb -Wno-atomic-alignment \"-Dvfprintf(stream, format, vlist)=vprintf(format, vlist)\" \"-Dfprintf(stream, format, ...)=printf(format)\" -D_LIBCPP_PRINT=1") if(${target} STREQUAL "armv8m.main-none-eabi") set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "${RUNTIMES_${target}_CMAKE_${lang}_local_flags} -mfloat-abi=softfp -march=armv8m.main+fp+dsp -mcpu=cortex-m33" CACHE STRING "") endif() @@ -385,7 +385,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)\" \"-Dtimeval=struct timeval{int tv_sec; int tv_usec;}\" \"-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 f17ea5542bd99d..8e9ad82befcf32 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() { @@ -213,6 +226,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(tp.tv_sec) + nanoseconds(tp.tv_nsec)); +} + # 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 473a54a00f013a..b15ef4ea61632a 100644 --- a/libcxx/src/filesystem/filesystem_clock.cpp +++ b/libcxx/src/filesystem/filesystem_clock.cpp @@ -29,6 +29,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 @@ -46,6 +50,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; >From b367a3470300a6a7656f45fecc981ad75239abd4 Mon Sep 17 00:00:00 2001 From: Petr Hosek <pho...@google.com> Date: Tue, 17 Dec 2024 00:38:14 -0800 Subject: [PATCH 2/2] Fix steady clock implementation --- libcxx/src/chrono.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/src/chrono.cpp b/libcxx/src/chrono.cpp index 26a38750e80dea..dbc0f617b4fc66 100644 --- a/libcxx/src/chrono.cpp +++ b/libcxx/src/chrono.cpp @@ -235,7 +235,7 @@ 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(tp.tv_sec) + nanoseconds(tp.tv_nsec)); + return steady_clock::time_point(seconds(ts.tv_sec) + microseconds(ts.tv_nsec / 1000)); } # elif defined(_LIBCPP_HAS_CLOCK_GETTIME) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits