[libc-commits] [libc] [libc][POSIX] Add clock_settime() function (PR #161729)
Anton Shepelev via libc-commits
libc-commits at lists.llvm.org
Thu Oct 2 13:49:55 PDT 2025
https://github.com/amemov updated https://github.com/llvm/llvm-project/pull/161729
>From 2c0ef107eea86381f17015fcd57c0b17d3c3cd22 Mon Sep 17 00:00:00 2001
From: Anton Shepelev <shepelev777 at gmail.com>
Date: Thu, 2 Oct 2025 13:21:18 -0700
Subject: [PATCH 1/2] - Implemented a clock_settime syscall wrapper for Linux -
Implemented unit-tests for the feature
---
libc/config/linux/aarch64/entrypoints.txt | 1 +
libc/config/linux/riscv/entrypoints.txt | 1 +
libc/config/linux/x86_64/entrypoints.txt | 1 +
libc/docs/headers/time.rst | 2 +-
libc/include/time.yaml | 7 +++
libc/src/__support/time/CMakeLists.txt | 7 +++
libc/src/__support/time/clock_settime.h | 22 ++++++++
libc/src/__support/time/linux/CMakeLists.txt | 15 ++++++
.../__support/time/linux/clock_settime.cpp | 53 +++++++++++++++++++
libc/src/time/CMakeLists.txt | 8 +++
libc/src/time/clock_settime.h | 22 ++++++++
libc/src/time/linux/CMakeLists.txt | 13 +++++
libc/src/time/linux/clock_settime.cpp | 30 +++++++++++
libc/test/src/time/CMakeLists.txt | 15 ++++++
libc/test/src/time/clock_settime_test.cpp | 31 +++++++++++
15 files changed, 227 insertions(+), 1 deletion(-)
create mode 100644 libc/src/__support/time/clock_settime.h
create mode 100644 libc/src/__support/time/linux/clock_settime.cpp
create mode 100644 libc/src/time/clock_settime.h
create mode 100644 libc/src/time/linux/clock_settime.cpp
create mode 100644 libc/test/src/time/clock_settime_test.cpp
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 00c4b2ec0f828..605b76718fd64 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -1142,6 +1142,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.time.ctime_r
libc.src.time.clock
libc.src.time.clock_gettime
+ libc.src.time.clock_settime
libc.src.time.difftime
libc.src.time.gettimeofday
libc.src.time.gmtime
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 89e3653186d13..97cd7fdef7a07 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -1267,6 +1267,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.time.ctime_r
libc.src.time.clock
libc.src.time.clock_gettime
+ libc.src.time.clock_settime
libc.src.time.difftime
libc.src.time.gettimeofday
libc.src.time.gmtime
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 0bb8a683c5b01..59357822ec537 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1305,6 +1305,7 @@ if(LLVM_LIBC_FULL_BUILD)
libc.src.time.ctime_r
libc.src.time.clock
libc.src.time.clock_gettime
+ libc.src.time.clock_settime
libc.src.time.difftime
libc.src.time.gettimeofday
libc.src.time.gmtime
diff --git a/libc/docs/headers/time.rst b/libc/docs/headers/time.rst
index 55bc1a17ee285..00b0dd472de5c 100644
--- a/libc/docs/headers/time.rst
+++ b/libc/docs/headers/time.rst
@@ -71,7 +71,7 @@ Implementation Status
+---------------------+---------+---------+---------+-----------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| clock_nanosleep | | | | | | | | | | | | | |
+---------------------+---------+---------+---------+-----------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
-| clock_settime | | | | | | | | | | | | | |
+| clock_settime | |check| | |check| | | |check| | | | | | | | | | |
+---------------------+---------+---------+---------+-----------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| ctime | |check| | |check| | | |check| | | | | | | | | | |
+---------------------+---------+---------+---------+-----------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
diff --git a/libc/include/time.yaml b/libc/include/time.yaml
index 2f8024298fad1..7b86838a7dca2 100644
--- a/libc/include/time.yaml
+++ b/libc/include/time.yaml
@@ -67,6 +67,13 @@ functions:
arguments:
- type: clockid_t
- type: struct timespec *
+ - name: clock_settime
+ standard:
+ - POSIX
+ return_type: int
+ arguments:
+ - type: clockid_t
+ - type: const struct timespec *
- name: difftime
standard:
- stdc
diff --git a/libc/src/__support/time/CMakeLists.txt b/libc/src/__support/time/CMakeLists.txt
index 8247e792e8410..8dbcb914fcc5b 100644
--- a/libc/src/__support/time/CMakeLists.txt
+++ b/libc/src/__support/time/CMakeLists.txt
@@ -19,3 +19,10 @@ add_object_library(
DEPENDS
libc.src.__support.time.${LIBC_TARGET_OS}.clock_gettime
)
+
+add_object_library(
+ clock_settime
+ ALIAS
+ DEPENDS
+ libc.src.__support.time.${LIBC_TARGET_OS}.clock_settime
+)
diff --git a/libc/src/__support/time/clock_settime.h b/libc/src/__support/time/clock_settime.h
new file mode 100644
index 0000000000000..d8d305cadf4b9
--- /dev/null
+++ b/libc/src/__support/time/clock_settime.h
@@ -0,0 +1,22 @@
+//===--- clock_settime linux implementation ---------------------*- 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___SUPPORT_TIME_CLOCK_SETTIME_H
+#define LLVM_LIBC_SRC___SUPPORT_TIME_CLOCK_SETTIME_H
+
+#include "hdr/types/clockid_t.h"
+#include "hdr/types/struct_timespec.h"
+#include "src/__support/error_or.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+ErrorOr<int> clock_settime(clockid_t clockid, const timespec *ts);
+} // namespace internal
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_TIME_CLOCK_SETTIME_H
diff --git a/libc/src/__support/time/linux/CMakeLists.txt b/libc/src/__support/time/linux/CMakeLists.txt
index 6fec7eeba99ad..478529502b403 100644
--- a/libc/src/__support/time/linux/CMakeLists.txt
+++ b/libc/src/__support/time/linux/CMakeLists.txt
@@ -14,6 +14,21 @@ add_object_library(
libc.src.__support.OSUtil.linux.vdso
)
+add_object_library(
+ clock_settime
+ HDRS
+ ../clock_settime.h
+ SRCS
+ clock_settime.cpp
+ DEPENDS
+ libc.include.sys_syscall
+ libc.hdr.types.struct_timespec
+ libc.hdr.types.clockid_t
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.OSUtil.osutil
+)
+
add_header_library(
clock_conversion
HDRS
diff --git a/libc/src/__support/time/linux/clock_settime.cpp b/libc/src/__support/time/linux/clock_settime.cpp
new file mode 100644
index 0000000000000..d81889ebc469d
--- /dev/null
+++ b/libc/src/__support/time/linux/clock_settime.cpp
@@ -0,0 +1,53 @@
+//===--- clock_settime linux implementation ---------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/time/clock_settime.h"
+#include "hdr/types/clockid_t.h"
+#include "hdr/types/struct_timespec.h"
+#include "src/__support/OSUtil/syscall.h"
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h>
+
+#if defined(SYS_clock_settime64)
+#include <linux/time_types.h>
+#endif
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+ErrorOr<int> clock_settime(clockid_t clockid, const timespec *ts) {
+ int ret;
+#if defined(SYS_clock_settime)
+ ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_settime,
+ static_cast<long>(clockid),
+ reinterpret_cast<long>(ts));
+#elif defined(SYS_clock_settime64)
+ static_assert(
+ sizeof(time_t) == sizeof(int64_t),
+ "SYS_clock_settime64 requires struct timespec with 64-bit members.");
+
+ __kernel_timespec ts64{};
+
+ ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_settime64,
+ static_cast<long>(clockid),
+ reinterpret_cast<long>(&ts64));
+ if (ret == 0) {
+ ts->tv_sec = static_cast<decltype(ts->tv_sec)>(ts64.tv_sec);
+ ts->tv_nsec = static_cast<decltype(ts->tv_nsec)>(ts64.tv_nsec);
+ }
+#else
+#error "SYS_clock_settime and SYS_clock_settime64 syscalls not available."
+#endif
+ if (ret < 0)
+ return Error(-ret);
+ return ret;
+}
+
+} // namespace internal
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/time/CMakeLists.txt b/libc/src/time/CMakeLists.txt
index ec942e38d1af5..4d647c22c3239 100644
--- a/libc/src/time/CMakeLists.txt
+++ b/libc/src/time/CMakeLists.txt
@@ -245,3 +245,11 @@ add_entrypoint_object(
DEPENDS
.${LIBC_TARGET_OS}.clock_getres
)
+
+add_entrypoint_object(
+ clock_settime
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.clock_settime
+)
+
diff --git a/libc/src/time/clock_settime.h b/libc/src/time/clock_settime.h
new file mode 100644
index 0000000000000..9321dd1074101
--- /dev/null
+++ b/libc/src/time/clock_settime.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for clock_settime 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_SETTIME_H
+#define LLVM_LIBC_SRC_TIME_CLOCK_SETTIME_H
+
+#include "hdr/types/clockid_t.h"
+#include "hdr/types/struct_timespec.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int clock_settime(clockid_t clockid, const timespec *tp);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_TIME_CLOCK_SETTIME_H
diff --git a/libc/src/time/linux/CMakeLists.txt b/libc/src/time/linux/CMakeLists.txt
index a6ec7c7c06963..6ea04597063cb 100644
--- a/libc/src/time/linux/CMakeLists.txt
+++ b/libc/src/time/linux/CMakeLists.txt
@@ -54,6 +54,19 @@ add_entrypoint_object(
libc.src.errno.errno
)
+add_entrypoint_object(
+ clock_settime
+ SRCS
+ clock_settime.cpp
+ HDRS
+ ../clock_settime.h
+ DEPENDS
+ libc.hdr.types.clockid_t
+ libc.hdr.types.struct_timespec
+ libc.src.__support.time.clock_settime
+ libc.src.errno.errno
+)
+
add_entrypoint_object(
gettimeofday
SRCS
diff --git a/libc/src/time/linux/clock_settime.cpp b/libc/src/time/linux/clock_settime.cpp
new file mode 100644
index 0000000000000..1f39ca6efa02d
--- /dev/null
+++ b/libc/src/time/linux/clock_settime.cpp
@@ -0,0 +1,30 @@
+//===---------- Linux implementation of the POSIX clock_settime 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_settime.h"
+#include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/time/clock_settime.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, clock_settime,
+ (clockid_t clockid, const struct timespec *ts)) {
+ auto result = internal::clock_settime(clockid, ts);
+
+ // A negative return value indicates an error with the magnitude of the
+ // value being the error code.
+ if (!result.has_value()) {
+ libc_errno = result.error();
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/time/CMakeLists.txt b/libc/test/src/time/CMakeLists.txt
index 03e5428292418..c8e113f06d50b 100644
--- a/libc/test/src/time/CMakeLists.txt
+++ b/libc/test/src/time/CMakeLists.txt
@@ -124,6 +124,21 @@ add_libc_test(
libc.src.time.clock_getres
)
+add_libc_test(
+ clock_settime_test
+ SUITE
+ libc_time_unittests
+ SRCS
+ clock_settime_test.cpp
+ DEPENDS
+ libc.src.time.clock_settime
+ libc.hdr.types.time_t
+ libc.hdr.types.struct_timespec
+ libc.hdr.time_macros
+ libc.hdr.errno_macros
+ libc.test.UnitTest.ErrnoCheckingTest
+)
+
add_libc_unittest(
difftime_test
SUITE
diff --git a/libc/test/src/time/clock_settime_test.cpp b/libc/test/src/time/clock_settime_test.cpp
new file mode 100644
index 0000000000000..881db1f75120d
--- /dev/null
+++ b/libc/test/src/time/clock_settime_test.cpp
@@ -0,0 +1,31 @@
+//===-- Unittests for clock_settime ---------------------------------------===//
+//
+// 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 "hdr/time_macros.h"
+#include "hdr/types/struct_timespec.h"
+#include "src/time/clock_settime.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/Test.h"
+
+using LlvmLibcClockSetTime = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+#ifdef CLOCK_MONOTONIC
+TEST_F(LlvmLibcClockSetTime, MonotonicIsNotSettable) {
+ timespec ts = {0, 0};
+ int result = LIBC_NAMESPACE::clock_settime(CLOCK_MONOTONIC, &ts);
+ ASSERT_EQ(result, -1);
+ ASSERT_ERRNO_EQ(EINVAL);
+}
+#endif // CLOCK_MONOTONIC
+
+TEST_F(LlvmLibcClockSetTime, InvalidClockId) {
+ timespec ts = {0, 0};
+ int result = LIBC_NAMESPACE::clock_settime(static_cast<clockid_t>(-1), &ts);
+ ASSERT_EQ(result, -1);
+ ASSERT_ERRNO_EQ(EINVAL);
+}
>From 06ac55c61287325c50011720b1be285cd7bee310 Mon Sep 17 00:00:00 2001
From: Anton Shepelev <shepelev777 at gmail.com>
Date: Thu, 2 Oct 2025 13:49:43 -0700
Subject: [PATCH 2/2] - Fixed CMake to include the implementation only on Linux
for now
---
libc/src/__support/time/CMakeLists.txt | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/libc/src/__support/time/CMakeLists.txt b/libc/src/__support/time/CMakeLists.txt
index 8dbcb914fcc5b..04744da3fc981 100644
--- a/libc/src/__support/time/CMakeLists.txt
+++ b/libc/src/__support/time/CMakeLists.txt
@@ -20,9 +20,11 @@ add_object_library(
libc.src.__support.time.${LIBC_TARGET_OS}.clock_gettime
)
-add_object_library(
- clock_settime
- ALIAS
- DEPENDS
- libc.src.__support.time.${LIBC_TARGET_OS}.clock_settime
-)
+if(LIBC_TARGET_OS_IS_LINUX)
+ add_object_library(
+ clock_settime
+ ALIAS
+ DEPENDS
+ libc.src.__support.time.${LIBC_TARGET_OS}.clock_settime
+ )
+endif()
More information about the libc-commits
mailing list