[libc-commits] [libc] 8393ea5 - [libc] Implement `clock_gettime` for the monotonic clock on the GPU (#99067)
via libc-commits
libc-commits at lists.llvm.org
Tue Jul 16 14:17:37 PDT 2024
Author: Joseph Huber
Date: 2024-07-16T16:17:34-05:00
New Revision: 8393ea5d1dd8e8b56a87a6edbca31fb8722cee48
URL: https://github.com/llvm/llvm-project/commit/8393ea5d1dd8e8b56a87a6edbca31fb8722cee48
DIFF: https://github.com/llvm/llvm-project/commit/8393ea5d1dd8e8b56a87a6edbca31fb8722cee48.diff
LOG: [libc] Implement `clock_gettime` for the monotonic clock on the GPU (#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.
Added:
libc/src/time/gpu/clock_gettime.cpp
Modified:
libc/config/gpu/entrypoints.txt
libc/docs/gpu/support.rst
libc/include/llvm-libc-macros/gpu/time-macros.h
libc/include/time.h.def
libc/src/time/gpu/CMakeLists.txt
libc/test/src/time/CMakeLists.txt
libc/test/src/time/clock_gettime_test.cpp
Removed:
################################################################################
diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt
index 36c5b8c808528..b0c4652c6b8ee 100644
--- a/libc/config/gpu/entrypoints.txt
+++ b/libc/config/gpu/entrypoints.txt
@@ -218,6 +218,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..de7899a2a17cc
--- /dev/null
+++ b/libc/src/time/gpu/clock_gettime.cpp
@@ -0,0 +1,32 @@
+//===---------- 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, 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..43715c0265f1f 100644
--- a/libc/test/src/time/clock_gettime_test.cpp
+++ b/libc/test/src/time/clock_gettime_test.cpp
@@ -6,22 +6,29 @@
//
//===----------------------------------------------------------------------===//
+#include "src/__support/macros/properties/architectures.h"
#include "src/time/clock_gettime.h"
#include "test/UnitTest/Test.h"
#include <time.h>
TEST(LlvmLibcClockGetTime, RealTime) {
- struct timespec tp;
+ 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
TEST(LlvmLibcClockGetTime, MonotonicTime) {
- struct timespec tp1, tp2;
+ timespec tp1, tp2;
int result;
result = LIBC_NAMESPACE::clock_gettime(CLOCK_MONOTONIC, &tp1);
ASSERT_EQ(result, 0);
More information about the libc-commits
mailing list