Tested:
Limited unit test: This makes a call and checks that no error was
returned, but we currently don't have the ability to ensure that
time has elapsed as expected.

Co-authored-by: Jeff Bailey <jeffbailey@google.com>

Reviewed By: sivachandra, jeffbailey

Differential Revision: https://reviews.llvm.org/D134095
This commit is contained in:
Raman Tenneti 2022-09-24 00:13:23 +00:00 committed by Jeff Bailey
parent 3bbb2c2d99
commit 8f1e362ee9
11 changed files with 140 additions and 3 deletions

View File

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

View File

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

View File

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

View File

@ -93,6 +93,7 @@ add_gen_header(
.llvm_libc_common_h
.llvm-libc-types.time_t
.llvm-libc-types.struct_tm
.llvm-libc-types.struct_timespec
)
add_gen_header(

View File

@ -12,8 +12,9 @@
#include <llvm-libc-types/time_t.h>
struct timespec {
time_t tv_sec;
long tv_nsec;
time_t tv_sec; /* Seconds. */
/* TODO: BIG_ENDIAN may require padding. */
long tv_nsec; /* Nanoseconds. */
};
#endif // __LLVM_LIBC_TYPES_TIMESPEC_H__

View File

@ -37,6 +37,9 @@ def StructDirentPtr : PtrType<StructDirent>;
def StructDirentPtrPtr : PtrType<StructDirentPtr>;
def ConstStructDirentPtrPtr : ConstType<StructDirentPtrPtr>;
def StructTimeSpec : NamedType<"struct timespec">;
def StructTimeSpecPtr : PtrType<StructTimeSpec>;
def POSIX : StandardSpec<"POSIX"> {
PtrType CharPtr = PtrType<CharType>;
RestrictedPtrType RestrictedCharPtr = RestrictedPtrType<CharType>;
@ -919,6 +922,23 @@ def POSIX : StandardSpec<"POSIX"> {
]
>;
HeaderSpec Time = HeaderSpec<
"time.h",
[], // Macros
[StructTimeSpec], // Types
[], // Enumerations
[
FunctionSpec<
"nanosleep",
RetValSpec<IntType>,
[
ArgSpec<StructTimeSpecPtr>,
ArgSpec<StructTimeSpecPtr>,
]
>,
]
>;
let Headers = [
CType,
Dirent,
@ -932,6 +952,7 @@ def POSIX : StandardSpec<"POSIX"> {
SysResource,
SysStat,
SysUtsName,
Time,
UniStd,
String
];

View File

@ -66,3 +66,17 @@ add_entrypoint_object(
libc.include.time
libc.src.errno.errno
)
add_entrypoint_object(
nanosleep
SRCS
nanosleep.cpp
HDRS
nanosleep.h
DEPENDS
libc.include.errno
libc.include.time
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
libc.src.errno.errno
)

View File

@ -0,0 +1,29 @@
//===-- Implementation of nanosleep 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/nanosleep.h"
#include "include/sys/syscall.h" // For syscall numbers.
#include "src/__support/OSUtil/syscall.h" // For syscall functions.
#include "src/__support/common.h"
#include <errno.h>
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, nanosleep,
(const struct timespec *req, struct timespec *rem)) {
int ret = __llvm_libc::syscall(SYS_nanosleep, req, rem);
if (ret < 0) {
errno = -ret;
return -1;
}
return ret;
}
} // namespace __llvm_libc

23
libc/src/time/nanosleep.h Normal file
View File

@ -0,0 +1,23 @@
//===-- Implementation header of nanosleep -------------------------*- 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_NANOSLEEP_H
#define LLVM_LIBC_SRC_TIME_NANOSLEEP_H
#include <time.h>
namespace __llvm_libc {
int nanosleep(const struct timespec *req, struct timespec *rem);
} // namespace __llvm_libc
#endif // LLVM_LIBC_SRC_TIME_NANOSLEEP_H
#include "include/time.h"

View File

@ -68,3 +68,20 @@ add_libc_unittest(
DEPENDS
libc.src.time.mktime
)
add_libc_unittest(
nanosleep
SUITE
libc_time_unittests
SRCS
nanosleep_test.cpp
HDRS
TmHelper.h
TmMatcher.h
CXX_STANDARD
20
DEPENDS
libc.include.errno
libc.include.time
libc.src.time.nanosleep
)

View File

@ -0,0 +1,29 @@
//===-- Unittests for nanosleep
//---------------------------------------------===//
//
// 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 <errno.h>
#include <time.h>
#include "src/time/nanosleep.h"
#include "test/ErrnoSetterMatcher.h"
#include "utils/UnitTest/Test.h"
namespace cpp = __llvm_libc::cpp;
TEST(LlvmLibcNanosleep, SmokeTest) {
// TODO: When we have the code to read clocks, test that time has passed.
using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds;
errno = 0;
struct timespec tim = {1, 500};
struct timespec tim2 = {0, 0};
int ret = __llvm_libc::nanosleep(&tim, &tim2);
ASSERT_EQ(errno, 0);
ASSERT_EQ(ret, 0);
}