-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc] Implement getitimer and setitimer, add proxy headers for itimerval #134773
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-libc Author: Tsz Chan (tszhin-swe) Changes#133983 Full diff: https://github.com/llvm/llvm-project/pull/134773.diff 19 Files Affected:
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 5f293dc1c3c73..2c621737e380b 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -363,6 +363,10 @@ set(TARGET_LIBC_ENTRYPOINTS
# sys/uio.h entrypoints
libc.src.sys.uio.writev
libc.src.sys.uio.readv
+
+ # sys/time.h entrypoints
+ libc.src.sys.time.setitimer
+ libc.src.sys.time.getitimer
)
if(LLVM_LIBC_INCLUDE_SCUDO)
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 05e8e9e308168..870a194418f43 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -185,6 +185,9 @@ set(TARGET_LIBC_ENTRYPOINTS
# libc.src.sys.epoll.epoll_pwait
# libc.src.sys.epoll.epoll_pwait2
+ # sys/time.h entrypoints
+ libc.src.sys.time.setitimer
+ libc.src.sys.time.getitimer
)
if(LLVM_LIBC_FULL_BUILD)
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index eccd222fa123e..065b608e5e065 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -365,6 +365,10 @@ set(TARGET_LIBC_ENTRYPOINTS
# sys/uio.h entrypoints
libc.src.sys.uio.writev
libc.src.sys.uio.readv
+
+ # sys/time.h entrypoints
+ libc.src.sys.time.setitimer
+ libc.src.sys.time.getitimer
)
if(LLVM_LIBC_INCLUDE_SCUDO)
diff --git a/libc/hdr/types/CMakeLists.txt b/libc/hdr/types/CMakeLists.txt
index e43c6f4552644..ac9fe40abf516 100644
--- a/libc/hdr/types/CMakeLists.txt
+++ b/libc/hdr/types/CMakeLists.txt
@@ -190,6 +190,15 @@ add_proxy_header_library(
libc.include.sys_time
)
+add_proxy_header_library(
+ struct_itimerval
+ HDRS
+ struct_itimerval.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.struct_itimerval
+ libc.include.sys_time
+)
+
add_proxy_header_library(
pid_t
HDRS
diff --git a/libc/hdr/types/struct_itimerval.h b/libc/hdr/types/struct_itimerval.h
new file mode 100644
index 0000000000000..b2281675b8023
--- /dev/null
+++ b/libc/hdr/types/struct_itimerval.h
@@ -0,0 +1,21 @@
+//===-- Proxy for struct itimerval ----------------------------------------===//
+//
+// 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_HDR_TYPES_STRUCT_ITIMERVAL_H
+#define LLVM_LIBC_HDR_TYPES_STRUCT_ITIMERVAL_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/struct_itimerval.h"
+
+#else
+
+#include <sys/time.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_STRUCT_ITIMERVAL_H
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index 66e8527701873..9f42d9e4a3c11 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -78,6 +78,7 @@ add_header(struct_pollfd HDR struct_pollfd.h)
add_header(struct_rlimit HDR struct_rlimit.h DEPENDS .rlim_t)
add_header(struct_sched_param HDR struct_sched_param.h)
add_header(struct_timeval HDR struct_timeval.h DEPENDS .suseconds_t .time_t)
+add_header(struct_itimerval HDR struct_itimerval.h DEPENDS .struct_timeval)
add_header(struct_rusage HDR struct_rusage.h DEPENDS .struct_timeval)
add_header(union_sigval HDR union_sigval.h)
add_header(siginfo_t HDR siginfo_t.h DEPENDS .union_sigval .pid_t .uid_t .clock_t)
diff --git a/libc/include/llvm-libc-types/struct_itimerval.h b/libc/include/llvm-libc-types/struct_itimerval.h
new file mode 100644
index 0000000000000..9d3026fc2d9d7
--- /dev/null
+++ b/libc/include/llvm-libc-types/struct_itimerval.h
@@ -0,0 +1,20 @@
+//===-- Definition of struct itimerval
+//-------------------------------------===//
+//
+// 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_TYPES_STRUCT_ITIMERVAL_H
+#define LLVM_LIBC_TYPES_STRUCT_ITIMERVAL_H
+
+#include "struct_timeval.h"
+
+struct itimerval {
+ struct timeval it_interval; /* Interval for periodic timer */
+ struct timeval it_value; /* Time until next expiration */
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_ITIMERVAL_H
diff --git a/libc/include/sys/time.yaml b/libc/include/sys/time.yaml
index ca497bbe92995..58123d96bb340 100644
--- a/libc/include/sys/time.yaml
+++ b/libc/include/sys/time.yaml
@@ -4,6 +4,23 @@ standards: Linux
macros: []
types:
- type_name: struct_timeval
+ - type_name: struct_itimerval
enums: []
-functions: []
+functions:
+ - name: setitimer
+ standards:
+ - POSIX
+ return_type: int
+ arguments:
+ - type: int
+ - type: const struct itimerval *
+ - type: struct itimerval *
+
+ - name: getitimer
+ standards:
+ - POSIX
+ return_type: int
+ arguments:
+ - type: int
+ - type: struct itimerval *
objects: []
diff --git a/libc/src/sys/CMakeLists.txt b/libc/src/sys/CMakeLists.txt
index bb177f11c6d62..e0412dc44dab5 100644
--- a/libc/src/sys/CMakeLists.txt
+++ b/libc/src/sys/CMakeLists.txt
@@ -12,3 +12,4 @@ add_subdirectory(utsname)
add_subdirectory(wait)
add_subdirectory(prctl)
add_subdirectory(uio)
+add_subdirectory(time)
diff --git a/libc/src/sys/time/CMakeLists.txt b/libc/src/sys/time/CMakeLists.txt
new file mode 100644
index 0000000000000..0aa9ce02862cf
--- /dev/null
+++ b/libc/src/sys/time/CMakeLists.txt
@@ -0,0 +1,17 @@
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+endif()
+
+add_entrypoint_object(
+ setitimer
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.setitimer
+)
+
+add_entrypoint_object(
+ getitimer
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.getitimer
+)
diff --git a/libc/src/sys/time/getitimer.h b/libc/src/sys/time/getitimer.h
new file mode 100644
index 0000000000000..a10462a30adfc
--- /dev/null
+++ b/libc/src/sys/time/getitimer.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for getitimer
+//-----------------------------------===//
+//
+// 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_SYS_TIME_GETITIMER_H
+#define LLVM_LIBC_SRC_SYS_TIME_GETITIMER_H
+
+#include "hdr/types/struct_itimerval.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+int getitimer(int which, struct itimerval *curr_value);
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SYS_TIME_GETITIMER_H
diff --git a/libc/src/sys/time/linux/CMakeLists.txt b/libc/src/sys/time/linux/CMakeLists.txt
new file mode 100644
index 0000000000000..5c7dfd0f7d207
--- /dev/null
+++ b/libc/src/sys/time/linux/CMakeLists.txt
@@ -0,0 +1,27 @@
+add_entrypoint_object(
+ setitimer
+ SRCS
+ setitimer.cpp
+ HDRS
+ ../setitimer.h
+ DEPENDS
+ libc.hdr.types.struct_itimerval
+ libc.include.sys_syscall
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.errno.errno
+)
+
+add_entrypoint_object(
+ getitimer
+ SRCS
+ getitimer.cpp
+ HDRS
+ ../getitimer.h
+ DEPENDS
+ libc.hdr.types.struct_itimerval
+ libc.include.sys_syscall
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.errno.errno
+)
diff --git a/libc/src/sys/time/linux/getitimer.cpp b/libc/src/sys/time/linux/getitimer.cpp
new file mode 100644
index 0000000000000..de9e4c0f26cbc
--- /dev/null
+++ b/libc/src/sys/time/linux/getitimer.cpp
@@ -0,0 +1,30 @@
+//===-- Implementation file for getitimer
+//------------------------------------===//
+//
+// 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/sys/time/getitimer.h"
+#include "hdr/types/struct_itimerval.h"
+#include "src/__support/OSUtil/syscall.h"
+#include "src/__support/common.h"
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, getitimer, (int which, struct itimerval *curr_value)) {
+ long ret =
+ LIBC_NAMESPACE::syscall_impl<long>(SYS_getitimer, which, curr_value);
+ // On failure, return -1 and set errno.
+ if (ret < 0) {
+ libc_errno = static_cast<int>(-ret);
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/sys/time/linux/setitimer.cpp b/libc/src/sys/time/linux/setitimer.cpp
new file mode 100644
index 0000000000000..3af0358fde139
--- /dev/null
+++ b/libc/src/sys/time/linux/setitimer.cpp
@@ -0,0 +1,31 @@
+//===-- Implementation file for setitimer
+//------------------------------------===//
+//
+// 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/sys/time/setitimer.h"
+#include "hdr/types/struct_itimerval.h"
+#include "src/__support/OSUtil/syscall.h"
+#include "src/__support/common.h"
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, setitimer,
+ (int which, const struct itimerval *new_value,
+ struct itimerval *old_value)) {
+ long ret = LIBC_NAMESPACE::syscall_impl<long>(SYS_setitimer, which, new_value,
+ old_value);
+ // On failure, return -1 and set errno.
+ if (ret < 0) {
+ libc_errno = static_cast<int>(-ret);
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/sys/time/setitimer.h b/libc/src/sys/time/setitimer.h
new file mode 100644
index 0000000000000..a2a750c2a5649
--- /dev/null
+++ b/libc/src/sys/time/setitimer.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for setitimer
+//-----------------------------------===//
+//
+// 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_SYS_TIME_SETITIMER_H
+#define LLVM_LIBC_SRC_SYS_TIME_SETITIMER_H
+
+#include "hdr/types/struct_itimerval.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+int setitimer(int which, const struct itimerval *new_value,
+ struct itimerval *old_value);
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SYS_TIME_SETITIMER_H
diff --git a/libc/test/src/sys/CMakeLists.txt b/libc/test/src/sys/CMakeLists.txt
index 9e9293aab628f..224cc7905ad31 100644
--- a/libc/test/src/sys/CMakeLists.txt
+++ b/libc/test/src/sys/CMakeLists.txt
@@ -12,3 +12,4 @@ add_subdirectory(prctl)
add_subdirectory(auxv)
add_subdirectory(epoll)
add_subdirectory(uio)
+add_subdirectory(time)
diff --git a/libc/test/src/sys/time/CMakeLists.txt b/libc/test/src/sys/time/CMakeLists.txt
new file mode 100644
index 0000000000000..ff2f087f1fe0d
--- /dev/null
+++ b/libc/test/src/sys/time/CMakeLists.txt
@@ -0,0 +1,29 @@
+add_custom_target(libc_sys_time_unittests)
+
+add_libc_unittest(
+ setitimer_test
+ SUITE
+ libc_sys_time_unittests
+ SRCS
+ setitimer_test.cpp
+ DEPENDS
+ libc.src.sys.time.setitimer
+ libc.src.__support.common
+ libc.src.errno.errno
+ libc.test.UnitTest.ErrnoSetterMatcher
+)
+
+add_libc_unittest(
+ getitimer_test
+ SUITE
+ libc_sys_time_unittests
+ SRCS
+ getitimer_test.cpp
+ DEPENDS
+ libc.src.sys.time.getitimer
+ libc.src.__support.common
+ libc.src.errno.errno
+ libc.test.UnitTest.ErrnoSetterMatcher
+)
+
+
diff --git a/libc/test/src/sys/time/getitimer_test.cpp b/libc/test/src/sys/time/getitimer_test.cpp
new file mode 100644
index 0000000000000..344ee77c57503
--- /dev/null
+++ b/libc/test/src/sys/time/getitimer_test.cpp
@@ -0,0 +1,33 @@
+// //===-- Unittests for getitimer
+// -------------------------------------------===//
+// //
+// // 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/sys/time/getitimer.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+#include <sys/time.h>
+
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+
+TEST(LlvmLibcSysTimeGetitimerTest, SmokeTest) {
+ struct itimerval timer;
+ timer.it_value.tv_sec = -1;
+ timer.it_value.tv_usec = -1;
+ timer.it_interval.tv_sec = -1;
+ timer.it_interval.tv_usec = -1;
+
+ ASSERT_THAT(LIBC_NAMESPACE::getitimer(ITIMER_REAL, &timer),
+ returns(EQ(0)).with_errno(EQ(0)));
+
+ ASSERT_TRUE(timer.it_value.tv_sec == 0);
+ ASSERT_TRUE(timer.it_value.tv_usec == 0);
+ ASSERT_TRUE(timer.it_interval.tv_sec == 0);
+ ASSERT_TRUE(timer.it_interval.tv_usec == 0);
+}
diff --git a/libc/test/src/sys/time/setitimer_test.cpp b/libc/test/src/sys/time/setitimer_test.cpp
new file mode 100644
index 0000000000000..eb76d821bfd88
--- /dev/null
+++ b/libc/test/src/sys/time/setitimer_test.cpp
@@ -0,0 +1,49 @@
+// //===-- Unittests for setitimer
+// -------------------------------------------===//
+// //
+// // 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/signal/signal.h"
+#include "src/sys/time/setitimer.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+#include <atomic>
+#include <signal.h>
+#include <sys/time.h>
+
+using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
+
+static std::atomic<bool> timer_fired(false);
+
+extern "C" void handle_sigalrm(int) { timer_fired.store(true); }
+
+TEST(LlvmLibcSysTimeSetitimerTest, SmokeTest) {
+ errno = 0;
+ struct sigaction sa;
+ sa.sa_handler = handle_sigalrm;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sigaction(SIGALRM, &sa, nullptr);
+
+ struct itimerval timer;
+ timer.it_value.tv_sec = 0;
+ timer.it_value.tv_usec = 200000;
+ timer.it_interval.tv_sec = 0;
+ timer.it_interval.tv_usec = 0; // One-shot timer
+
+ ASSERT_THAT(LIBC_NAMESPACE::setitimer(ITIMER_REAL, &timer, nullptr),
+ returns(EQ(0)).with_errno(EQ(0)));
+
+ while (true) {
+ if (timer_fired.load())
+ break;
+ }
+
+ ASSERT_TRUE(timer_fired.load());
+}
|
84d8382
to
6e2593f
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
6e2593f
to
018bf2d
Compare
c365b3e
to
4b40205
Compare
4b40205
to
ce4c93f
Compare
@lntue Hello, this is ready for review. Thanks! |
|
||
using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher; | ||
|
||
TEST(LlvmLibcSysTimeGetitimerTest, SmokeTest) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're moving tests that rely on errno to a new framework, which you can see an example of in the epoll_pwait_test.cpp
. You should just need to add the using
and change to TEST_F
for both tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
ASSERT_THAT(LIBC_NAMESPACE::getitimer(0, &timer), | ||
returns(EQ(0)).with_errno(EQ(0))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ideally there would be a test where the function succeeds and one where it fails. Could you add a test where the function gives an error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added
libc/include/sys/time.yaml
Outdated
arguments: | ||
- type: int | ||
- type: struct itimerval * | ||
objects: [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why did objects
get moved?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, missed it during conflicts solve, fixed.
2be20b3
to
511c635
Compare
511c635
to
6b7ec28
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with one change
libc/include/sys/time.yaml
Outdated
- type: const struct itimerval * | ||
- type: struct itimerval * |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should be restrict
- type: const struct itimerval * | |
- type: struct itimerval * | |
- type: const struct itimerval *__restrict | |
- type: struct itimerval *__restrict |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, should be good to land?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you're good to land. Please wait for the presubmits to finish, though if the buildkite is taking a long time you can skip that one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have merge access, could you merge it for me? Thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see there this isn't touching the RISC-V side. Aren't these functions supported there?
Adding the RISC-V targets can be done in a followup patch. I'm going to merge this as-is for now. |
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/10/builds/3445 Here is the relevant piece of the build log for the reference
|
#133983