Skip to content

Commit 84d8382

Browse files
committed
[libc] Implement getitimer and setitimer, add proxy headers for itimerval
1 parent c87dc2b commit 84d8382

File tree

19 files changed

+339
-1
lines changed

19 files changed

+339
-1
lines changed

libc/config/linux/aarch64/entrypoints.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,10 @@ set(TARGET_LIBC_ENTRYPOINTS
363363
# sys/uio.h entrypoints
364364
libc.src.sys.uio.writev
365365
libc.src.sys.uio.readv
366+
367+
# sys/time.h entrypoints
368+
libc.src.sys.time.setitimer
369+
libc.src.sys.time.getitimer
366370
)
367371

368372
if(LLVM_LIBC_INCLUDE_SCUDO)

libc/config/linux/arm/entrypoints.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@ set(TARGET_LIBC_ENTRYPOINTS
185185
# libc.src.sys.epoll.epoll_pwait
186186
# libc.src.sys.epoll.epoll_pwait2
187187

188+
# sys/time.h entrypoints
189+
libc.src.sys.time.setitimer
190+
libc.src.sys.time.getitimer
188191
)
189192

190193
if(LLVM_LIBC_FULL_BUILD)

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,10 @@ set(TARGET_LIBC_ENTRYPOINTS
365365
# sys/uio.h entrypoints
366366
libc.src.sys.uio.writev
367367
libc.src.sys.uio.readv
368+
369+
# sys/time.h entrypoints
370+
libc.src.sys.time.setitimer
371+
libc.src.sys.time.getitimer
368372
)
369373

370374
if(LLVM_LIBC_INCLUDE_SCUDO)

libc/hdr/types/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,15 @@ add_proxy_header_library(
190190
libc.include.sys_time
191191
)
192192

193+
add_proxy_header_library(
194+
struct_itimerval
195+
HDRS
196+
struct_itimerval.h
197+
FULL_BUILD_DEPENDS
198+
libc.include.llvm-libc-types.struct_itimerval
199+
libc.include.sys_time
200+
)
201+
193202
add_proxy_header_library(
194203
pid_t
195204
HDRS

libc/hdr/types/struct_itimerval.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Proxy for struct itimerval ----------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
#ifndef LLVM_LIBC_HDR_TYPES_STRUCT_ITIMERVAL_H
9+
#define LLVM_LIBC_HDR_TYPES_STRUCT_ITIMERVAL_H
10+
11+
#ifdef LIBC_FULL_BUILD
12+
13+
#include "include/llvm-libc-types/struct_itimerval.h"
14+
15+
#else
16+
17+
#include <sys/time.h>
18+
19+
#endif // LIBC_FULL_BUILD
20+
21+
#endif // LLVM_LIBC_HDR_TYPES_STRUCT_ITIMERVAL_H

libc/include/llvm-libc-types/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ add_header(struct_pollfd HDR struct_pollfd.h)
7878
add_header(struct_rlimit HDR struct_rlimit.h DEPENDS .rlim_t)
7979
add_header(struct_sched_param HDR struct_sched_param.h)
8080
add_header(struct_timeval HDR struct_timeval.h DEPENDS .suseconds_t .time_t)
81+
add_header(struct_itimerval HDR struct_itimerval.h DEPENDS .struct_timeval)
8182
add_header(struct_rusage HDR struct_rusage.h DEPENDS .struct_timeval)
8283
add_header(union_sigval HDR union_sigval.h)
8384
add_header(siginfo_t HDR siginfo_t.h DEPENDS .union_sigval .pid_t .uid_t .clock_t)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Definition of struct itimerval
2+
//-------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef LLVM_LIBC_TYPES_STRUCT_ITIMERVAL_H
11+
#define LLVM_LIBC_TYPES_STRUCT_ITIMERVAL_H
12+
13+
#include "struct_timeval.h"
14+
15+
struct itimerval {
16+
struct timeval it_interval; /* Interval for periodic timer */
17+
struct timeval it_value; /* Time until next expiration */
18+
};
19+
20+
#endif // LLVM_LIBC_TYPES_STRUCT_ITIMERVAL_H

libc/include/sys/time.yaml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,23 @@ standards: Linux
44
macros: []
55
types:
66
- type_name: struct_timeval
7+
- type_name: struct_itimerval
78
enums: []
8-
functions: []
9+
functions:
10+
- name: setitimer
11+
standards:
12+
- POSIX
13+
return_type: int
14+
arguments:
15+
- type: int
16+
- type: const struct itimerval *
17+
- type: struct itimerval *
18+
19+
- name: getitimer
20+
standards:
21+
- POSIX
22+
return_type: int
23+
arguments:
24+
- type: int
25+
- type: struct itimerval *
926
objects: []

libc/src/sys/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ add_subdirectory(utsname)
1212
add_subdirectory(wait)
1313
add_subdirectory(prctl)
1414
add_subdirectory(uio)
15+
add_subdirectory(time)

libc/src/sys/time/CMakeLists.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
2+
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
3+
endif()
4+
5+
add_entrypoint_object(
6+
setitimer
7+
ALIAS
8+
DEPENDS
9+
.${LIBC_TARGET_OS}.setitimer
10+
)
11+
12+
add_entrypoint_object(
13+
getitimer
14+
ALIAS
15+
DEPENDS
16+
.${LIBC_TARGET_OS}.getitimer
17+
)

libc/src/sys/time/getitimer.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation header for getitimer
2+
//-----------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef LLVM_LIBC_SRC_SYS_TIME_GETITIMER_H
11+
#define LLVM_LIBC_SRC_SYS_TIME_GETITIMER_H
12+
13+
#include "hdr/types/struct_itimerval.h"
14+
#include "src/__support/macros/config.h"
15+
16+
namespace LIBC_NAMESPACE_DECL {
17+
int getitimer(int which, struct itimerval *curr_value);
18+
} // namespace LIBC_NAMESPACE_DECL
19+
20+
#endif // LLVM_LIBC_SRC_SYS_TIME_GETITIMER_H
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
add_entrypoint_object(
2+
setitimer
3+
SRCS
4+
setitimer.cpp
5+
HDRS
6+
../setitimer.h
7+
DEPENDS
8+
libc.hdr.types.struct_itimerval
9+
libc.include.sys_syscall
10+
libc.src.__support.OSUtil.osutil
11+
libc.src.__support.common
12+
libc.src.errno.errno
13+
)
14+
15+
add_entrypoint_object(
16+
getitimer
17+
SRCS
18+
getitimer.cpp
19+
HDRS
20+
../getitimer.h
21+
DEPENDS
22+
libc.hdr.types.struct_itimerval
23+
libc.include.sys_syscall
24+
libc.src.__support.OSUtil.osutil
25+
libc.src.__support.common
26+
libc.src.errno.errno
27+
)

libc/src/sys/time/linux/getitimer.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//===-- Implementation file for getitimer
2+
//------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "src/sys/time/getitimer.h"
11+
#include "hdr/types/struct_itimerval.h"
12+
#include "src/__support/OSUtil/syscall.h"
13+
#include "src/__support/common.h"
14+
#include "src/errno/libc_errno.h"
15+
#include <sys/syscall.h>
16+
17+
namespace LIBC_NAMESPACE_DECL {
18+
19+
LLVM_LIBC_FUNCTION(int, getitimer, (int which, struct itimerval *curr_value)) {
20+
long ret =
21+
LIBC_NAMESPACE::syscall_impl<long>(SYS_getitimer, which, curr_value);
22+
// On failure, return -1 and set errno.
23+
if (ret < 0) {
24+
libc_errno = static_cast<int>(-ret);
25+
return -1;
26+
}
27+
return 0;
28+
}
29+
30+
} // namespace LIBC_NAMESPACE_DECL

libc/src/sys/time/linux/setitimer.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//===-- Implementation file for setitimer
2+
//------------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
#include "src/sys/time/setitimer.h"
10+
#include "hdr/types/struct_itimerval.h"
11+
#include "src/__support/OSUtil/syscall.h"
12+
#include "src/__support/common.h"
13+
#include "src/errno/libc_errno.h"
14+
#include <sys/syscall.h>
15+
16+
namespace LIBC_NAMESPACE_DECL {
17+
18+
LLVM_LIBC_FUNCTION(int, setitimer,
19+
(int which, const struct itimerval *new_value,
20+
struct itimerval *old_value)) {
21+
long ret = LIBC_NAMESPACE::syscall_impl<long>(SYS_setitimer, which, new_value,
22+
old_value);
23+
// On failure, return -1 and set errno.
24+
if (ret < 0) {
25+
libc_errno = static_cast<int>(-ret);
26+
return -1;
27+
}
28+
return 0;
29+
}
30+
31+
} // namespace LIBC_NAMESPACE_DECL

libc/src/sys/time/setitimer.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Implementation header for setitimer
2+
//-----------------------------------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef LLVM_LIBC_SRC_SYS_TIME_SETITIMER_H
11+
#define LLVM_LIBC_SRC_SYS_TIME_SETITIMER_H
12+
13+
#include "hdr/types/struct_itimerval.h"
14+
#include "src/__support/macros/config.h"
15+
16+
namespace LIBC_NAMESPACE_DECL {
17+
int setitimer(int which, const struct itimerval *new_value,
18+
struct itimerval *old_value);
19+
} // namespace LIBC_NAMESPACE_DECL
20+
21+
#endif // LLVM_LIBC_SRC_SYS_TIME_SETITIMER_H

libc/test/src/sys/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ add_subdirectory(prctl)
1212
add_subdirectory(auxv)
1313
add_subdirectory(epoll)
1414
add_subdirectory(uio)
15+
add_subdirectory(time)

libc/test/src/sys/time/CMakeLists.txt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
add_custom_target(libc_sys_time_unittests)
2+
3+
add_libc_unittest(
4+
setitimer_test
5+
SUITE
6+
libc_sys_time_unittests
7+
SRCS
8+
setitimer_test.cpp
9+
DEPENDS
10+
libc.src.sys.time.setitimer
11+
libc.src.__support.common
12+
libc.src.errno.errno
13+
libc.test.UnitTest.ErrnoSetterMatcher
14+
)
15+
16+
add_libc_unittest(
17+
getitimer_test
18+
SUITE
19+
libc_sys_time_unittests
20+
SRCS
21+
getitimer_test.cpp
22+
DEPENDS
23+
libc.src.sys.time.getitimer
24+
libc.src.__support.common
25+
libc.src.errno.errno
26+
libc.test.UnitTest.ErrnoSetterMatcher
27+
)
28+
29+
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// //===-- Unittests for getitimer
2+
// -------------------------------------------===//
3+
// //
4+
// // Part of the LLVM Project, under the Apache License v2.0 with LLVM
5+
// Exceptions.
6+
// // See https://llvm.org/LICENSE.txt for license information.
7+
// // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8+
// //
9+
// //===----------------------------------------------------------------------===//
10+
11+
#include "src/sys/time/getitimer.h"
12+
#include "test/UnitTest/ErrnoSetterMatcher.h"
13+
#include "test/UnitTest/Test.h"
14+
15+
#include <sys/time.h>
16+
17+
using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
18+
19+
TEST(LlvmLibcSysTimeGetitimerTest, SmokeTest) {
20+
struct itimerval timer;
21+
timer.it_value.tv_sec = -1;
22+
timer.it_value.tv_usec = -1;
23+
timer.it_interval.tv_sec = -1;
24+
timer.it_interval.tv_usec = -1;
25+
26+
ASSERT_THAT(LIBC_NAMESPACE::getitimer(ITIMER_REAL, &timer),
27+
returns(EQ(0)).with_errno(EQ(0)));
28+
29+
ASSERT_TRUE(timer.it_value.tv_sec == 0);
30+
ASSERT_TRUE(timer.it_value.tv_usec == 0);
31+
ASSERT_TRUE(timer.it_interval.tv_sec == 0);
32+
ASSERT_TRUE(timer.it_interval.tv_usec == 0);
33+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// //===-- Unittests for setitimer
2+
// -------------------------------------------===//
3+
// //
4+
// // Part of the LLVM Project, under the Apache License v2.0 with LLVM
5+
// Exceptions.
6+
// // See https://llvm.org/LICENSE.txt for license information.
7+
// // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8+
// //
9+
// //===----------------------------------------------------------------------===//
10+
11+
#include "src/signal/signal.h"
12+
#include "src/sys/time/setitimer.h"
13+
#include "test/UnitTest/ErrnoSetterMatcher.h"
14+
#include "test/UnitTest/Test.h"
15+
16+
#include <atomic>
17+
#include <signal.h>
18+
#include <sys/time.h>
19+
20+
using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;
21+
22+
static std::atomic<bool> timer_fired(false);
23+
24+
extern "C" void handle_sigalrm(int) { timer_fired.store(true); }
25+
26+
TEST(LlvmLibcSysTimeSetitimerTest, SmokeTest) {
27+
errno = 0;
28+
struct sigaction sa;
29+
sa.sa_handler = handle_sigalrm;
30+
sigemptyset(&sa.sa_mask);
31+
sa.sa_flags = 0;
32+
sigaction(SIGALRM, &sa, nullptr);
33+
34+
struct itimerval timer;
35+
timer.it_value.tv_sec = 0;
36+
timer.it_value.tv_usec = 200000;
37+
timer.it_interval.tv_sec = 0;
38+
timer.it_interval.tv_usec = 0; // One-shot timer
39+
40+
ASSERT_THAT(LIBC_NAMESPACE::setitimer(ITIMER_REAL, &timer, nullptr),
41+
returns(EQ(0)).with_errno(EQ(0)));
42+
43+
while (true) {
44+
if (timer_fired.load())
45+
break;
46+
}
47+
48+
ASSERT_TRUE(timer_fired.load());
49+
}

0 commit comments

Comments
 (0)