[libc-commits] [libc] 8f1e362 - Implement nanosleep per https://pubs.opengroup.org/onlinepubs/009695399/basedefs/time.h.html
Jeff Bailey via libc-commits
libc-commits at lists.llvm.org
Fri Sep 23 17:14:05 PDT 2022
Author: Raman Tenneti
Date: 2022-09-24T00:13:58Z
New Revision: 8f1e362ee9275a687693448bd975194ee9b984f2
URL: https://github.com/llvm/llvm-project/commit/8f1e362ee9275a687693448bd975194ee9b984f2
DIFF: https://github.com/llvm/llvm-project/commit/8f1e362ee9275a687693448bd975194ee9b984f2.diff
LOG: Implement nanosleep per https://pubs.opengroup.org/onlinepubs/009695399/basedefs/time.h.html
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 at google.com>
Reviewed By: sivachandra, jeffbailey
Differential Revision: https://reviews.llvm.org/D134095
Added:
libc/src/time/nanosleep.cpp
libc/src/time/nanosleep.h
libc/test/src/time/nanosleep_test.cpp
Modified:
libc/config/linux/aarch64/entrypoints.txt
libc/config/linux/api.td
libc/config/linux/x86_64/entrypoints.txt
libc/include/CMakeLists.txt
libc/include/llvm-libc-types/struct_timespec.h
libc/spec/posix.td
libc/src/time/CMakeLists.txt
libc/test/src/time/CMakeLists.txt
Removed:
################################################################################
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index b506663a04b60..e05012391beaa 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -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()
diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td
index 508ef3721a64e..03559879b353d 100644
--- a/libc/config/linux/api.td
+++ b/libc/config/linux/api.td
@@ -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"> {
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index cf8c2c2d7746f..2a48c90b967d5 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -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()
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 63eb88247de04..a8aac4cfbd31d 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -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(
diff --git a/libc/include/llvm-libc-types/struct_timespec.h b/libc/include/llvm-libc-types/struct_timespec.h
index eb6e70bb578a4..1fa6272d3df92 100644
--- a/libc/include/llvm-libc-types/struct_timespec.h
+++ b/libc/include/llvm-libc-types/struct_timespec.h
@@ -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__
diff --git a/libc/spec/posix.td b/libc/spec/posix.td
index 8f8cad426ef59..d93ba16de9faf 100644
--- a/libc/spec/posix.td
+++ b/libc/spec/posix.td
@@ -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
];
diff --git a/libc/src/time/CMakeLists.txt b/libc/src/time/CMakeLists.txt
index 514b36cd852ac..880e7ed956acb 100644
--- a/libc/src/time/CMakeLists.txt
+++ b/libc/src/time/CMakeLists.txt
@@ -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
+)
diff --git a/libc/src/time/nanosleep.cpp b/libc/src/time/nanosleep.cpp
new file mode 100644
index 0000000000000..2eb5e97aff090
--- /dev/null
+++ b/libc/src/time/nanosleep.cpp
@@ -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
diff --git a/libc/src/time/nanosleep.h b/libc/src/time/nanosleep.h
new file mode 100644
index 0000000000000..5177ef0f63acd
--- /dev/null
+++ b/libc/src/time/nanosleep.h
@@ -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"
diff --git a/libc/test/src/time/CMakeLists.txt b/libc/test/src/time/CMakeLists.txt
index 9fe06e3a22974..0fe964ca4333b 100644
--- a/libc/test/src/time/CMakeLists.txt
+++ b/libc/test/src/time/CMakeLists.txt
@@ -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
+)
diff --git a/libc/test/src/time/nanosleep_test.cpp b/libc/test/src/time/nanosleep_test.cpp
new file mode 100644
index 0000000000000..2b2c90710e1a3
--- /dev/null
+++ b/libc/test/src/time/nanosleep_test.cpp
@@ -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);
+}
More information about the libc-commits
mailing list