[libc-commits] [libc] [libc] Implement `clock_gettime` for the monotonic clock on the GPU (PR #99067)
Joseph Huber via libc-commits
libc-commits at lists.llvm.org
Tue Jul 16 12:50:29 PDT 2024
https://github.com/jhuber6 updated https://github.com/llvm/llvm-project/pull/99067
>From 8e4d424ec47fb54823416eec9521f726b687c0bf Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Tue, 16 Jul 2024 12:38:13 -0500
Subject: [PATCH 1/2] [libc] Implement `clock_gettime` for the monotonic clock
on the GPU
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.
---
libc/config/gpu/entrypoints.txt | 1 +
libc/docs/gpu/support.rst | 1 +
.../llvm-libc-macros/gpu/time-macros.h | 3 ++
libc/include/time.h.def | 2 ++
libc/src/time/gpu/CMakeLists.txt | 12 +++++++
libc/src/time/gpu/clock_gettime.cpp | 33 +++++++++++++++++++
libc/test/src/time/CMakeLists.txt | 2 +-
libc/test/src/time/clock_gettime_test.cpp | 7 ++++
8 files changed, 60 insertions(+), 1 deletion(-)
create mode 100644 libc/src/time/gpu/clock_gettime.cpp
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
>From 5e6da5b66b65c29aff7ae49245e9a3371bf6d092 Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Tue, 16 Jul 2024 14:50:22 -0500
Subject: [PATCH 2/2] Update libc/src/time/gpu/clock_gettime.cpp
---
libc/src/time/gpu/clock_gettime.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/time/gpu/clock_gettime.cpp b/libc/src/time/gpu/clock_gettime.cpp
index fd36b7fcb05e2..7241d5b6e82d2 100644
--- a/libc/src/time/gpu/clock_gettime.cpp
+++ b/libc/src/time/gpu/clock_gettime.cpp
@@ -17,7 +17,7 @@ namespace LIBC_NAMESPACE_DECL {
constexpr uint64_t TICKS_PER_SEC = 1000000000UL;
LLVM_LIBC_FUNCTION(int, clock_gettime,
- (clockid_t clockid, struct timespec *ts)) {
+ (clockid_t clockid, timespec *ts)) {
if (clockid != CLOCK_MONOTONIC || !ts)
return -1;
More information about the libc-commits
mailing list