Skip to content
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

Merged
merged 1 commit into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libc/config/gpu/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions libc/docs/gpu/support.rst
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ time.h
Function Name Available RPC Required
============= ========= ============
clock |check|
clock_gettime |check|
nanosleep |check|
============= ========= ============

Expand Down
3 changes: 3 additions & 0 deletions libc/include/llvm-libc-macros/gpu/time-macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 2 additions & 0 deletions libc/include/time.h.def
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
12 changes: 12 additions & 0 deletions libc/src/time/gpu/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
32 changes: 32 additions & 0 deletions libc/src/time/gpu/clock_gettime.cpp
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion libc/test/src/time/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 9 additions & 2 deletions libc/test/src/time/clock_gettime_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading