[libc-commits] [libc] 8877db4 - [libc] Implement sleep and usleep for Linux (#213912)
via libc-commits
libc-commits at lists.llvm.org
Thu Aug 6 00:14:46 PDT 2026
Author: Pavel Labath
Date: 2026-08-06T09:14:41+02:00
New Revision: 8877db40d77e1a2e1cc3cb3a01bcf963bd4cda01
URL: https://github.com/llvm/llvm-project/commit/8877db40d77e1a2e1cc3cb3a01bcf963bd4cda01
DIFF: https://github.com/llvm/llvm-project/commit/8877db40d77e1a2e1cc3cb3a01bcf963bd4cda01.diff
LOG: [libc] Implement sleep and usleep for Linux (#213912)
Implemented the sleep and usleep entrypoints for Linux. Refactored the
syscall implementation out of the public nanosleep entrypoint into a
standard internal syscall wrapper.
Fixes #214293.
Co-authored-by: Jeff Bailey <jbailey at raspberryginger.com>
Added:
libc/hdr/types/useconds_t.h
libc/src/__support/OSUtil/linux/syscall_wrappers/nanosleep.h
libc/src/unistd/linux/sleep.cpp
libc/src/unistd/linux/usleep.cpp
libc/src/unistd/sleep.h
libc/src/unistd/usleep.h
libc/test/src/unistd/sleep_test.cpp
libc/test/src/unistd/usleep_test.cpp
Modified:
libc/config/linux/aarch64/entrypoints.txt
libc/config/linux/riscv/entrypoints.txt
libc/config/linux/x86_64/entrypoints.txt
libc/hdr/types/CMakeLists.txt
libc/include/CMakeLists.txt
libc/include/unistd.yaml
libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
libc/src/time/linux/CMakeLists.txt
libc/src/time/linux/nanosleep.cpp
libc/src/unistd/CMakeLists.txt
libc/src/unistd/linux/CMakeLists.txt
libc/test/src/time/CMakeLists.txt
libc/test/src/unistd/CMakeLists.txt
Removed:
################################################################################
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index c2c037c51ea08d..1d5244b9c443e3 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -411,12 +411,14 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.unistd.readlinkat
libc.src.unistd.rmdir
libc.src.unistd.setsid
+ libc.src.unistd.sleep
libc.src.unistd.symlink
libc.src.unistd.symlinkat
libc.src.unistd.sysconf
libc.src.unistd.truncate
libc.src.unistd.unlink
libc.src.unistd.unlinkat
+ libc.src.unistd.usleep
libc.src.unistd.write
# wchar.h entrypoints
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 4e3a383baa3ede..0f7822b36a761b 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -447,12 +447,14 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.unistd.readlinkat
libc.src.unistd.rmdir
libc.src.unistd.setsid
+ libc.src.unistd.sleep
libc.src.unistd.symlink
libc.src.unistd.symlinkat
libc.src.unistd.sysconf
libc.src.unistd.truncate
libc.src.unistd.unlink
libc.src.unistd.unlinkat
+ libc.src.unistd.usleep
libc.src.unistd.write
# wchar.h entrypoints
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 5e848146594bb9..7a9e741310c6ac 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -452,12 +452,14 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.unistd.readlinkat
libc.src.unistd.rmdir
libc.src.unistd.setsid
+ libc.src.unistd.sleep
libc.src.unistd.symlink
libc.src.unistd.symlinkat
libc.src.unistd.sysconf
libc.src.unistd.truncate
libc.src.unistd.unlink
libc.src.unistd.unlinkat
+ libc.src.unistd.usleep
libc.src.unistd.write
# wchar.h entrypoints
diff --git a/libc/hdr/types/CMakeLists.txt b/libc/hdr/types/CMakeLists.txt
index 23dbd98d52203b..f56ddda2dc9fe4 100644
--- a/libc/hdr/types/CMakeLists.txt
+++ b/libc/hdr/types/CMakeLists.txt
@@ -298,6 +298,14 @@ add_proxy_header_library(
libc.include.sys_time
)
+add_proxy_header_library(
+ useconds_t
+ HDRS
+ useconds_t.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.useconds_t
+)
+
add_proxy_header_library(
struct_timeval
HDRS
@@ -711,7 +719,6 @@ add_proxy_header_library(
libc.include.wchar
)
-
add_proxy_header_library(
wctype_t
HDRS
diff --git a/libc/hdr/types/useconds_t.h b/libc/hdr/types/useconds_t.h
new file mode 100644
index 00000000000000..c6e26bdbf81ef2
--- /dev/null
+++ b/libc/hdr/types/useconds_t.h
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Proxy header for the useconds_t type.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_USECONDS_T_H
+#define LLVM_LIBC_HDR_TYPES_USECONDS_T_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/useconds_t.h"
+
+#else // Overlay mode
+
+#include <sys/types.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_USECONDS_T_H
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index add1411a9f95ce..b77f149b2f65de 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -490,6 +490,7 @@ add_header_macro(
.llvm-libc-types.size_t
.llvm-libc-types.ssize_t
.llvm-libc-types.uid_t
+ .llvm-libc-types.useconds_t
.llvm-libc-types.__getoptargv_t
)
diff --git a/libc/include/unistd.yaml b/libc/include/unistd.yaml
index c1ae4567bfc026..4b3703af7798ea 100644
--- a/libc/include/unistd.yaml
+++ b/libc/include/unistd.yaml
@@ -42,6 +42,7 @@ types:
- type_name: __getoptargv_t
- type_name: __exec_envp_t
- type_name: __exec_argv_t
+ - type_name: useconds_t
enums: []
objects:
- object_name: environ
@@ -384,6 +385,12 @@ functions:
return_type: pid_t
arguments:
- type: void
+ - name: sleep
+ standards:
+ - posix
+ return_type: unsigned int
+ arguments:
+ - type: unsigned int
- name: symlink
standards:
- posix
@@ -426,6 +433,12 @@ functions:
- type: int
- type: const char *
- type: int
+ - name: usleep
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: useconds_t
- name: write
standards:
- posix
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
index a45641483bbef2..2b22bb8e733de3 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
@@ -745,7 +745,6 @@ add_header_library(
libc.include.sys_syscall
)
-
add_header_library(
dup
HDRS
@@ -927,3 +926,17 @@ add_header_library(
libc.src.__support.macros.config
libc.include.sys_syscall
)
+
+add_header_library(
+ nanosleep
+ HDRS
+ nanosleep.h
+ DEPENDS
+ libc.hdr.types.struct_timespec
+ libc.hdr.time_macros
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+ libc.include.sys_syscall
+)
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/nanosleep.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/nanosleep.h
new file mode 100644
index 00000000000000..694becbd395b58
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/nanosleep.h
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for nanosleep syscall wrapper.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_NANOSLEEP_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_NANOSLEEP_H
+
+#include "hdr/time_macros.h"
+#include "hdr/types/struct_timespec.h"
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h>
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> nanosleep(const timespec *req, timespec *rem) {
+#if defined(SYS_clock_nanosleep_time64)
+ static_assert(
+ sizeof(time_t) == sizeof(int64_t),
+ "SYS_clock_nanosleep_time64 requires struct timespec with 64-bit "
+ "members.");
+ return syscall_checked<int>(SYS_clock_nanosleep_time64, CLOCK_REALTIME, 0,
+ req, rem);
+#elif defined(SYS_nanosleep)
+ static_assert(
+ sizeof(timespec::tv_nsec) == sizeof(long),
+ "This legacy syscall fallback is only safe on platforms where tv_nsec "
+ "matches the register size (long). It is unsafe on 32-bit platforms "
+ "with 64-bit tv_nsec.");
+ return syscall_checked<int>(SYS_nanosleep, req, rem);
+#else
+#error "SYS_nanosleep and SYS_clock_nanosleep_time64 syscalls not available."
+#endif
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_NANOSLEEP_H
diff --git a/libc/src/time/linux/CMakeLists.txt b/libc/src/time/linux/CMakeLists.txt
index 4b4b84277e7bf1..e605b53b9eb29c 100644
--- a/libc/src/time/linux/CMakeLists.txt
+++ b/libc/src/time/linux/CMakeLists.txt
@@ -40,10 +40,10 @@ add_entrypoint_object(
../nanosleep.h
DEPENDS
libc.hdr.types.struct_timespec
- libc.hdr.stdint_proxy
- libc.include.sys_syscall
- libc.src.__support.OSUtil.osutil
- libc.src.__support.CPP.limits
+ libc.src.__support.OSUtil.linux.syscall_wrappers.nanosleep
+ libc.src.__support.common
+ libc.src.__support.libc_errno
+ libc.src.__support.macros.config
libc.src.errno.errno
)
diff --git a/libc/src/time/linux/nanosleep.cpp b/libc/src/time/linux/nanosleep.cpp
index 15b119ead20c6f..872a1b27110dee 100644
--- a/libc/src/time/linux/nanosleep.cpp
+++ b/libc/src/time/linux/nanosleep.cpp
@@ -1,43 +1,31 @@
-//===-- Linux 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
//
//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Linux implementation of nanosleep function.
+///
+//===----------------------------------------------------------------------===//
#include "src/time/nanosleep.h"
-#include "hdr/stdint_proxy.h" // For int64_t.
-#include "hdr/time_macros.h"
-#include "src/__support/OSUtil/syscall.h" // For syscall functions.
+#include "src/__support/OSUtil/linux/syscall_wrappers/nanosleep.h"
#include "src/__support/common.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
-#include <sys/syscall.h> // For syscall numbers.
-
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(int, nanosleep, (const timespec *req, timespec *rem)) {
-#if defined(SYS_clock_nanosleep_time64)
- int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_nanosleep_time64,
- CLOCK_REALTIME, 0, req, rem);
-#elif defined(SYS_nanosleep)
- static_assert(
- sizeof(timespec::tv_nsec) == sizeof(long),
- "This legacy syscall fallback is only safe on platforms where tv_nsec "
- "matches the register size (long). It is unsafe on 32-bit platforms "
- "with 64-bit tv_nsec.");
- int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_nanosleep, req, rem);
-#else
-#error "SYS_nanosleep and SYS_clock_nanosleep_time64 syscalls not available."
-#endif
-
- if (ret < 0) {
- libc_errno = -ret;
+ auto result = linux_syscalls::nanosleep(req, rem);
+ if (!result) {
+ libc_errno = result.error();
return -1;
}
- return ret;
+ return result.value();
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/unistd/CMakeLists.txt
index c8f1b8d3ef15f4..98444e7b31631e 100644
--- a/libc/src/unistd/CMakeLists.txt
+++ b/libc/src/unistd/CMakeLists.txt
@@ -236,7 +236,6 @@ add_entrypoint_object(
.${LIBC_TARGET_OS}.pathconf
)
-
add_entrypoint_object(
pipe
ALIAS
@@ -300,6 +299,13 @@ add_entrypoint_object(
.${LIBC_TARGET_OS}.setsid
)
+add_entrypoint_object(
+ sleep
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.sleep
+)
+
add_entrypoint_object(
symlink
ALIAS
@@ -349,6 +355,13 @@ add_entrypoint_object(
.${LIBC_TARGET_OS}.unlinkat
)
+add_entrypoint_object(
+ usleep
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.usleep
+)
+
add_entrypoint_object(
write
ALIAS
diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt
index 7e7a551d9539e7..7a8b51e9514aaa 100644
--- a/libc/src/unistd/linux/CMakeLists.txt
+++ b/libc/src/unistd/linux/CMakeLists.txt
@@ -541,6 +541,20 @@ add_entrypoint_object(
libc.src.__support.OSUtil.osutil
)
+add_entrypoint_object(
+ sleep
+ SRCS
+ sleep.cpp
+ HDRS
+ ../sleep.h
+ DEPENDS
+ libc.hdr.types.struct_timespec
+ libc.hdr.types.time_t
+ libc.src.__support.OSUtil.linux.syscall_wrappers.nanosleep
+ libc.src.__support.common
+ libc.src.__support.macros.config
+)
+
add_entrypoint_object(
symlink
SRCS
@@ -638,6 +652,22 @@ add_entrypoint_object(
libc.src.errno.errno
)
+add_entrypoint_object(
+ usleep
+ SRCS
+ usleep.cpp
+ HDRS
+ ../usleep.h
+ DEPENDS
+ libc.hdr.types.useconds_t
+ libc.hdr.types.struct_timespec
+ libc.src.__support.OSUtil.linux.syscall_wrappers.nanosleep
+ libc.src.__support.common
+ libc.src.__support.libc_errno
+ libc.src.__support.macros.config
+ libc.src.errno.errno
+)
+
add_entrypoint_object(
write
SRCS
diff --git a/libc/src/unistd/linux/sleep.cpp b/libc/src/unistd/linux/sleep.cpp
new file mode 100644
index 00000000000000..8c2a85043e1807
--- /dev/null
+++ b/libc/src/unistd/linux/sleep.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Linux implementation of sleep.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/unistd/sleep.h"
+#include "hdr/types/struct_timespec.h"
+#include "hdr/types/time_t.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/nanosleep.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(unsigned int, sleep, (unsigned int seconds)) {
+ static_assert(sizeof(unsigned int) <= sizeof(time_t), "Avoids overflow");
+ struct timespec req = {seconds, 0};
+ struct timespec rem = {};
+ ErrorOr<int> result = linux_syscalls::nanosleep(&req, &rem);
+ if (!result) {
+ // Cast does not lose information as `remaining` cannot be greater than
+ // `seconds`.
+ return static_cast<unsigned int>(rem.tv_sec);
+ }
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/unistd/linux/usleep.cpp b/libc/src/unistd/linux/usleep.cpp
new file mode 100644
index 00000000000000..1eadc44bb8005b
--- /dev/null
+++ b/libc/src/unistd/linux/usleep.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Linux implementation of usleep.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/unistd/usleep.h"
+#include "hdr/types/struct_timespec.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/nanosleep.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, usleep, (useconds_t usec)) {
+ static_assert(sizeof(useconds_t) >= 4, "Avoids overflow in ns computation");
+ constexpr useconds_t US_IN_S = 1'000'000;
+ struct timespec ts = {usec / US_IN_S, (usec % US_IN_S) * 1000};
+ auto result = linux_syscalls::nanosleep(&ts, nullptr);
+ if (!result) {
+ libc_errno = result.error();
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/unistd/sleep.h b/libc/src/unistd/sleep.h
new file mode 100644
index 00000000000000..52eb0d7ce7f493
--- /dev/null
+++ b/libc/src/unistd/sleep.h
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for sleep.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_UNISTD_SLEEP_H
+#define LLVM_LIBC_SRC_UNISTD_SLEEP_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned int sleep(unsigned int seconds);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_UNISTD_SLEEP_H
diff --git a/libc/src/unistd/usleep.h b/libc/src/unistd/usleep.h
new file mode 100644
index 00000000000000..f9def0b304c35d
--- /dev/null
+++ b/libc/src/unistd/usleep.h
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for usleep.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_UNISTD_USLEEP_H
+#define LLVM_LIBC_SRC_UNISTD_USLEEP_H
+
+#include "hdr/types/useconds_t.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int usleep(useconds_t usec);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_UNISTD_USLEEP_H
diff --git a/libc/test/src/time/CMakeLists.txt b/libc/test/src/time/CMakeLists.txt
index ad5017369b0a77..e4d7dce066c7b0 100644
--- a/libc/test/src/time/CMakeLists.txt
+++ b/libc/test/src/time/CMakeLists.txt
@@ -209,9 +209,10 @@ add_libc_test(
SRCS
nanosleep_test.cpp
DEPENDS
- libc.include.time
libc.hdr.types.struct_timespec
+ libc.hdr.signal_macros
libc.src.time.nanosleep
+ libc.src.__support.macros.config
libc.test.UnitTest.ErrnoCheckingTest
)
diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt
index 7d92fa258214b7..4cdf5d0e4fc606 100644
--- a/libc/test/src/unistd/CMakeLists.txt
+++ b/libc/test/src/unistd/CMakeLists.txt
@@ -403,6 +403,19 @@ add_libc_unittest(
libc.src.unistd.setsid
)
+add_libc_unittest(
+ sleep_test
+ SUITE
+ libc_unistd_unittests
+ SRCS
+ sleep_test.cpp
+ DEPENDS
+ libc.hdr.time_macros
+ libc.hdr.types.struct_timespec
+ libc.src.__support.time.clock_gettime
+ libc.src.unistd.sleep
+)
+
add_libc_unittest(
symlink_test
SUITE
@@ -495,6 +508,20 @@ add_libc_unittest(
libc.test.UnitTest.ErrnoSetterMatcher
)
+add_libc_unittest(
+ usleep_test
+ SUITE
+ libc_unistd_unittests
+ SRCS
+ usleep_test.cpp
+ DEPENDS
+ libc.hdr.time_macros
+ libc.hdr.types.struct_timespec
+ libc.src.__support.time.clock_gettime
+ libc.src.unistd.usleep
+ libc.test.UnitTest.ErrnoCheckingTest
+)
+
add_libc_unittest(
gethostname_test
SUITE
diff --git a/libc/test/src/unistd/sleep_test.cpp b/libc/test/src/unistd/sleep_test.cpp
new file mode 100644
index 00000000000000..a126a7e9e76e26
--- /dev/null
+++ b/libc/test/src/unistd/sleep_test.cpp
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Unittests for sleep.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hdr/time_macros.h"
+#include "hdr/types/struct_timespec.h"
+#include "src/__support/time/clock_gettime.h"
+#include "src/unistd/sleep.h"
+#include "test/UnitTest/Test.h"
+
+TEST(LlvmLibcSleepTest, SmokeTest) {
+ struct timespec start, end;
+ ASSERT_TRUE(LIBC_NAMESPACE::internal::clock_gettime(CLOCK_MONOTONIC, &start)
+ .has_value());
+
+ // Sleep for 1 second.
+ ASSERT_EQ(LIBC_NAMESPACE::sleep(1), 0u);
+
+ ASSERT_TRUE(LIBC_NAMESPACE::internal::clock_gettime(CLOCK_MONOTONIC, &end)
+ .has_value());
+
+ // Calculate elapsed time in seconds.
+ uint64_t elapsed_sec = static_cast<uint64_t>(end.tv_sec - start.tv_sec);
+ if (end.tv_nsec < start.tv_nsec)
+ --elapsed_sec;
+
+ // It should have slept for at least 1 second.
+ ASSERT_GE(elapsed_sec, uint64_t{1});
+}
+
+TEST(LlvmLibcSleepTest, Zero) { ASSERT_EQ(LIBC_NAMESPACE::sleep(0), 0u); }
diff --git a/libc/test/src/unistd/usleep_test.cpp b/libc/test/src/unistd/usleep_test.cpp
new file mode 100644
index 00000000000000..18a797c28eccb6
--- /dev/null
+++ b/libc/test/src/unistd/usleep_test.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Unittests for usleep.
+///
+//===----------------------------------------------------------------------===//
+
+#include "hdr/time_macros.h"
+#include "hdr/types/struct_timespec.h"
+#include "src/__support/time/clock_gettime.h"
+#include "src/unistd/usleep.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcUsleepTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcUsleepTest, SmokeTest) {
+ struct timespec start, end;
+ ASSERT_TRUE(LIBC_NAMESPACE::internal::clock_gettime(CLOCK_MONOTONIC, &start)
+ .has_value());
+
+ // Sleep for 10000 microseconds (10 ms).
+ ASSERT_EQ(LIBC_NAMESPACE::usleep(10000), 0);
+
+ ASSERT_TRUE(LIBC_NAMESPACE::internal::clock_gettime(CLOCK_MONOTONIC, &end)
+ .has_value());
+
+ // Calculate elapsed time in nanoseconds.
+ int64_t
diff _sec = end.tv_sec - start.tv_sec;
+ int64_t
diff _nsec = end.tv_nsec - start.tv_nsec;
+ int64_t elapsed_ns =
diff _sec * 1000000000LL +
diff _nsec;
+
+ // It should have slept for at least 10 ms (10,000,000 ns).
+ ASSERT_GE(elapsed_ns, int64_t{10000000});
+}
+
+TEST_F(LlvmLibcUsleepTest, Zero) { ASSERT_EQ(LIBC_NAMESPACE::usleep(0), 0); }
More information about the libc-commits
mailing list