Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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/baremetal/arm/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.time.gmtime
libc.src.time.gmtime_r
libc.src.time.mktime
libc.src.time.timespec_get

# internal entrypoints
libc.startup.baremetal.init
Expand Down
1 change: 1 addition & 0 deletions libc/config/baremetal/riscv/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.time.gmtime
libc.src.time.gmtime_r
libc.src.time.mktime
libc.src.time.timespec_get

# internal entrypoints
libc.startup.baremetal.init
Expand Down
1 change: 1 addition & 0 deletions libc/config/linux/aarch64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.time.mktime
libc.src.time.nanosleep
libc.src.time.time
libc.src.time.timespec_get

# unistd.h entrypoints
libc.src.unistd.__llvm_libc_syscall
Expand Down
1 change: 1 addition & 0 deletions libc/config/linux/riscv/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -937,6 +937,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.time.mktime
libc.src.time.nanosleep
libc.src.time.time
libc.src.time.timespec_get

# unistd.h entrypoints
libc.src.unistd.__llvm_libc_syscall
Expand Down
1 change: 1 addition & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1082,6 +1082,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.time.mktime
libc.src.time.nanosleep
libc.src.time.time
libc.src.time.timespec_get

# locale.h entrypoints
libc.src.locale.localeconv
Expand Down
2 changes: 2 additions & 0 deletions libc/include/llvm-libc-macros/time-macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@
#include "linux/time-macros.h"
#endif

#define TIME_UTC 1

#endif // LLVM_LIBC_MACROS_TIME_MACROS_H
7 changes: 7 additions & 0 deletions libc/newhdrgen/yaml/time.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,10 @@ functions:
return_type: time_t
arguments:
- type: time_t *
- name: timespec_get
standard:
- stdc
return_type: int
arguments:
- type: struct timespec *
- type: int
2 changes: 2 additions & 0 deletions libc/src/__support/OSUtil/baremetal/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ add_object_library(
SRCS
io.cpp
exit.cpp
time.cpp
HDRS
io.h
time.h
DEPENDS
libc.src.__support.common
libc.src.__support.CPP.string_view
Expand Down
23 changes: 23 additions & 0 deletions libc/src/__support/OSUtil/baremetal/time.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//===---------- Baremetal implementation of time utils ----------*- C++ -*-===//
//
// 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 "time.h"

#include "src/__support/macros/config.h"

namespace LIBC_NAMESPACE_DECL {
namespace internal {

extern "C" int __llvm_libc_timespec_get_utc(struct timespec *ts);

bool timespec_get_utc(struct timespec *ts) {
return __llvm_libc_timespec_get_utc(ts);
}

} // namespace internal
} // namespace LIBC_NAMESPACE_DECL
23 changes: 23 additions & 0 deletions libc/src/__support/OSUtil/baremetal/time.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//===---------- Baremetal implementation of time utils ----------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_BAREMETAL_TIME_H
#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_BAREMETAL_TIME_H

#include "include/llvm-libc-types/struct_timespec.h"
#include "src/__support/macros/config.h"

namespace LIBC_NAMESPACE_DECL {
namespace internal {

bool timespec_get_utc(struct timespec *ts);

} // namespace internal
} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_BAREMETAL_IO_H
7 changes: 7 additions & 0 deletions libc/src/time/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ add_entrypoint_object(
.${LIBC_TARGET_OS}.time
)

add_entrypoint_object(
timespec_get
ALIAS
DEPENDS
.${LIBC_TARGET_OS}.timespec_get
)

add_entrypoint_object(
clock
ALIAS
Expand Down
11 changes: 11 additions & 0 deletions libc/src/time/baremetal/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
add_entrypoint_object(
timespec_get
SRCS
timespec_get.cpp
HDRS
../timespec_get.h
DEPENDS
libc.hdr.time_macros
libc.hdr.types.struct_timespec
libc.src.__support.OSUtil.osutil
)
28 changes: 28 additions & 0 deletions libc/src/time/baremetal/timespec_get.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//===-- Implementation of timespec_get for baremetal ----------------------===//
//
// 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/timespec_get.h"
#include "hdr/time_macros.h"
#include "src/__support/OSUtil/baremetal/time.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, timespec_get, (struct timespec * ts, int base)) {
if (base != TIME_UTC) {
return 0;
}

if (!internal::timespec_get_utc(ts)) {
return 0;
}
return base;
}

} // namespace LIBC_NAMESPACE_DECL
13 changes: 13 additions & 0 deletions libc/src/time/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ add_entrypoint_object(
libc.src.errno.errno
)

add_entrypoint_object(
timespec_get
SRCS
timespec_get.cpp
HDRS
../timespec_get.h
DEPENDS
libc.hdr.time_macros
libc.hdr.types.struct_timespec
libc.src.__support.time.linux.clock_gettime
libc.src.errno.errno
)

add_entrypoint_object(
clock
SRCS
Expand Down
31 changes: 31 additions & 0 deletions libc/src/time/linux/timespec_get.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//===-- Implementation of timespec_get for Linux --------------------------===//
//
// 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/timespec_get.h"
#include "hdr/time_macros.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/time/linux/clock_gettime.h"
#include "src/errno/libc_errno.h"

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, timespec_get, (struct timespec * ts, int base)) {
if (base != TIME_UTC) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please file a TODO (then link to it from a comment in the sources) about supporting the other specified bases (TIME_MONOTONIC, TIME_ACTIVE, and TIME_THREAD_ACTIVE). Especially since 7.29.2.6.5 recommends:

Because of its wider value range and improved indications on error, timespec_get with time base TIME_ACTIVE should be used instead of clock by new code whenever possible.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't aware of these, looks they were added in the latest standard (and aren't even mentioned on https://en.cppreference.com/w/c/chrono/timespec_get). I implemented all of them for Linux since it was straightforward.

return 0;
}

auto result = internal::clock_gettime(CLOCK_REALTIME, ts);
if (!result.has_value()) {
libc_errno = result.error();
return 0;
}
return base;
}

} // namespace LIBC_NAMESPACE_DECL
21 changes: 21 additions & 0 deletions libc/src/time/timespec_get.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation header of timespec_get -------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_TIME_TIMESPEC_GET_H
#define LLVM_LIBC_SRC_TIME_TIMESPEC_GET_H

#include "src/__support/macros/config.h"
#include <time.h>

namespace LIBC_NAMESPACE_DECL {

int timespec_get(struct timespec *ts, int base);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_TIME_TIMESPEC_GET_H
10 changes: 10 additions & 0 deletions libc/test/src/time/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,16 @@ add_libc_unittest(
libc.src.errno.errno
)

add_libc_test(
timespec_get_test
SUITE
libc_time_unittests
SRCS
timespec_get_test.cpp
DEPENDS
libc.src.time.timespec_get
)

add_libc_test(
clock_test
SUITE
Expand Down
32 changes: 32 additions & 0 deletions libc/test/src/time/timespec_get_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//===-- Unittests for timespec_get ----------------------------------------===//
//
// 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/__support/macros/properties/architectures.h"
#include "src/time/timespec_get.h"
#include "test/UnitTest/Test.h"

#include <time.h>

TEST(LlvmLibcTimespecGet, Utc) {
#ifndef LIBC_TARGET_ARCH_IS_GPU
timespec ts;
int result;
result = LIBC_NAMESPACE::timespec_get(&ts, TIME_UTC);
ASSERT_EQ(result, TIME_UTC);
ASSERT_GT(ts.tv_sec, time_t(0));
#endif
}

TEST(LlvmLibcTimespecGet, Unknown) {
#ifndef LIBC_TARGET_ARCH_IS_GPU
timespec ts;
int result;
result = LIBC_NAMESPACE::timespec_get(&ts, 0);
ASSERT_EQ(result, 0);
#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How come these tests are disabled on the GPU?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GPU doesn't support UTC clock, it only implements monotonic clock. I could do the same for TIME_MONOTONIC and for TIME_UTC just return 0. @jhuber6 what do you think?

}
Loading