[libc] add clock_gettime

Add the clock_gettime syscall wrapper and tests.

Reviewed By: sivachandra

Differential Revision: https://reviews.llvm.org/D134773
This commit is contained in:
Michael Jones 2022-09-23 14:00:52 -07:00
parent c4d9b40574
commit b49d626cb4
16 changed files with 189 additions and 4 deletions

View File

@ -171,7 +171,7 @@ def StdlibAPI : PublicAPI<"stdlib.h"> {
}
def TimeAPI : PublicAPI<"time.h"> {
let Types = ["time_t", "struct tm", "struct timespec"];
let Types = ["time_t", "struct tm", "struct timespec", "clockid_t",];
}
def ErrnoAPI : PublicAPI<"errno.h"> {

View File

@ -395,6 +395,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.time.gmtime_r
libc.src.time.mktime
libc.src.time.nanosleep
libc.src.time.clock_gettime
)
endif()

View File

@ -91,7 +91,9 @@ add_gen_header(
GEN_HDR time.h
DEPENDS
.llvm_libc_common_h
.llvm-libc-macros.time_macros
.llvm-libc-types.time_t
.llvm-libc-types.clockid_t
.llvm-libc-types.struct_tm
.llvm-libc-types.struct_timespec
)

View File

@ -38,6 +38,14 @@ add_header(
.linux.sys_resource_macros
)
add_header(
time_macros
HDR
time-macros.h
DEPENDS
.linux.time_macros
)
add_header(
unistd_macros
HDR

View File

@ -16,6 +16,12 @@ add_header(
sys-stat-macros.h
)
add_header(
time_macros
HDR
time-macros.h
)
add_header(
sys_resource_macros
HDR

View File

@ -0,0 +1,24 @@
//===-- Definition of macros from time.h ---------------------------------===//
//
// 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_MACROS_LINUX_TIME_MACROS_H
#define __LLVM_LIBC_MACROS_LINUX_TIME_MACROS_H
// clock type macros
#define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 1
#define CLOCK_PROCESS_CPUTIME_ID 2
#define CLOCK_THREAD_CPUTIME_ID 3
#define CLOCK_MONOTONIC_RAW 4
#define CLOCK_REALTIME_COARSE 5
#define CLOCK_MONOTONIC_COARSE 6
#define CLOCK_BOOTTIME 7
#define CLOCK_REALTIME_ALARM 8
#define CLOCK_BOOTTIME_ALARM 9
#endif //__LLVM_LIBC_MACROS_LINUX_TIME_MACROS_H

View File

@ -0,0 +1,8 @@
#ifndef __LLVM_LIBC_MACROS_TIME_MACROS_H
#define __LLVM_LIBC_MACROS_TIME_MACROS_H
#ifdef __unix__
#include "linux/time-macros.h"
#endif
#endif // __LLVM_LIBC_MACROS_TIME_MACROS_H

View File

@ -12,6 +12,7 @@ add_header(__sighandler_t HDR __sighandler_t.h)
add_header(__thread_type HDR __thread_type.h)
add_header(blkcnt_t HDR blkcnt_t.h)
add_header(blksize_t HDR blksize_t.h)
add_header(clockid_t HDR clockid_t.h)
add_header(cnd_t HDR cnd_t.h)
add_header(cookie_io_functions_t HDR cookie_io_functions_t.h DEPENDS .off64_t)
add_header(double_t HDR double_t.h)

View File

@ -0,0 +1,14 @@
//===-- Definition of the type clockid_t ----------------------------------===//
//
// 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_TYPES_CLOCKID_T_H__
#define __LLVM_LIBC_TYPES_CLOCKID_T_H__
typedef int clockid_t;
#endif // __LLVM_LIBC_TYPES_CLOCKID_T_H__

View File

@ -10,6 +10,7 @@
#define LLVM_LIBC_TIME_H
#include <__llvm-libc-common.h>
#include <llvm-libc-macros/time-macros.h>
%%public_api()

View File

@ -22,10 +22,10 @@ def InoT : NamedType<"ino_t">;
def UidT : NamedType<"uid_t">;
def GidT : NamedType<"gid_t">;
def DevT : NamedType<"dev_t">;
def ClockIdT : NamedType<"clockid_t">;
def BlkSizeT : NamedType<"blksize_t">;
def BlkCntT : NamedType<"blkcnt_t">;
def NLinkT : NamedType<"nlink_t">;
def TimeSpec : NamedType<"struct timespec">;
def PidT : NamedType<"pid_t">;
def StatType : NamedType<"struct stat">;
@ -608,7 +608,7 @@ def POSIX : StandardSpec<"POSIX"> {
HeaderSpec SysStat = HeaderSpec<
"sys/stat.h",
[], // Macros
[ModeTType, DevT, InoT, UidT, GidT, TimeSpec, BlkSizeT, BlkCntT, OffTType, NLinkT, StatType], // Types
[ModeTType, DevT, InoT, UidT, GidT, StructTimeSpec, BlkSizeT, BlkCntT, OffTType, NLinkT, StatType], // Types
[], // Enumerations
[
FunctionSpec<
@ -935,7 +935,7 @@ def POSIX : StandardSpec<"POSIX"> {
HeaderSpec Time = HeaderSpec<
"time.h",
[], // Macros
[StructTimeSpec], // Types
[ClockIdT, StructTimeSpec], // Types
[], // Enumerations
[
FunctionSpec<
@ -946,6 +946,11 @@ def POSIX : StandardSpec<"POSIX"> {
ArgSpec<StructTimeSpecPtr>,
]
>,
FunctionSpec<
"clock_gettime",
RetValSpec<IntType>,
[ArgSpec<ClockIdT>,ArgSpec<StructTimeSpecPtr>]
>,
]
>;

View File

@ -32,6 +32,19 @@ add_entrypoint_object(
libc.include.time
)
add_entrypoint_object(
clock_gettime
SRCS
clock_gettime.cpp
HDRS
clock_gettime.h
DEPENDS
libc.include.time
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
libc.src.errno.errno
)
add_entrypoint_object(
gmtime
SRCS

View File

@ -0,0 +1,36 @@
//===---------- Linux 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/OSUtil/syscall.h" // For internal syscall function.
#include "src/__support/common.h"
#include <errno.h>
#include <sys/syscall.h> // For syscall numbers.
#include <time.h>
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, clock_gettime,
(clockid_t clockid, struct timespec *tp)) {
long ret_val =
__llvm_libc::syscall(SYS_clock_gettime, static_cast<long>(clockid),
reinterpret_cast<long>(tp));
// A negative return value indicates an error with the magnitude of the
// value being the error code.
if (ret_val < 0) {
errno = -ret_val;
return -1;
}
return 0;
}
} // namespace __llvm_libc

View File

@ -0,0 +1,20 @@
//===-- Implementation header for clock_gettime function --------*- 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_CLOCK_GETTIME_H
#define LLVM_LIBC_SRC_TIME_CLOCK_GETTIME_H
#include <time.h>
namespace __llvm_libc {
int clock_gettime(clockid_t clockid, struct timespec *tp);
} // namespace __llvm_libc
#endif // LLVM_LIBC_SRC_TIME_CLOCK_GETTIME_H

View File

@ -30,6 +30,16 @@ add_libc_unittest(
libc.src.time.asctime_r
)
add_libc_unittest(
clock_gettime
SUITE
libc_time_unittests
SRCS
clock_gettime_test.cpp
DEPENDS
libc.src.time.clock_gettime
)
add_libc_unittest(
gmtime
SUITE

View File

@ -0,0 +1,36 @@
//===-- Unittests for clock_gettime ---------------------------------------===//
//
// 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 "utils/UnitTest/Test.h"
#include <time.h>
TEST(LlvmLibcClockGetTime, RealTime) {
struct timespec tp;
int result;
result = clock_gettime(CLOCK_REALTIME, &tp);
ASSERT_EQ(result, 0);
ASSERT_GT(tp.tv_sec, time_t(0));
}
#ifdef CLOCK_MONOTONIC
TEST(LlvmLibcClockGetTime, MonotonicTime) {
struct timespec tp1, tp2;
int result;
result = clock_gettime(CLOCK_MONOTONIC, &tp1);
ASSERT_EQ(result, 0);
ASSERT_GT(tp1.tv_sec, time_t(0));
result = clock_gettime(CLOCK_MONOTONIC, &tp2);
ASSERT_EQ(result, 0);
ASSERT_GE(tp2.tv_sec, tp1.tv_sec); // The monotonic clock should increase.
if (tp2.tv_sec == tp1.tv_sec) {
ASSERT_GE(tp2.tv_nsec, tp1.tv_nsec);
}
}
#endif // CLOCK_MONOTONIC