[libc] [llvm] Reapply "[libc][windows] start time API implementation (#117775)" (PR #118886)
Schrodinger ZHU Yifan via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 5 14:14:29 PST 2024
https://github.com/SchrodingerZhu updated https://github.com/llvm/llvm-project/pull/118886
>From 4dee4c98eb5c2a84ccf4d19e6c9aaf2f3b47b86c Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Thu, 5 Dec 2024 17:03:21 -0500
Subject: [PATCH 1/3] Reapply "[libc][windows] start time API implementation
(#117775)"
This reverts commit 9fd052a1223c19245664922c68c101a79cb694f0.
---
libc/config/windows/entrypoints.txt | 3 +
libc/hdr/CMakeLists.txt | 8 +
libc/hdr/time_macros.h | 6 +
libc/hdr/types/clockid_t.h | 3 +-
.../llvm-libc-macros/windows/CMakeLists.txt | 6 +
.../windows/time-macros-ext.h | 17 ++
libc/src/CMakeLists.txt | 2 +-
libc/src/__support/time/CMakeLists.txt | 7 +
.../time/{linux => }/clock_gettime.h | 10 +-
libc/src/__support/time/linux/CMakeLists.txt | 2 +-
.../__support/time/linux/clock_conversion.h | 2 +-
.../__support/time/linux/clock_gettime.cpp | 2 +-
.../src/__support/time/windows/CMakeLists.txt | 16 ++
.../__support/time/windows/clock_gettime.cpp | 150 ++++++++++++++++++
libc/src/time/CMakeLists.txt | 10 +-
libc/src/time/linux/CMakeLists.txt | 21 +--
libc/src/time/linux/clock.cpp | 2 +-
libc/src/time/linux/clock_gettime.cpp | 2 +-
libc/src/time/linux/gettimeofday.cpp | 2 +-
libc/src/time/linux/timespec_get.cpp | 2 +-
libc/src/time/{linux => }/time.cpp | 8 +-
libc/test/src/CMakeLists.txt | 2 +-
.../threads/linux/raw_mutex_test.cpp | 2 +-
libc/test/src/time/CMakeLists.txt | 2 +-
libc/test/src/time/time_test.cpp | 2 -
.../llvm-project-overlay/libc/BUILD.bazel | 6 +-
26 files changed, 248 insertions(+), 47 deletions(-)
create mode 100644 libc/include/llvm-libc-macros/windows/CMakeLists.txt
create mode 100644 libc/include/llvm-libc-macros/windows/time-macros-ext.h
rename libc/src/__support/time/{linux => }/clock_gettime.h (72%)
create mode 100644 libc/src/__support/time/windows/CMakeLists.txt
create mode 100644 libc/src/__support/time/windows/clock_gettime.cpp
rename libc/src/time/{linux => }/time.cpp (83%)
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index 8f0b50bcc83ea2..d0796b85aec2af 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -95,6 +95,9 @@ set(TARGET_LIBC_ENTRYPOINTS
# errno.h entrypoints
libc.src.errno.errno
+
+ # time.h entrypoints
+ libc.src.time.time
)
set(TARGET_LIBM_ENTRYPOINTS
diff --git a/libc/hdr/CMakeLists.txt b/libc/hdr/CMakeLists.txt
index 93da271f5e040b..5eb311f4bb2298 100644
--- a/libc/hdr/CMakeLists.txt
+++ b/libc/hdr/CMakeLists.txt
@@ -135,10 +135,18 @@ add_proxy_header_library(
libc.include.llvm-libc-macros.unistd_macros
)
+if (WIN32)
+ set(windows_addtional_time_macros libc.include.llvm-libc-macros.windows.time_macros_ext)
+else()
+ set(windows_addtional_time_macros "")
+endif()
+
add_proxy_header_library(
time_macros
HDRS
time_macros.h
+ DEPENDS
+ ${windows_addtional_time_macros}
FULL_BUILD_DEPENDS
libc.include.time
libc.include.llvm-libc-macros.time_macros
diff --git a/libc/hdr/time_macros.h b/libc/hdr/time_macros.h
index dc36fe66f7a802..4488a24848c359 100644
--- a/libc/hdr/time_macros.h
+++ b/libc/hdr/time_macros.h
@@ -19,4 +19,10 @@
#endif // LLVM_LIBC_FULL_BUILD
+// TODO: For now, on windows, let's always include the extension header.
+// We will need to decide how to export this header.
+#ifdef _WIN32
+#include "include/llvm-libc-macros/windows/time-macros-ext.h"
+#endif // _WIN32
+
#endif // LLVM_LIBC_HDR_TIME_MACROS_H
diff --git a/libc/hdr/types/clockid_t.h b/libc/hdr/types/clockid_t.h
index 333342072a2ff2..729e580aba4384 100644
--- a/libc/hdr/types/clockid_t.h
+++ b/libc/hdr/types/clockid_t.h
@@ -9,7 +9,8 @@
#ifndef LLVM_LIBC_HDR_TYPES_CLOCKID_T_H
#define LLVM_LIBC_HDR_TYPES_CLOCKID_T_H
-#ifdef LIBC_FULL_BUILD
+// TODO: we will need to decide how to export extension to windows.
+#if defined(LIBC_FULL_BUILD) || defined(_WIN32)
#include "include/llvm-libc-types/clockid_t.h"
diff --git a/libc/include/llvm-libc-macros/windows/CMakeLists.txt b/libc/include/llvm-libc-macros/windows/CMakeLists.txt
new file mode 100644
index 00000000000000..48afc795178a0d
--- /dev/null
+++ b/libc/include/llvm-libc-macros/windows/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_header(
+ time_macros_ext
+ HDR
+ time-macros-ext.h
+)
+
diff --git a/libc/include/llvm-libc-macros/windows/time-macros-ext.h b/libc/include/llvm-libc-macros/windows/time-macros-ext.h
new file mode 100644
index 00000000000000..71d914b4518771
--- /dev/null
+++ b/libc/include/llvm-libc-macros/windows/time-macros-ext.h
@@ -0,0 +1,17 @@
+//===-- Windows Time Macros Extension -------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_WINDOWS_TIME_MACROS_EXT_H
+#define LLVM_LIBC_MACROS_WINDOWS_TIME_MACROS_EXT_H
+
+#define CLOCK_MONOTONIC 0
+#define CLOCK_REALTIME 1
+#define CLOCK_PROCESS_CPUTIME_ID 2
+#define CLOCK_THREAD_CPUTIME_ID 3
+
+#endif // LLVM_LIBC_MACROS_WINDOWS_TIME_MACROS_EXT_H
diff --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt
index 02c193e635362e..dd3b51886edfea 100644
--- a/libc/src/CMakeLists.txt
+++ b/libc/src/CMakeLists.txt
@@ -13,6 +13,7 @@ add_subdirectory(stdio)
add_subdirectory(stdlib)
add_subdirectory(string)
add_subdirectory(wchar)
+add_subdirectory(time)
if(${LIBC_TARGET_OS} STREQUAL "linux")
add_subdirectory(dirent)
@@ -40,5 +41,4 @@ add_subdirectory(setjmp)
add_subdirectory(signal)
add_subdirectory(spawn)
add_subdirectory(threads)
-add_subdirectory(time)
add_subdirectory(locale)
diff --git a/libc/src/__support/time/CMakeLists.txt b/libc/src/__support/time/CMakeLists.txt
index 89ddffb099388b..e73f2744b15a0e 100644
--- a/libc/src/__support/time/CMakeLists.txt
+++ b/libc/src/__support/time/CMakeLists.txt
@@ -2,6 +2,13 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
add_subdirectory(${LIBC_TARGET_OS})
endif()
+add_object_library(
+ clock_gettime
+ ALIAS
+ DEPENDS
+ libc.src.__support.time.${LIBC_TARGET_OS}.clock_gettime
+)
+
add_header_library(
units
HDRS
diff --git a/libc/src/__support/time/linux/clock_gettime.h b/libc/src/__support/time/clock_gettime.h
similarity index 72%
rename from libc/src/__support/time/linux/clock_gettime.h
rename to libc/src/__support/time/clock_gettime.h
index f7f996ce7c1975..584bf546cd60cd 100644
--- a/libc/src/__support/time/linux/clock_gettime.h
+++ b/libc/src/__support/time/clock_gettime.h
@@ -6,21 +6,17 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIBC_SRC___SUPPORT_TIME_LINUX_CLOCK_GETTIME_H
-#define LLVM_LIBC_SRC___SUPPORT_TIME_LINUX_CLOCK_GETTIME_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_TIME_CLOCK_GETTIME_H
+#define LLVM_LIBC_SRC___SUPPORT_TIME_CLOCK_GETTIME_H
#include "hdr/types/clockid_t.h"
#include "hdr/types/struct_timespec.h"
#include "src/__support/error_or.h"
-#if defined(SYS_clock_gettime64)
-#include <linux/time_types.h>
-#endif
-
namespace LIBC_NAMESPACE_DECL {
namespace internal {
ErrorOr<int> clock_gettime(clockid_t clockid, timespec *ts);
} // namespace internal
} // namespace LIBC_NAMESPACE_DECL
-#endif // LLVM_LIBC_SRC___SUPPORT_TIME_LINUX_CLOCK_GETTIME_H
+#endif // LLVM_LIBC_SRC___SUPPORT_TIME_CLOCK_GETTIME_H
diff --git a/libc/src/__support/time/linux/CMakeLists.txt b/libc/src/__support/time/linux/CMakeLists.txt
index 94ed09e6521524..6fec7eeba99add 100644
--- a/libc/src/__support/time/linux/CMakeLists.txt
+++ b/libc/src/__support/time/linux/CMakeLists.txt
@@ -1,7 +1,7 @@
add_object_library(
clock_gettime
HDRS
- clock_gettime.h
+ ../clock_gettime.h
SRCS
clock_gettime.cpp
DEPENDS
diff --git a/libc/src/__support/time/linux/clock_conversion.h b/libc/src/__support/time/linux/clock_conversion.h
index 7a52873263a14c..ac5357d308d7c5 100644
--- a/libc/src/__support/time/linux/clock_conversion.h
+++ b/libc/src/__support/time/linux/clock_conversion.h
@@ -10,7 +10,7 @@
#define LLVM_LIBC_SRC___SUPPORT_TIME_LINUX_CLOCK_CONVERSION_H
#include "src/__support/macros/config.h"
-#include "src/__support/time/linux/clock_gettime.h"
+#include "src/__support/time/clock_gettime.h"
#include "src/__support/time/units.h"
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/__support/time/linux/clock_gettime.cpp b/libc/src/__support/time/linux/clock_gettime.cpp
index 3a0eca417724ac..944fc0a2b80fe7 100644
--- a/libc/src/__support/time/linux/clock_gettime.cpp
+++ b/libc/src/__support/time/linux/clock_gettime.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "src/__support/time/linux/clock_gettime.h"
+#include "src/__support/time/clock_gettime.h"
#include "hdr/types/clockid_t.h"
#include "hdr/types/struct_timespec.h"
#include "src/__support/OSUtil/linux/vdso.h"
diff --git a/libc/src/__support/time/windows/CMakeLists.txt b/libc/src/__support/time/windows/CMakeLists.txt
new file mode 100644
index 00000000000000..0f557ed8800802
--- /dev/null
+++ b/libc/src/__support/time/windows/CMakeLists.txt
@@ -0,0 +1,16 @@
+add_object_library(
+ clock_gettime
+ HDRS
+ ../clock_gettime.h
+ SRCS
+ clock_gettime.cpp
+ DEPENDS
+ libc.hdr.types.struct_timespec
+ libc.hdr.types.clockid_t
+ libc.hdr.errno_macros
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.CPP.atomic
+ libc.src.__support.CPP.limits
+)
diff --git a/libc/src/__support/time/windows/clock_gettime.cpp b/libc/src/__support/time/windows/clock_gettime.cpp
new file mode 100644
index 00000000000000..c2536acf37d799
--- /dev/null
+++ b/libc/src/__support/time/windows/clock_gettime.cpp
@@ -0,0 +1,150 @@
+//===--- clock_gettime windows implementation -------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "hdr/time_macros.h"
+
+#include "src/__support/CPP/atomic.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/limits.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/time/clock_gettime.h"
+#include "src/__support/time/units.h"
+
+#define WIN32_LEAN_AND_MEAN
+#define NOMINMAX
+#include <Windows.h>
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+static long long get_ticks_per_second() {
+ static cpp::Atomic<long long> frequency = 0;
+ // Relaxed ordering is enough. It is okay to record the frequency multiple
+ // times. The store operation itself is atomic and the value must propagate
+ // as required by cache coherence.
+ auto freq = frequency.load(cpp::MemoryOrder::RELAXED);
+ if (!freq) {
+ [[clang::uninitialized]] LARGE_INTEGER buffer;
+ // On systems that run Windows XP or later, the function will always
+ // succeed and will thus never return zero.
+ ::QueryPerformanceFrequency(&buffer);
+ frequency.store(buffer.QuadPart, cpp::MemoryOrder::RELAXED);
+ return buffer.QuadPart;
+ }
+ return freq;
+}
+
+ErrorOr<int> clock_gettime(clockid_t clockid, timespec *ts) {
+ using namespace time_units;
+ constexpr unsigned long long HNS_PER_SEC = 1_s_ns / 100ULL;
+ constexpr long long SEC_LIMIT =
+ cpp::numeric_limits<decltype(ts->tv_sec)>::max();
+ ErrorOr<int> ret = 0;
+ switch (clockid) {
+ default:
+ ret = cpp::unexpected(EINVAL);
+ break;
+
+ case CLOCK_MONOTONIC: {
+ // see
+ // https://learn.microsoft.com/en-us/windows/win32/sysinfo/acquiring-high-resolution-time-stamps
+ // Is the performance counter monotonic (non-decreasing)?
+ // Yes. QPC does not go backward.
+ [[clang::uninitialized]] LARGE_INTEGER buffer;
+ // On systems that run Windows XP or later, the function will always
+ // succeed and will thus never return zero.
+ ::QueryPerformanceCounter(&buffer);
+ long long freq = get_ticks_per_second();
+ long long ticks = buffer.QuadPart;
+ long long tv_sec = ticks / freq;
+ long long tv_nsec = (ticks % freq) * 1_s_ns / freq;
+ if (LIBC_UNLIKELY(tv_sec > SEC_LIMIT)) {
+ ret = cpp::unexpected(EOVERFLOW);
+ break;
+ }
+ ts->tv_sec = static_cast<decltype(ts->tv_sec)>(tv_sec);
+ ts->tv_nsec = static_cast<decltype(ts->tv_nsec)>(tv_nsec);
+ break;
+ }
+ case CLOCK_REALTIME: {
+ // https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime
+ // GetSystemTimePreciseAsFileTime
+ // This function is best suited for high-resolution time-of-day
+ // measurements, or time stamps that are synchronized to UTC
+ [[clang::uninitialized]] FILETIME file_time;
+ [[clang::uninitialized]] ULARGE_INTEGER time;
+ ::GetSystemTimePreciseAsFileTime(&file_time);
+ time.LowPart = file_time.dwLowDateTime;
+ time.HighPart = file_time.dwHighDateTime;
+
+ // adjust to POSIX epoch (from Jan 1, 1601 to Jan 1, 1970)
+ constexpr unsigned long long POSIX_TIME_SHIFT =
+ (11644473600ULL * HNS_PER_SEC);
+ if (LIBC_UNLIKELY(POSIX_TIME_SHIFT > time.QuadPart)) {
+ ret = cpp::unexpected(EOVERFLOW);
+ break;
+ }
+ time.QuadPart -= (11644473600ULL * HNS_PER_SEC);
+ unsigned long long tv_sec = time.QuadPart / HNS_PER_SEC;
+ unsigned long long tv_nsec = (time.QuadPart % HNS_PER_SEC) * 100ULL;
+ if (LIBC_UNLIKELY(tv_sec > SEC_LIMIT)) {
+ ret = cpp::unexpected(EOVERFLOW);
+ break;
+ }
+ ts->tv_sec = static_cast<decltype(ts->tv_sec)>(tv_sec);
+ ts->tv_nsec = static_cast<decltype(ts->tv_nsec)>(tv_nsec);
+ break;
+ }
+ case CLOCK_PROCESS_CPUTIME_ID:
+ case CLOCK_THREAD_CPUTIME_ID: {
+ [[clang::uninitialized]] FILETIME creation_time;
+ [[clang::uninitialized]] FILETIME exit_time;
+ [[clang::uninitialized]] FILETIME kernel_time;
+ [[clang::uninitialized]] FILETIME user_time;
+ bool success;
+ if (clockid == CLOCK_PROCESS_CPUTIME_ID) {
+ // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocesstimes
+ success = ::GetProcessTimes(::GetCurrentProcess(), &creation_time,
+ &exit_time, &kernel_time, &user_time);
+ } else {
+ // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getthreadtimes
+ success = ::GetThreadTimes(::GetCurrentThread(), &creation_time,
+ &exit_time, &kernel_time, &user_time);
+ }
+ if (!success) {
+ ret = cpp::unexpected(EINVAL);
+ break;
+ }
+ // https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
+ // It is not recommended that you add and subtract values from the FILETIME
+ // structure to obtain relative times. Instead, you should copy the low- and
+ // high-order parts of the file time to a ULARGE_INTEGER structure, perform
+ // 64-bit arithmetic on the QuadPart member, and copy the LowPart and
+ // HighPart members into the FILETIME structure.
+ auto kernel_time_hns = cpp::bit_cast<ULARGE_INTEGER>(kernel_time);
+ auto user_time_hns = cpp::bit_cast<ULARGE_INTEGER>(user_time);
+ unsigned long long total_time_hns =
+ kernel_time_hns.QuadPart + user_time_hns.QuadPart;
+
+ unsigned long long tv_sec = total_time_hns / HNS_PER_SEC;
+ unsigned long long tv_nsec = (total_time_hns % HNS_PER_SEC) * 100ULL;
+
+ if (LIBC_UNLIKELY(tv_sec > SEC_LIMIT)) {
+ ret = cpp::unexpected(EOVERFLOW);
+ break;
+ }
+
+ ts->tv_sec = static_cast<decltype(ts->tv_sec)>(tv_sec);
+ ts->tv_nsec = static_cast<decltype(ts->tv_nsec)>(tv_nsec);
+
+ break;
+ }
+ }
+ return ret;
+}
+} // namespace internal
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/time/CMakeLists.txt b/libc/src/time/CMakeLists.txt
index f18e74a15e6fc2..3e8e6882ffc5d4 100644
--- a/libc/src/time/CMakeLists.txt
+++ b/libc/src/time/CMakeLists.txt
@@ -106,9 +106,15 @@ add_entrypoint_object(
add_entrypoint_object(
time
- ALIAS
+ SRCS
+ time.cpp
+ HDRS
+ time_func.h
DEPENDS
- .${LIBC_TARGET_OS}.time
+ libc.hdr.time_macros
+ libc.hdr.types.time_t
+ libc.src.__support.time.clock_gettime
+ libc.src.errno.errno
)
add_entrypoint_object(
diff --git a/libc/src/time/linux/CMakeLists.txt b/libc/src/time/linux/CMakeLists.txt
index 31fd7d1e64c85c..314623f9f425e7 100644
--- a/libc/src/time/linux/CMakeLists.txt
+++ b/libc/src/time/linux/CMakeLists.txt
@@ -1,16 +1,3 @@
-add_entrypoint_object(
- time
- SRCS
- time.cpp
- HDRS
- ../time_func.h
- DEPENDS
- libc.hdr.time_macros
- libc.hdr.types.time_t
- libc.src.__support.time.linux.clock_gettime
- libc.src.errno.errno
-)
-
add_entrypoint_object(
timespec_get
SRCS
@@ -20,7 +7,7 @@ add_entrypoint_object(
DEPENDS
libc.hdr.time_macros
libc.hdr.types.struct_timespec
- libc.src.__support.time.linux.clock_gettime
+ libc.src.__support.time.clock_gettime
libc.src.errno.errno
)
@@ -34,7 +21,7 @@ add_entrypoint_object(
libc.hdr.time_macros
libc.hdr.types.clock_t
libc.src.__support.time.units
- libc.src.__support.time.linux.clock_gettime
+ libc.src.__support.time.clock_gettime
libc.src.__support.CPP.limits
libc.src.errno.errno
)
@@ -62,7 +49,7 @@ add_entrypoint_object(
DEPENDS
libc.hdr.types.clockid_t
libc.hdr.types.struct_timespec
- libc.src.__support.time.linux.clock_gettime
+ libc.src.__support.time.clock_gettime
libc.src.errno.errno
)
@@ -75,7 +62,7 @@ add_entrypoint_object(
DEPENDS
libc.hdr.time_macros
libc.hdr.types.suseconds_t
- libc.src.__support.time.linux.clock_gettime
+ libc.src.__support.time.clock_gettime
libc.src.__support.time.units
libc.src.errno.errno
)
diff --git a/libc/src/time/linux/clock.cpp b/libc/src/time/linux/clock.cpp
index f43e1bcad6a3a1..ee4fa82b4f8944 100644
--- a/libc/src/time/linux/clock.cpp
+++ b/libc/src/time/linux/clock.cpp
@@ -11,7 +11,7 @@
#include "src/__support/CPP/limits.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
-#include "src/__support/time/linux/clock_gettime.h"
+#include "src/__support/time/clock_gettime.h"
#include "src/__support/time/units.h"
#include "src/errno/libc_errno.h"
diff --git a/libc/src/time/linux/clock_gettime.cpp b/libc/src/time/linux/clock_gettime.cpp
index a2b20a6dbc9879..743c644d65d024 100644
--- a/libc/src/time/linux/clock_gettime.cpp
+++ b/libc/src/time/linux/clock_gettime.cpp
@@ -9,7 +9,7 @@
#include "src/time/clock_gettime.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
-#include "src/__support/time/linux/clock_gettime.h"
+#include "src/__support/time/clock_gettime.h"
#include "src/errno/libc_errno.h"
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/time/linux/gettimeofday.cpp b/libc/src/time/linux/gettimeofday.cpp
index 19d9988ae73a6e..e8ddf482fc9840 100644
--- a/libc/src/time/linux/gettimeofday.cpp
+++ b/libc/src/time/linux/gettimeofday.cpp
@@ -11,7 +11,7 @@
#include "hdr/types/suseconds_t.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
-#include "src/__support/time/linux/clock_gettime.h"
+#include "src/__support/time/clock_gettime.h"
#include "src/__support/time/units.h"
#include "src/errno/libc_errno.h"
diff --git a/libc/src/time/linux/timespec_get.cpp b/libc/src/time/linux/timespec_get.cpp
index ba9f8eb2e4426b..cf5174523aa4f9 100644
--- a/libc/src/time/linux/timespec_get.cpp
+++ b/libc/src/time/linux/timespec_get.cpp
@@ -10,7 +10,7 @@
#include "hdr/time_macros.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
-#include "src/__support/time/linux/clock_gettime.h"
+#include "src/__support/time/clock_gettime.h"
#include "src/errno/libc_errno.h"
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/time/linux/time.cpp b/libc/src/time/time.cpp
similarity index 83%
rename from libc/src/time/linux/time.cpp
rename to libc/src/time/time.cpp
index 20fb86e8e29dbb..4a0b614a68ef5f 100644
--- a/libc/src/time/linux/time.cpp
+++ b/libc/src/time/time.cpp
@@ -9,14 +9,14 @@
#include "hdr/time_macros.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
-#include "src/__support/time/linux/clock_gettime.h"
+#include "src/__support/time/clock_gettime.h"
#include "src/errno/libc_errno.h"
#include "src/time/time_func.h"
namespace LIBC_NAMESPACE_DECL {
-
-LLVM_LIBC_FUNCTION(time_t, time, (time_t * tp)) {
- // TODO: Use the Linux VDSO to fetch the time and avoid the syscall.
+// avoid inconsitent clang-format behavior
+using time_ptr_t = time_t *;
+LLVM_LIBC_FUNCTION(time_t, time, (time_ptr_t tp)) {
struct timespec ts;
auto result = internal::clock_gettime(CLOCK_REALTIME, &ts);
if (!result.has_value()) {
diff --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt
index 8ac8f91e98d4cc..606f6d837e4fe7 100644
--- a/libc/test/src/CMakeLists.txt
+++ b/libc/test/src/CMakeLists.txt
@@ -59,6 +59,7 @@ add_subdirectory(stdio)
add_subdirectory(stdlib)
add_subdirectory(string)
add_subdirectory(wchar)
+add_subdirectory(time)
# Depends on utilities in stdlib
add_subdirectory(inttypes)
@@ -82,7 +83,6 @@ add_subdirectory(network)
add_subdirectory(setjmp)
add_subdirectory(signal)
add_subdirectory(spawn)
-add_subdirectory(time)
add_subdirectory(locale)
if(${LIBC_TARGET_OS} STREQUAL "linux")
diff --git a/libc/test/src/__support/threads/linux/raw_mutex_test.cpp b/libc/test/src/__support/threads/linux/raw_mutex_test.cpp
index 918f5d35c94f42..dadc706421d06e 100644
--- a/libc/test/src/__support/threads/linux/raw_mutex_test.cpp
+++ b/libc/test/src/__support/threads/linux/raw_mutex_test.cpp
@@ -12,7 +12,7 @@
#include "src/__support/OSUtil/syscall.h"
#include "src/__support/threads/linux/raw_mutex.h"
#include "src/__support/threads/sleep.h"
-#include "src/__support/time/linux/clock_gettime.h"
+#include "src/__support/time/clock_gettime.h"
#include "src/stdlib/exit.h"
#include "src/sys/mman/mmap.h"
#include "src/sys/mman/munmap.h"
diff --git a/libc/test/src/time/CMakeLists.txt b/libc/test/src/time/CMakeLists.txt
index 7151526b72b26d..d2a98677a55435 100644
--- a/libc/test/src/time/CMakeLists.txt
+++ b/libc/test/src/time/CMakeLists.txt
@@ -157,8 +157,8 @@ add_libc_unittest(
SRCS
time_test.cpp
DEPENDS
- libc.include.time
libc.src.time.time
+ libc.src.__support.time.clock_gettime
libc.src.errno.errno
)
diff --git a/libc/test/src/time/time_test.cpp b/libc/test/src/time/time_test.cpp
index d3d4dc9a285158..7cdb4e834633e5 100644
--- a/libc/test/src/time/time_test.cpp
+++ b/libc/test/src/time/time_test.cpp
@@ -9,8 +9,6 @@
#include "src/time/time_func.h"
#include "test/UnitTest/Test.h"
-#include <time.h>
-
TEST(LlvmLibcTimeTest, SmokeTest) {
time_t t1;
time_t t2 = LIBC_NAMESPACE::time(&t1);
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index c5a0076d2ef308..957b49fe6afe8e 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -1471,13 +1471,13 @@ libc_support_library(
}),
deps = [
":__support_time",
- ":__support_time_linux_clock_gettime",
+ ":__support_time_clock_gettime",
],
)
libc_support_library(
- name = "__support_time_linux_clock_gettime",
- hdrs = ["src/__support/time/linux/clock_gettime.h"],
+ name = "__support_time_clock_gettime",
+ hdrs = ["src/__support/time/clock_gettime.h"],
target_compatible_with = select({
"@platforms//os:linux": [],
"//conditions:default": ["@platforms//:incompatible"],
>From 67e357e4ccfedfb1dc81579eb4ae370ba0a80e14 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Thu, 5 Dec 2024 12:02:56 -0800
Subject: [PATCH 2/3] [libc][gpu] unify time implementation style and fix build
---
libc/src/__support/time/CMakeLists.txt | 20 ++++++-----
libc/src/__support/time/gpu/CMakeLists.txt | 22 ++++++++++++
libc/src/__support/time/gpu/clock_gettime.cpp | 33 +++++++++++++++++
.../{ => __support}/time/gpu/time_utils.cpp | 0
.../src/{ => __support}/time/gpu/time_utils.h | 0
libc/src/time/gpu/CMakeLists.txt | 36 ++++++++-----------
libc/src/time/gpu/clock.cpp | 2 +-
libc/src/time/gpu/clock_gettime.cpp | 19 ++++------
libc/src/time/gpu/nanosleep.cpp | 2 +-
9 files changed, 88 insertions(+), 46 deletions(-)
create mode 100644 libc/src/__support/time/gpu/CMakeLists.txt
create mode 100644 libc/src/__support/time/gpu/clock_gettime.cpp
rename libc/src/{ => __support}/time/gpu/time_utils.cpp (100%)
rename libc/src/{ => __support}/time/gpu/time_utils.h (100%)
diff --git a/libc/src/__support/time/CMakeLists.txt b/libc/src/__support/time/CMakeLists.txt
index e73f2744b15a0e..8247e792e84105 100644
--- a/libc/src/__support/time/CMakeLists.txt
+++ b/libc/src/__support/time/CMakeLists.txt
@@ -1,5 +1,16 @@
+add_header_library(
+ units
+ HDRS
+ units.h
+ DEPENDS
+ libc.src.__support.common
+ libc.hdr.types.time_t
+)
+
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
add_subdirectory(${LIBC_TARGET_OS})
+else()
+ return()
endif()
add_object_library(
@@ -8,12 +19,3 @@ add_object_library(
DEPENDS
libc.src.__support.time.${LIBC_TARGET_OS}.clock_gettime
)
-
-add_header_library(
- units
- HDRS
- units.h
- DEPENDS
- libc.src.__support.common
- libc.hdr.types.time_t
-)
diff --git a/libc/src/__support/time/gpu/CMakeLists.txt b/libc/src/__support/time/gpu/CMakeLists.txt
new file mode 100644
index 00000000000000..efa6cd32454cc0
--- /dev/null
+++ b/libc/src/__support/time/gpu/CMakeLists.txt
@@ -0,0 +1,22 @@
+add_object_library(
+ time_utils
+ SRCS
+ time_utils.cpp
+ HDRS
+ time_utils.h
+ DEPENDS
+ libc.hdr.types.clock_t
+ libc.hdr.time_macros
+)
+
+add_entrypoint_object(
+ clock_gettime
+ SRCS
+ clock_gettime.cpp
+ HDRS
+ ../clock_gettime.h
+ DEPENDS
+ libc.hdr.types.clockid_t
+ libc.hdr.types.struct_timespec
+ .time_utils
+)
diff --git a/libc/src/__support/time/gpu/clock_gettime.cpp b/libc/src/__support/time/gpu/clock_gettime.cpp
new file mode 100644
index 00000000000000..cede72a1f35da4
--- /dev/null
+++ b/libc/src/__support/time/gpu/clock_gettime.cpp
@@ -0,0 +1,33 @@
+//===---------- GPU implementation of the clock_gettime function ----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/time/clock_gettime.h"
+
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/time/clock_gettime.h"
+#include "src/__support/time/gpu/time_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+constexpr uint64_t TICKS_PER_SEC = 1000000000UL;
+
+ErrorOr<int> clock_gettime(clockid_t clockid, timespec *ts) {
+ if (clockid != CLOCK_MONOTONIC || !ts)
+ return cpp::unexpected(-1);
+
+ uint64_t ns_per_tick = TICKS_PER_SEC / GPU_CLOCKS_PER_SEC;
+ uint64_t ticks = gpu::fixed_frequency_clock();
+
+ ts->tv_nsec = (ticks * ns_per_tick) % TICKS_PER_SEC;
+ ts->tv_sec = (ticks * ns_per_tick) / TICKS_PER_SEC;
+
+ return 0;
+}
+} // namespace internal
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/time/gpu/time_utils.cpp b/libc/src/__support/time/gpu/time_utils.cpp
similarity index 100%
rename from libc/src/time/gpu/time_utils.cpp
rename to libc/src/__support/time/gpu/time_utils.cpp
diff --git a/libc/src/time/gpu/time_utils.h b/libc/src/__support/time/gpu/time_utils.h
similarity index 100%
rename from libc/src/time/gpu/time_utils.h
rename to libc/src/__support/time/gpu/time_utils.h
diff --git a/libc/src/time/gpu/CMakeLists.txt b/libc/src/time/gpu/CMakeLists.txt
index 8da5d3a22f5a09..31a60595d68ff3 100644
--- a/libc/src/time/gpu/CMakeLists.txt
+++ b/libc/src/time/gpu/CMakeLists.txt
@@ -1,14 +1,3 @@
-add_object_library(
- time_utils
- SRCS
- time_utils.cpp
- HDRS
- time_utils.h
- DEPENDS
- libc.hdr.types.clock_t
- libc.hdr.time_macros
-)
-
add_entrypoint_object(
clock
SRCS
@@ -18,7 +7,8 @@ add_entrypoint_object(
DEPENDS
libc.include.time
libc.src.__support.GPU.utils
- .time_utils
+ libc.src.__support.time.clock_gettime
+ libc.src.__support.time.gpu.time_utils
)
add_entrypoint_object(
@@ -30,29 +20,31 @@ add_entrypoint_object(
DEPENDS
libc.include.time
libc.src.__support.GPU.utils
- .time_utils
+ libc.src.__support.time.gpu.time_utils
)
add_entrypoint_object(
- clock_gettime
+ timespec_get
SRCS
- clock_gettime.cpp
+ timespec_get.cpp
HDRS
- ../clock_gettime.h
+ ../timespec_get.h
DEPENDS
- libc.hdr.types.clockid_t
+ libc.hdr.time_macros
libc.hdr.types.struct_timespec
- .time_utils
+ libc.src.__support.time.gpu.time_utils
)
add_entrypoint_object(
- timespec_get
+ clock_gettime
SRCS
- timespec_get.cpp
+ clock_gettime.cpp
HDRS
- ../timespec_get.h
+ ../clock_gettime.h
DEPENDS
libc.hdr.time_macros
+ libc.hdr.types.clockid_t
libc.hdr.types.struct_timespec
- .time_utils
+ libc.src.__support.time.gpu.time_utils
+ libc.src.__support.time.clock_gettime
)
diff --git a/libc/src/time/gpu/clock.cpp b/libc/src/time/gpu/clock.cpp
index 4cdb1d505aed2b..add5b2725ef8f0 100644
--- a/libc/src/time/gpu/clock.cpp
+++ b/libc/src/time/gpu/clock.cpp
@@ -8,7 +8,7 @@
#include "src/time/clock.h"
#include "src/__support/macros/config.h"
-#include "src/time/gpu/time_utils.h"
+#include "src/__support/time/gpu/time_utils.h"
namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/time/gpu/clock_gettime.cpp b/libc/src/time/gpu/clock_gettime.cpp
index de7899a2a17cc0..81547ef7f1ca68 100644
--- a/libc/src/time/gpu/clock_gettime.cpp
+++ b/libc/src/time/gpu/clock_gettime.cpp
@@ -10,23 +10,16 @@
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
-#include "time_utils.h"
+#include "src/__support/time/clock_gettime.h"
+#include "src/__support/time/gpu/time_utils.h"
namespace LIBC_NAMESPACE_DECL {
-constexpr uint64_t TICKS_PER_SEC = 1000000000UL;
-
LLVM_LIBC_FUNCTION(int, clock_gettime, (clockid_t clockid, timespec *ts)) {
- if (clockid != CLOCK_MONOTONIC || !ts)
- return -1;
-
- uint64_t ns_per_tick = TICKS_PER_SEC / GPU_CLOCKS_PER_SEC;
- uint64_t ticks = gpu::fixed_frequency_clock();
-
- ts->tv_nsec = (ticks * ns_per_tick) % TICKS_PER_SEC;
- ts->tv_sec = (ticks * ns_per_tick) / TICKS_PER_SEC;
-
- return 0;
+ ErrorOr<int> result = internal::clock_gettime(clockid, ts);
+ if (result)
+ return result.value();
+ return result.error();
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/time/gpu/nanosleep.cpp b/libc/src/time/gpu/nanosleep.cpp
index 3f4a609dd40eba..25a22d5703fa78 100644
--- a/libc/src/time/gpu/nanosleep.cpp
+++ b/libc/src/time/gpu/nanosleep.cpp
@@ -9,7 +9,7 @@
#include "src/time/nanosleep.h"
#include "src/__support/macros/config.h"
-#include "time_utils.h"
+#include "src/__support/time/gpu/time_utils.h"
namespace LIBC_NAMESPACE_DECL {
>From ea35f2a0cdc3b02d3299e49204d7b7fdd58a5456 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Thu, 5 Dec 2024 17:14:15 -0500
Subject: [PATCH 3/3] fix
---
libc/src/__support/time/gpu/CMakeLists.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/__support/time/gpu/CMakeLists.txt b/libc/src/__support/time/gpu/CMakeLists.txt
index efa6cd32454cc0..fc465e0cea25ff 100644
--- a/libc/src/__support/time/gpu/CMakeLists.txt
+++ b/libc/src/__support/time/gpu/CMakeLists.txt
@@ -9,7 +9,7 @@ add_object_library(
libc.hdr.time_macros
)
-add_entrypoint_object(
+add_object_library(
clock_gettime
SRCS
clock_gettime.cpp
More information about the llvm-commits
mailing list