forked from llvm/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[libc] Implement
timespec_get
(llvm#116102)
`timespec_get` is C standard counterpart to POSIX `clock_gettime`. On Linux we simply use `clock_gettime`. On baremetal we introduce a new external API `__llvm_libc_timespec_get_utc` that should be implemented by the vendor.
- Loading branch information
Showing
18 changed files
with
245 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
add_entrypoint_object( | ||
timespec_get | ||
SRCS | ||
timespec_get.cpp | ||
HDRS | ||
../timespec_get.h | ||
DEPENDS | ||
libc.hdr.time_macros | ||
libc.hdr.types.struct_timespec | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
//===-- 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/common.h" | ||
#include "src/__support/macros/config.h" | ||
|
||
namespace LIBC_NAMESPACE_DECL { | ||
|
||
extern "C" bool __llvm_libc_timespec_get_utc(struct timespec *ts); | ||
|
||
LLVM_LIBC_FUNCTION(int, timespec_get, (struct timespec * ts, int base)) { | ||
if (base != TIME_UTC) | ||
return 0; | ||
|
||
if (!__llvm_libc_timespec_get_utc(ts)) | ||
return 0; | ||
return base; | ||
} | ||
|
||
} // namespace LIBC_NAMESPACE_DECL |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
//===-- Implementation of timespec_get for gpu ----------------------------===// | ||
// | ||
// 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" | ||
|
||
namespace LIBC_NAMESPACE_DECL { | ||
|
||
LLVM_LIBC_FUNCTION(int, timespec_get, (struct timespec * ts, int base)) { | ||
if (base != TIME_MONOTONIC || !ts) | ||
return 0; | ||
|
||
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 base; | ||
} | ||
|
||
} // namespace LIBC_NAMESPACE_DECL |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
//===-- 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)) { | ||
clockid_t clockid; | ||
switch (base) { | ||
case TIME_UTC: | ||
clockid = CLOCK_REALTIME; | ||
break; | ||
case TIME_MONOTONIC: | ||
clockid = CLOCK_MONOTONIC; | ||
break; | ||
case TIME_ACTIVE: | ||
clockid = CLOCK_PROCESS_CPUTIME_ID; | ||
break; | ||
case TIME_THREAD_ACTIVE: | ||
clockid = CLOCK_THREAD_CPUTIME_ID; | ||
break; | ||
default: | ||
return 0; | ||
} | ||
|
||
auto result = internal::clock_gettime(clockid, ts); | ||
if (!result.has_value()) { | ||
libc_errno = result.error(); | ||
return 0; | ||
} | ||
return base; | ||
} | ||
|
||
} // namespace LIBC_NAMESPACE_DECL |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 "hdr/types/struct_timespec.h" | ||
#include "src/__support/macros/config.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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
//===-- 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 "hdr/time_macros.h" | ||
#include "hdr/types/struct_timespec.h" | ||
#include "src/__support/macros/properties/architectures.h" | ||
#include "src/time/timespec_get.h" | ||
#include "test/UnitTest/Test.h" | ||
|
||
TEST(LlvmLibcTimespecGet, Utc) { | ||
timespec ts; | ||
int result; | ||
result = LIBC_NAMESPACE::timespec_get(&ts, TIME_UTC); | ||
#ifdef LIBC_TARGET_ARCH_IS_GPU | ||
ASSERT_EQ(result, 0); | ||
#else | ||
ASSERT_EQ(result, TIME_UTC); | ||
ASSERT_GT(ts.tv_sec, time_t(0)); | ||
#endif | ||
} | ||
|
||
TEST(LlvmLibcTimespecGet, Monotonic) { | ||
timespec ts1, ts2; | ||
int result; | ||
result = LIBC_NAMESPACE::timespec_get(&ts1, TIME_MONOTONIC); | ||
ASSERT_EQ(result, TIME_MONOTONIC); | ||
ASSERT_GT(ts1.tv_sec, time_t(0)); | ||
result = LIBC_NAMESPACE::timespec_get(&ts2, TIME_MONOTONIC); | ||
ASSERT_EQ(result, TIME_MONOTONIC); | ||
ASSERT_GE(ts2.tv_sec, ts1.tv_sec); // The monotonic time should increase. | ||
if (ts2.tv_sec == ts1.tv_sec) { | ||
ASSERT_GE(ts2.tv_nsec, ts1.tv_nsec); | ||
} | ||
} | ||
|
||
TEST(LlvmLibcTimespecGet, Unknown) { | ||
timespec ts; | ||
int result; | ||
result = LIBC_NAMESPACE::timespec_get(&ts, 0); | ||
ASSERT_EQ(result, 0); | ||
} |