[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