Skip to content

Commit abc4084

Browse files
mikhailramalhoJaddyen
authored andcommitted
[libc] Enable setitimer and getitimer functions on riscv (llvm#139182)
These functions don't have a _time64 variant, so we can't use time_t directly (since our time_t is a uint64_t). The workaround is to use longs when doing the syscall and write back when necessary.
1 parent 7e1837e commit abc4084

File tree

3 files changed

+42
-6
lines changed

3 files changed

+42
-6
lines changed

libc/config/linux/riscv/entrypoints.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,8 @@ set(TARGET_LIBC_ENTRYPOINTS
370370
libc.src.sys.uio.readv
371371

372372
# sys/time.h entrypoints
373-
# libc.src.sys.time.setitimer
374-
# libc.src.sys.time.getitimer
373+
libc.src.sys.time.setitimer
374+
libc.src.sys.time.getitimer
375375
)
376376

377377
if(LLVM_LIBC_INCLUDE_SCUDO)

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,22 @@
1616
namespace LIBC_NAMESPACE_DECL {
1717

1818
LLVM_LIBC_FUNCTION(int, getitimer, (int which, struct itimerval *curr_value)) {
19-
long ret =
20-
LIBC_NAMESPACE::syscall_impl<long>(SYS_getitimer, which, curr_value);
19+
long ret = 0;
20+
if constexpr (sizeof(time_t) > sizeof(long)) {
21+
// There is no SYS_getitimer_time64 call, so we can't use time_t directly.
22+
long curr_value32[4];
23+
ret =
24+
LIBC_NAMESPACE::syscall_impl<long>(SYS_getitimer, which, curr_value32);
25+
if (!ret) {
26+
curr_value->it_interval.tv_sec = curr_value32[0];
27+
curr_value->it_interval.tv_usec = curr_value32[1];
28+
curr_value->it_value.tv_sec = curr_value32[2];
29+
curr_value->it_value.tv_usec = curr_value32[3];
30+
}
31+
} else {
32+
ret = LIBC_NAMESPACE::syscall_impl<long>(SYS_getitimer, which, curr_value);
33+
}
34+
2135
// On failure, return -1 and set errno.
2236
if (ret < 0) {
2337
libc_errno = static_cast<int>(-ret);

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

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,30 @@ namespace LIBC_NAMESPACE_DECL {
1717
LLVM_LIBC_FUNCTION(int, setitimer,
1818
(int which, const struct itimerval *new_value,
1919
struct itimerval *old_value)) {
20-
long ret = LIBC_NAMESPACE::syscall_impl<long>(SYS_setitimer, which, new_value,
21-
old_value);
20+
long ret = 0;
21+
if constexpr (sizeof(time_t) > sizeof(long)) {
22+
// There is no SYS_setitimer_time64 call, so we can't use time_t directly,
23+
// and need to convert it to long first.
24+
long new_value32[4] = {static_cast<long>(new_value->it_interval.tv_sec),
25+
new_value->it_interval.tv_usec,
26+
static_cast<long>(new_value->it_value.tv_sec),
27+
new_value->it_value.tv_usec};
28+
long old_value32[4];
29+
30+
ret = LIBC_NAMESPACE::syscall_impl<long>(SYS_setitimer, which, new_value32,
31+
old_value32);
32+
33+
if (!ret && old_value) {
34+
old_value->it_interval.tv_sec = old_value32[0];
35+
old_value->it_interval.tv_usec = old_value32[1];
36+
old_value->it_value.tv_sec = old_value32[2];
37+
old_value->it_value.tv_usec = old_value32[3];
38+
}
39+
} else {
40+
ret = LIBC_NAMESPACE::syscall_impl<long>(SYS_setitimer, which, new_value,
41+
old_value);
42+
}
43+
2244
// On failure, return -1 and set errno.
2345
if (ret < 0) {
2446
libc_errno = static_cast<int>(-ret);

0 commit comments

Comments
 (0)