-
Notifications
You must be signed in to change notification settings - Fork 11.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[libc] Implement clock_gettime
for the monotonic clock on the GPU
#99067
Conversation
@llvm/pr-subscribers-libc Author: Joseph Huber (jhuber6) ChangesSummary: Full diff: https://github.com/llvm/llvm-project/pull/99067.diff 8 Files Affected:
diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt
index 63228216c85ec..457018beaf0a3 100644
--- a/libc/config/gpu/entrypoints.txt
+++ b/libc/config/gpu/entrypoints.txt
@@ -216,6 +216,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# time.h entrypoints
libc.src.time.clock
+ libc.src.time.clock_gettime
libc.src.time.nanosleep
# wchar.h entrypoints
diff --git a/libc/docs/gpu/support.rst b/libc/docs/gpu/support.rst
index 6e2c8c7e93987..89ea4d588a16f 100644
--- a/libc/docs/gpu/support.rst
+++ b/libc/docs/gpu/support.rst
@@ -242,6 +242,7 @@ time.h
Function Name Available RPC Required
============= ========= ============
clock |check|
+clock_gettime |check|
nanosleep |check|
============= ========= ============
diff --git a/libc/include/llvm-libc-macros/gpu/time-macros.h b/libc/include/llvm-libc-macros/gpu/time-macros.h
index c3dc812f90a3b..7142a3e1b2764 100644
--- a/libc/include/llvm-libc-macros/gpu/time-macros.h
+++ b/libc/include/llvm-libc-macros/gpu/time-macros.h
@@ -9,6 +9,9 @@
#ifndef LLVM_LIBC_MACROS_GPU_TIME_MACROS_H
#define LLVM_LIBC_MACROS_GPU_TIME_MACROS_H
+#define CLOCK_REALTIME 0
+#define CLOCK_MONOTONIC 1
+
#define CLOCKS_PER_SEC 1000000
#endif // LLVM_LIBC_MACROS_GPU_TIME_MACROS_H
diff --git a/libc/include/time.h.def b/libc/include/time.h.def
index 2355e8822fad7..3776dfcadad28 100644
--- a/libc/include/time.h.def
+++ b/libc/include/time.h.def
@@ -11,6 +11,8 @@
#include "__llvm-libc-common.h"
#include "llvm-libc-macros/time-macros.h"
+#include "llvm-libc-types/clock_t.h"
+#include "llvm-libc-types/clockid_t.h"
%%public_api()
diff --git a/libc/src/time/gpu/CMakeLists.txt b/libc/src/time/gpu/CMakeLists.txt
index 088271d881911..c9b4562815801 100644
--- a/libc/src/time/gpu/CMakeLists.txt
+++ b/libc/src/time/gpu/CMakeLists.txt
@@ -32,3 +32,15 @@ add_entrypoint_object(
libc.src.__support.GPU.utils
.time_utils
)
+
+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/time/gpu/clock_gettime.cpp b/libc/src/time/gpu/clock_gettime.cpp
new file mode 100644
index 0000000000000..fd36b7fcb05e2
--- /dev/null
+++ b/libc/src/time/gpu/clock_gettime.cpp
@@ -0,0 +1,33 @@
+//===---------- GPU implementation of the POSIX 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 "time_utils.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+constexpr uint64_t TICKS_PER_SEC = 1000000000UL;
+
+LLVM_LIBC_FUNCTION(int, clock_gettime,
+ (clockid_t clockid, struct 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;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/time/CMakeLists.txt b/libc/test/src/time/CMakeLists.txt
index 51cacef0a62fe..78cfe8f301615 100644
--- a/libc/test/src/time/CMakeLists.txt
+++ b/libc/test/src/time/CMakeLists.txt
@@ -30,7 +30,7 @@ add_libc_unittest(
libc.src.time.asctime_r
)
-add_libc_unittest(
+add_libc_test(
clock_gettime_test
SUITE
libc_time_unittests
diff --git a/libc/test/src/time/clock_gettime_test.cpp b/libc/test/src/time/clock_gettime_test.cpp
index 6367ae7145a47..8ae2a503e0926 100644
--- a/libc/test/src/time/clock_gettime_test.cpp
+++ b/libc/test/src/time/clock_gettime_test.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "src/__support/macros/properties/architectures.h"
#include "src/time/clock_gettime.h"
#include "test/UnitTest/Test.h"
@@ -15,8 +16,14 @@ TEST(LlvmLibcClockGetTime, RealTime) {
struct timespec tp;
int result;
result = LIBC_NAMESPACE::clock_gettime(CLOCK_REALTIME, &tp);
+ // The GPU does not implement CLOCK_REALTIME but provides it so programs will
+ // compile.
+#ifdef LIBC_TARGET_ARCH_IS_GPU
+ ASSERT_EQ(result, -1);
+#else
ASSERT_EQ(result, 0);
ASSERT_GT(tp.tv_sec, time_t(0));
+#endif
}
#ifdef CLOCK_MONOTONIC
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
You can test this locally with the following command:git-clang-format --diff 3cdbb8d74d6fbd298ad4d7d283a3c7bba008e8ef d52779f59adff528b34fdeb8c8e14a557352b759 --extensions cpp,h -- libc/src/time/gpu/clock_gettime.cpp libc/include/llvm-libc-macros/gpu/time-macros.h libc/test/src/time/clock_gettime_test.cpp View the diff from clang-format here.diff --git a/libc/src/time/gpu/clock_gettime.cpp b/libc/src/time/gpu/clock_gettime.cpp
index 7241d5b6e8..de7899a2a1 100644
--- a/libc/src/time/gpu/clock_gettime.cpp
+++ b/libc/src/time/gpu/clock_gettime.cpp
@@ -16,8 +16,7 @@ namespace LIBC_NAMESPACE_DECL {
constexpr uint64_t TICKS_PER_SEC = 1000000000UL;
-LLVM_LIBC_FUNCTION(int, clock_gettime,
- (clockid_t clockid, timespec *ts)) {
+LLVM_LIBC_FUNCTION(int, clock_gettime, (clockid_t clockid, timespec *ts)) {
if (clockid != CLOCK_MONOTONIC || !ts)
return -1;
|
Summary: This patch implements `clock_gettime` using the monotonic clock. This allows users to get time elapsed at nanosecond resolution. This is primarily to facilitate compiling the `chrono` library from `libc++`. For this reason we provide both `CLOCK_MONOTONIC`, which we can implement with the GPU's global fixed-frequency clock, and `CLOCK_REALTIME` which we cannot. The latter is provided just to make people who use this header happy and it will always return failure.
…lvm#99067) Summary: This patch implements `clock_gettime` using the monotonic clock. This allows users to get time elapsed at nanosecond resolution. This is primarily to facilitate compiling the `chrono` library from `libc++`. For this reason we provide both `CLOCK_MONOTONIC`, which we can implement with the GPU's global fixed-frequency clock, and `CLOCK_REALTIME` which we cannot. The latter is provided just to make people who use this header happy and it will always return failure.
…99067) Summary: This patch implements `clock_gettime` using the monotonic clock. This allows users to get time elapsed at nanosecond resolution. This is primarily to facilitate compiling the `chrono` library from `libc++`. For this reason we provide both `CLOCK_MONOTONIC`, which we can implement with the GPU's global fixed-frequency clock, and `CLOCK_REALTIME` which we cannot. The latter is provided just to make people who use this header happy and it will always return failure.
Summary:
This patch implements
clock_gettime
using the monotonic clock. Thisallows users to get time elapsed at nanosecond resolution. This is
primarily to facilitate compiling the
chrono
library fromlibc++
.For this reason we provide both
CLOCK_MONOTONIC
, which we can implementwith the GPU's global fixed-frequency clock, and
CLOCK_REALTIME
whichwe cannot. The latter is provided just to make people who use this
header happy and it will always return failure.