[libc-commits] [libc] [libc] Implement sleep and usleep for Linux (PR #213912)
Pavel Labath via libc-commits
libc-commits at lists.llvm.org
Tue Aug 4 04:43:01 PDT 2026
https://github.com/labath updated https://github.com/llvm/llvm-project/pull/213912
>From 04b9e9d010129ff0f1ce631f1389917d88a5e61a Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Tue, 4 Aug 2026 11:05:47 +0000
Subject: [PATCH 1/2] [libc] Implement sleep and usleep for Linux
Implemented the sleep and usleep entrypoints for Linux. Refactored
the syscall implementation out of the public nanosleep entrypoint
into a standard internal syscall wrapper.
Co-authored-by: Jeff Bailey <jbailey at raspberryginger.com>
---
libc/config/linux/aarch64/entrypoints.txt | 2 +
libc/config/linux/riscv/entrypoints.txt | 2 +
libc/config/linux/x86_64/entrypoints.txt | 2 +
libc/hdr/types/CMakeLists.txt | 9 +++-
libc/hdr/types/useconds_t.h | 27 ++++++++++
libc/include/CMakeLists.txt | 1 +
libc/include/unistd.yaml | 13 +++++
.../linux/syscall_wrappers/CMakeLists.txt | 15 +++++-
.../OSUtil/linux/syscall_wrappers/nanosleep.h | 51 +++++++++++++++++++
libc/src/time/linux/CMakeLists.txt | 8 +--
libc/src/time/linux/nanosleep.cpp | 34 ++++---------
libc/src/unistd/CMakeLists.txt | 15 +++++-
libc/src/unistd/linux/CMakeLists.txt | 32 ++++++++++++
libc/src/unistd/linux/sleep.cpp | 41 +++++++++++++++
libc/src/unistd/linux/usleep.cpp | 36 +++++++++++++
libc/src/unistd/sleep.h | 25 +++++++++
libc/src/unistd/usleep.h | 26 ++++++++++
libc/test/src/time/CMakeLists.txt | 3 +-
libc/test/src/unistd/CMakeLists.txt | 28 ++++++++++
libc/test/src/unistd/sleep_test.cpp | 40 +++++++++++++++
libc/test/src/unistd/usleep_test.cpp | 45 ++++++++++++++++
21 files changed, 424 insertions(+), 31 deletions(-)
create mode 100644 libc/hdr/types/useconds_t.h
create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/nanosleep.h
create mode 100644 libc/src/unistd/linux/sleep.cpp
create mode 100644 libc/src/unistd/linux/usleep.cpp
create mode 100644 libc/src/unistd/sleep.h
create mode 100644 libc/src/unistd/usleep.h
create mode 100644 libc/test/src/unistd/sleep_test.cpp
create mode 100644 libc/test/src/unistd/usleep_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index c2c037c51ea08..1d5244b9c443e 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 4e3a383baa3ed..0f7822b36a761 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 5e848146594bb..7a9e741310c6a 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 23dbd98d52203..f56ddda2dc9fe 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 0000000000000..c6e26bdbf81ef
--- /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 add1411a9f95c..b77f149b2f65d 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 c1ae4567bfc02..4b3703af7798e 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 a45641483bbef..2b22bb8e733de 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 0000000000000..694becbd395b5
--- /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 4b4b84277e7bf..e605b53b9eb29 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 15b119ead20c6..872a1b27110de 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 c8f1b8d3ef15f..98444e7b31631 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 7e7a551d9539e..c31f0443b1210 100644
--- a/libc/src/unistd/linux/CMakeLists.txt
+++ b/libc/src/unistd/linux/CMakeLists.txt
@@ -541,6 +541,21 @@ add_entrypoint_object(
libc.src.__support.OSUtil.osutil
)
+add_entrypoint_object(
+ sleep
+ SRCS
+ sleep.cpp
+ HDRS
+ ../sleep.h
+ DEPENDS
+ libc.hdr.errno_macros
+ 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 +653,23 @@ add_entrypoint_object(
libc.src.errno.errno
)
+add_entrypoint_object(
+ usleep
+ SRCS
+ usleep.cpp
+ HDRS
+ ../usleep.h
+ DEPENDS
+ libc.hdr.errno_macros
+ 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 0000000000000..5f75dfd76edde
--- /dev/null
+++ b/libc/src/unistd/linux/sleep.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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/errno_macros.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 {
+
+static_assert(sizeof(time_t) == sizeof(int64_t),
+ "32-bit time_t is not supported");
+
+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 0000000000000..9e87f6708057b
--- /dev/null
+++ b/libc/src/unistd/linux/usleep.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 usleep.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/unistd/usleep.h"
+#include "hdr/errno_macros.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 0000000000000..52eb0d7ce7f49
--- /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 0000000000000..f9def0b304c35
--- /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 ad5017369b0a7..e4d7dce066c7b 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 ddd8729933b90..3290fbdfb0e25 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,21 @@ add_libc_unittest(
libc.test.UnitTest.ErrnoSetterMatcher
)
+add_libc_unittest(
+ usleep_test
+ SUITE
+ libc_unistd_unittests
+ SRCS
+ usleep_test.cpp
+ DEPENDS
+ libc.hdr.errno_macros
+ 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 0000000000000..a126a7e9e76e2
--- /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 0000000000000..61a9557fa4962
--- /dev/null
+++ b/libc/test/src/unistd/usleep_test.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// 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/errno_macros.h"
+#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/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+
+TEST(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(LlvmLibcUsleepTest, Zero) { ASSERT_EQ(LIBC_NAMESPACE::usleep(0), 0); }
>From fad2eb7f6c77590f418c8740fda8e2415e894a10 Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Tue, 4 Aug 2026 11:42:40 +0000
Subject: [PATCH 2/2] fix deps
---
libc/src/unistd/linux/CMakeLists.txt | 2 --
libc/src/unistd/linux/sleep.cpp | 2 --
libc/src/unistd/linux/usleep.cpp | 1 -
libc/test/src/unistd/CMakeLists.txt | 1 -
libc/test/src/unistd/usleep_test.cpp | 8 +++-----
5 files changed, 3 insertions(+), 11 deletions(-)
diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt
index c31f0443b1210..7a8b51e9514aa 100644
--- a/libc/src/unistd/linux/CMakeLists.txt
+++ b/libc/src/unistd/linux/CMakeLists.txt
@@ -548,7 +548,6 @@ add_entrypoint_object(
HDRS
../sleep.h
DEPENDS
- libc.hdr.errno_macros
libc.hdr.types.struct_timespec
libc.hdr.types.time_t
libc.src.__support.OSUtil.linux.syscall_wrappers.nanosleep
@@ -660,7 +659,6 @@ add_entrypoint_object(
HDRS
../usleep.h
DEPENDS
- libc.hdr.errno_macros
libc.hdr.types.useconds_t
libc.hdr.types.struct_timespec
libc.src.__support.OSUtil.linux.syscall_wrappers.nanosleep
diff --git a/libc/src/unistd/linux/sleep.cpp b/libc/src/unistd/linux/sleep.cpp
index 5f75dfd76edde..7f0a8c5fcf2f0 100644
--- a/libc/src/unistd/linux/sleep.cpp
+++ b/libc/src/unistd/linux/sleep.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "src/unistd/sleep.h"
-#include "hdr/errno_macros.h"
#include "hdr/types/struct_timespec.h"
#include "hdr/types/time_t.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/nanosleep.h"
@@ -25,7 +24,6 @@ static_assert(sizeof(time_t) == sizeof(int64_t),
"32-bit time_t is not supported");
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 = {};
diff --git a/libc/src/unistd/linux/usleep.cpp b/libc/src/unistd/linux/usleep.cpp
index 9e87f6708057b..1eadc44bb8005 100644
--- a/libc/src/unistd/linux/usleep.cpp
+++ b/libc/src/unistd/linux/usleep.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "src/unistd/usleep.h"
-#include "hdr/errno_macros.h"
#include "hdr/types/struct_timespec.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/nanosleep.h"
#include "src/__support/common.h"
diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt
index 3290fbdfb0e25..0d803f7bb24e7 100644
--- a/libc/test/src/unistd/CMakeLists.txt
+++ b/libc/test/src/unistd/CMakeLists.txt
@@ -515,7 +515,6 @@ add_libc_unittest(
SRCS
usleep_test.cpp
DEPENDS
- libc.hdr.errno_macros
libc.hdr.time_macros
libc.hdr.types.struct_timespec
libc.src.__support.time.clock_gettime
diff --git a/libc/test/src/unistd/usleep_test.cpp b/libc/test/src/unistd/usleep_test.cpp
index 61a9557fa4962..18a797c28eccb 100644
--- a/libc/test/src/unistd/usleep_test.cpp
+++ b/libc/test/src/unistd/usleep_test.cpp
@@ -11,18 +11,16 @@
///
//===----------------------------------------------------------------------===//
-#include "hdr/errno_macros.h"
#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/ErrnoSetterMatcher.h"
#include "test/UnitTest/Test.h"
-using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+using LlvmLibcUsleepTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
-TEST(LlvmLibcUsleepTest, SmokeTest) {
+TEST_F(LlvmLibcUsleepTest, SmokeTest) {
struct timespec start, end;
ASSERT_TRUE(LIBC_NAMESPACE::internal::clock_gettime(CLOCK_MONOTONIC, &start)
.has_value());
@@ -42,4 +40,4 @@ TEST(LlvmLibcUsleepTest, SmokeTest) {
ASSERT_GE(elapsed_ns, int64_t{10000000});
}
-TEST(LlvmLibcUsleepTest, Zero) { ASSERT_EQ(LIBC_NAMESPACE::usleep(0), 0); }
+TEST_F(LlvmLibcUsleepTest, Zero) { ASSERT_EQ(LIBC_NAMESPACE::usleep(0), 0); }
More information about the libc-commits
mailing list