PowerPC is big-endian architecture, so there are some significant differences in comparison with time64 support for little-endian architectures like ARM and xtensa. The main difference is that we strictly need to pass two 64bit values to system calls because Linux Kernel internally uses `struct __ketnel_timespec` and similar, which consists of two 64bit fields. For this reason many files have been changed to convert timespec-family structures (mixed of 64bit and 32bit values) to the 64bit-only structures for using as system calls args. Now time64 syscalls works properly both for LE (ARM, xtensa) and BE (PPC) memory layouts.
Signed-off-by: Dmitry Chestnykh dm.chestnykh@gmail.com --- extra/Configs/Config.in | 2 +- libc/inet/socketcalls.c | 16 ++++++++- libc/misc/sysvipc/sem.c | 16 ++++++++- libc/signal/sigwait.c | 3 +- libc/sysdeps/linux/common/__rt_sigtimedwait.c | 23 ++++++++++-- libc/sysdeps/linux/common/__rt_sigwaitinfo.c | 2 +- libc/sysdeps/linux/common/alarm.c | 2 +- libc/sysdeps/linux/common/clock_getres.c | 20 ++++++++++- libc/sysdeps/linux/common/clock_gettime.c | 21 ++++++++++- libc/sysdeps/linux/common/clock_settime.c | 17 ++++++++- libc/sysdeps/linux/common/ppoll.c | 15 +++++++- libc/sysdeps/linux/common/pselect.c | 15 +++++++- libc/sysdeps/linux/common/select.c | 23 +++++++++--- libc/sysdeps/linux/common/time.c | 2 +- libc/sysdeps/linux/common/timerfd.c | 23 +++++++++++- libc/sysdeps/linux/common/utimensat.c | 23 +++++++++++- libc/sysdeps/linux/powerpc/bits/kernel_stat.h | 28 +++++++++++++-- libc/sysdeps/linux/powerpc/bits/sem.h | 16 +++++++++ libpthread/nptl/pthread_mutex_timedlock.c | 20 +++++++++-- .../sysdeps/pthread/pthread_cond_timedwait.c | 5 +-- .../pthread/pthread_rwlock_timedrdlock.c | 5 +-- .../pthread/pthread_rwlock_timedwrlock.c | 5 +-- .../sysdeps/unix/sysv/linux/lowlevellock.c | 10 +++--- .../sysdeps/unix/sysv/linux/lowlevellock.h | 35 +++++++++++++++++-- .../unix/sysv/linux/lowlevelrobustlock.c | 6 ++-- .../sysdeps/unix/sysv/linux/sem_timedwait.c | 6 ++-- .../sysdeps/unix/sysv/linux/timer_settime.c | 19 +++++++++- librt/clock_gettime.c | 20 +++++++++-- librt/clock_nanosleep.c | 23 ++++++++++-- librt/mq_timedreceive.c | 22 ++++++++++-- librt/mq_timedsend.c | 20 ++++++++++- librt/timer_settime.c | 28 +++++++++++++-- 32 files changed, 435 insertions(+), 56 deletions(-)
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index 9351dffc8..f11a63b79 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -1026,7 +1026,7 @@ config UCLIBC_FALLBACK_TO_ETC_LOCALTIME
config UCLIBC_USE_TIME64 bool "Use *time64 syscalls instead of 32bit ones (if possible)" - depends on TARGET_arm || TARGET_xtensa + depends on TARGET_arm || TARGET_powerpc || TARGET_xtensa # TODO: add support for other architectures default n
diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c index eb0983698..7ec439887 100644 --- a/libc/inet/socketcalls.c +++ b/libc/inet/socketcalls.c @@ -268,12 +268,26 @@ lt_libc_hidden(recvmsg) #endif
#ifdef L_recvmmsg + +#if defined(__UCLIBC_USE_TIME64__) + +struct ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; + +#endif + #ifdef __ASSUME_RECVMMSG_SYSCALL static ssize_t __NC(recvmmsg)(int sockfd, struct mmsghdr *msg, size_t vlen, int flags, struct timespec *tmo) { # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_recvmmsg_time64) - return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo); + struct ts64_struct __ts64 = { + .tv_sec = tmo ? tmo->tv_sec : 0, + .tv_nsec = tmo ? tmo->tv_nsec : 0 + }; + return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo ? &__ts64 : 0); # elif defined(__NR_recvmmsg) return (ssize_t)INLINE_SYSCALL(recvmmsg, 5, sockfd, msg, vlen, flags, tmo); # elif __NR_socketcall diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c index cd541761c..d0bd0ba28 100644 --- a/libc/misc/sysvipc/sem.c +++ b/libc/misc/sysvipc/sem.c @@ -96,7 +96,21 @@ int semop (int semid, struct sembuf *sops, size_t nsops) #ifdef L_semtimedop
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_semtimedop_time64) -_syscall4_time64(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout) + +struct ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; + +int semtimedop(int semid, struct sembuf *sops, size_t nsops, const struct timespec *timeout) { + struct ts64_struct __ts64 = { + .tv_sec = timeout ? timeout->tv_sec : 0, + .tv_nsec = timeout ? timeout->tv_nsec : 0 + }; + + return INLINE_SYSCALL(semtimedop_time64, 4, semid, sops, nsops, timeout ? &__ts64 : 0); +} + #elif defined(__NR_semtimedop) _syscall4(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout)
diff --git a/libc/signal/sigwait.c b/libc/signal/sigwait.c index 3557a039e..b237534cd 100644 --- a/libc/signal/sigwait.c +++ b/libc/signal/sigwait.c @@ -24,7 +24,8 @@ #include <signal.h> #include <cancel.h>
-#if defined __NR_rt_sigtimedwait && defined __UCLIBC_HAS_REALTIME__ +#if (defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64))) && \ + defined(__UCLIBC_HAS_REALTIME__)
#include <string.h>
diff --git a/libc/sysdeps/linux/common/__rt_sigtimedwait.c b/libc/sysdeps/linux/common/__rt_sigtimedwait.c index bd82ca6d5..cd25fe177 100644 --- a/libc/sysdeps/linux/common/__rt_sigtimedwait.c +++ b/libc/sysdeps/linux/common/__rt_sigtimedwait.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__NR_rt_sigtimedwait_time64) && defined(__UCLIBC_USE_TIME64__)) # include <signal.h> # include <cancel.h> # ifdef __UCLIBC_HAS_THREADS_NATIVE__ @@ -21,6 +21,15 @@ # include <string.h> # endif
+#if defined(__UCLIBC_USE_TIME64__) + +struct ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; + +#endif + int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, const struct timespec *timeout) { @@ -53,8 +62,12 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, real size of the user-level sigset_t. */ /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64) + struct ts64_struct __ts64 = { + .tv_sec = timeout ? timeout->tv_sec : 0, + .tv_nsec = timeout ? timeout->tv_nsec : 0 + }; result = INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info, - timeout, __SYSCALL_SIGSET_T_SIZE); + timeout ? &__ts64 : 0, __SYSCALL_SIGSET_T_SIZE); # else result = INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); @@ -71,8 +84,12 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, # else /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64) + struct ts64_struct __ts64 = { + .tv_sec = timeout ? timeout->tv_sec : 0, + .tv_nsec = timeout ? timeout->tv_nsec : 0 + }; return INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info, - timeout, __SYSCALL_SIGSET_T_SIZE); + timeout ? &__ts64 : 0, __SYSCALL_SIGSET_T_SIZE); # else return INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); diff --git a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c index d2d176a64..7830b2e2c 100644 --- a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c +++ b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)) # define __need_NULL # include <stddef.h> # include <signal.h> diff --git a/libc/sysdeps/linux/common/alarm.c b/libc/sysdeps/linux/common/alarm.c index 4e6e2215b..861f6ad8e 100644 --- a/libc/sysdeps/linux/common/alarm.c +++ b/libc/sysdeps/linux/common/alarm.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <unistd.h>
-#ifdef __NR_alarm && !defined(__UCLIBC_USE_TIME64__) +#if defined(__NR_alarm) && !defined(__UCLIBC_USE_TIME64__) _syscall1(unsigned int, alarm, unsigned int, seconds) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/clock_getres.c b/libc/sysdeps/linux/common/clock_getres.c index d4b989958..c72b0a21c 100644 --- a/libc/sysdeps/linux/common/clock_getres.c +++ b/libc/sysdeps/linux/common/clock_getres.c @@ -10,9 +10,27 @@ #include <sys/syscall.h> #include <time.h>
+#if defined(__UCLIBC_USE_TIME64__) + +struct ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; + +#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64) -_syscall2_time64(int, clock_getres, clockid_t, clock_id, struct timespec*, res) +int clock_getres(clockid_t clock_id, struct timespec *res) +{ + struct ts64_struct __ts64; + int __ret = INLINE_SYSCALL(clock_getres_time64, 2, clock_id, &__ts64); + if (__ret == 0 && res) { + res->tv_sec = __ts64.tv_sec; + res->tv_nsec = __ts64.tv_nsec; + }; + + return __ret; +} #elif defined(__NR_clock_getres) _syscall2(int, clock_getres, clockid_t, clock_id, struct timespec*, res) #else diff --git a/libc/sysdeps/linux/common/clock_gettime.c b/libc/sysdeps/linux/common/clock_gettime.c index a595bd691..dbb767c94 100644 --- a/libc/sysdeps/linux/common/clock_gettime.c +++ b/libc/sysdeps/linux/common/clock_gettime.c @@ -11,8 +11,27 @@ #include <sys/syscall.h> #include <time.h>
+#if defined(__UCLIBC_USE_TIME64__) + +struct ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; + +#endif + #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) -_syscall2_64(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) +int clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + struct ts64_struct __ts64; + int __ret = INLINE_SYSCALL(clock_gettime64, 2, clock_id, &__ts64); + if (tp) { + tp->tv_sec = __ts64.tv_sec; + tp->tv_nsec = __ts64.tv_nsec; + } + + return __ret; +} #elif defined(__NR_clock_gettime) _syscall2(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/clock_settime.c b/libc/sysdeps/linux/common/clock_settime.c index 89550af5a..54bfa20e8 100644 --- a/libc/sysdeps/linux/common/clock_settime.c +++ b/libc/sysdeps/linux/common/clock_settime.c @@ -12,7 +12,22 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_settime64) -_syscall2_64(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) + +struct ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; + +int clock_settime(clockid_t clock_id, const struct timespec *tp) +{ + struct ts64_struct __ts64 = { + .tv_sec = tp->tv_sec, + .tv_nsec = tp->tv_nsec + }; + + return INLINE_SYSCALL(clock_settime64, 2, clock_id, &__ts64); +} + #elif defined(__NR_clock_settime) _syscall2(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/ppoll.c b/libc/sysdeps/linux/common/ppoll.c index cb36149c5..16d836b6f 100644 --- a/libc/sysdeps/linux/common/ppoll.c +++ b/libc/sysdeps/linux/common/ppoll.c @@ -26,6 +26,15 @@ #include <sys/poll.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__) + +struct ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; + +#endif + static int __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, const sigset_t *sigmask) @@ -38,7 +47,11 @@ __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, timeout = &tval; } #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_ppoll_time64) - return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE); + struct ts64_struct __ts64 = { + .tv_sec = timeout ? timeout->tv_sec : 0, + .tv_nsec = timeout ? timeout->tv_nsec : 0 + }; + return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout ? &__ts64 : 0, sigmask, __SYSCALL_SIGSET_T_SIZE); #else return INLINE_SYSCALL(ppoll, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE); #endif diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c index 23bdab5cf..a189624ec 100644 --- a/libc/sysdeps/linux/common/pselect.c +++ b/libc/sysdeps/linux/common/pselect.c @@ -26,6 +26,15 @@ #include <signal.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__) + +struct ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; + +#endif + static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask) @@ -57,7 +66,11 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, sigmask = (void *)&data; } #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64) - return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask); + struct ts64_struct __ts64 = { + .tv_sec = timeout ? timeout->tv_sec : 0, + .tv_nsec = timeout ? timeout->tv_nsec : 0 + }; + return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout ? &__ts64 : 0, sigmask); #else return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask); #endif diff --git a/libc/sysdeps/linux/common/select.c b/libc/sysdeps/linux/common/select.c index 3132a109c..a55a61df1 100644 --- a/libc/sysdeps/linux/common/select.c +++ b/libc/sysdeps/linux/common/select.c @@ -15,17 +15,22 @@ # define __NR_select __NR__newselect #endif
-#if !defined __NR_select && defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) # include <stdint.h> # define USEC_PER_SEC 1000000L #endif
+#if defined(__UCLIBC_USE_TIME64__) +struct ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; +#endif + int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { -#ifdef __NR_select - return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, timeout); -#elif defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) struct timespec _ts, *ts = 0; if (timeout) { uint32_t usec; @@ -47,8 +52,18 @@ int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
ts = &_ts; } +#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64) + struct ts64_struct __ts64 = { + .tv_sec = ts ? ts->tv_sec : 0, + .tv_nsec = ts ? ts->tv_nsec : 0 + }; + return INLINE_SYSCALL(pselect6_time64, 6, n, readfds, writefds, exceptfds, timeout ? &__ts64 : 0, 0); +#else return INLINE_SYSCALL(pselect6, 6, n, readfds, writefds, exceptfds, ts, 0); #endif +#elif defined(__NR_select) + return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, timeout); +#endif } /* we should guard it, but we need it in other files, so let it fail * if we miss any of the syscalls */ diff --git a/libc/sysdeps/linux/common/time.c b/libc/sysdeps/linux/common/time.c index 22403f174..d084ffaad 100644 --- a/libc/sysdeps/linux/common/time.c +++ b/libc/sysdeps/linux/common/time.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <time.h>
-#ifdef __NR_time +#if defined(__NR_time) && !defined(__UCLIBC_USE_TIME64__) _syscall_noerr1(time_t, time, time_t *, t) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/timerfd.c b/libc/sysdeps/linux/common/timerfd.c index 0f19b44ed..04db6ed00 100644 --- a/libc/sysdeps/linux/common/timerfd.c +++ b/libc/sysdeps/linux/common/timerfd.c @@ -16,12 +16,33 @@ _syscall2(int, timerfd_create, int, clockid, int, flags) #endif
+#if defined(__UCLIBC_USE_TIME64__) + +struct its64_struct { + __S64_TYPE interval_tv_sec; + __S64_TYPE interval_tv_nsec; + __S64_TYPE value_tv_sec; + __S64_TYPE value_tv_nsec; +}; + +#endif + /* * timerfd_settime() */ #if defined(__NR_timerfd_settime) || defined(__NR_timerfd_settime64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timerfd_settime64) -_syscall4_64(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) +int timerfd_settime(int ufd, int flags, const struct itimerspec *utmr, struct itimerspec *otmr) +{ + struct its64_struct __its64 = { + .interval_tv_sec = utmr->it_interval.tv_sec, + .interval_tv_nsec = utmr->it_interval.tv_nsec, + .value_tv_sec = utmr->it_value.tv_sec, + .value_tv_nsec = utmr->it_value.tv_nsec, + }; + + return INLINE_SYSCALL(timerfd_settime64, 4, ufd, flags, &__its64, otmr); +} #else _syscall4(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) #endif diff --git a/libc/sysdeps/linux/common/utimensat.c b/libc/sysdeps/linux/common/utimensat.c index 6a78ebb4f..0c87b5c45 100644 --- a/libc/sysdeps/linux/common/utimensat.c +++ b/libc/sysdeps/linux/common/utimensat.c @@ -9,9 +9,30 @@ #include <sys/syscall.h> #include <sys/stat.h>
+#if defined(__UCLIBC_USE_TIME64__) + +struct uts64_struct { + __S64_TYPE tv_sec1; + __S64_TYPE tv_nsec1; + __S64_TYPE tv_sec2; + __S64_TYPE tv_nsec2; +}; + +#endif + #if defined(__NR_utimensat) || defined(__NR_utimensat_time64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_utimensat_time64) -_syscall4_time64(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) +int utimensat(int fd, const char *path, const struct timespec times[2], int flags) +{ + struct uts64_struct __uts64 = { + .tv_sec1 = times ? times[0].tv_sec : 0, + .tv_nsec1 = times ? times[0].tv_nsec : 0, + .tv_sec2 = times ? times[1].tv_sec : 0, + .tv_nsec2 = times ? times[1].tv_nsec : 0 + }; + + return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ? &__uts64 : 0, flags); +} #else _syscall4(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) #endif diff --git a/libc/sysdeps/linux/powerpc/bits/kernel_stat.h b/libc/sysdeps/linux/powerpc/bits/kernel_stat.h index ce62b2ba2..0e76120ab 100644 --- a/libc/sysdeps/linux/powerpc/bits/kernel_stat.h +++ b/libc/sysdeps/linux/powerpc/bits/kernel_stat.h @@ -5,6 +5,16 @@ * struct kernel_stat should look like... It turns out each arch has a * different opinion on the subject... */
+#if defined(__UCLIBC_USE_TIME64__) +#include <bits/types.h> + +struct ts32_struct { + __S32_TYPE tv_sec; + __S32_TYPE tv_nsec; +}; + +#endif + #if __WORDSIZE == 64 #define kernel_stat kernel_stat64 #else @@ -19,9 +29,15 @@ struct kernel_stat { __kernel_off_t st_size; unsigned long st_blksize; unsigned long st_blocks; +#if defined(__UCLIBC_USE_TIME64__) + struct ts32_struct __st_atim32; + struct ts32_struct __st_mtim32; + struct ts32_struct __st_ctim32; +#else struct timespec st_atim; struct timespec st_mtim; struct timespec st_ctim; +#endif unsigned long __unused4; unsigned long __unused5; }; @@ -39,9 +55,15 @@ struct kernel_stat64 { long long st_size; /* Size of file, in bytes. */ long st_blksize; /* Optimal block size for I/O. */ long long st_blocks; /* Number 512-byte blocks allocated. */ - struct timespec st_atim; /* Time of last access. */ - struct timespec st_mtim; /* Time of last modification. */ - struct timespec st_ctim; /* Time of last status change. */ +#if defined(__UCLIBC_USE_TIME64__) + struct ts32_struct __st_atim32; + struct ts32_struct __st_mtim32; + struct ts32_struct __st_ctim32; +#else + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; +#endif unsigned long int __uclibc_unused4; unsigned long int __uclibc_unused5; }; diff --git a/libc/sysdeps/linux/powerpc/bits/sem.h b/libc/sysdeps/linux/powerpc/bits/sem.h index a9d895374..8d338eac0 100644 --- a/libc/sysdeps/linux/powerpc/bits/sem.h +++ b/libc/sysdeps/linux/powerpc/bits/sem.h @@ -35,6 +35,7 @@ #define SETALL 17 /* set all semval's */
+ /* Data structure describing a set of semaphores. */ struct semid_ds { @@ -42,16 +43,31 @@ struct semid_ds #if __WORDSIZE == 32 unsigned int __uclibc_unused1; #endif +#if defined(__UCLIBC_USE_TIME64__) + unsigned long int __sem_otime_internal_1; /* last semop() time */ + unsigned long int __sem_otime_internal_2; +#else __time_t sem_otime; /* last semop() time */ +#endif #if __WORDSIZE == 32 unsigned int __uclibc_unused2; #endif +#if defined(__UCLIBC_USE_TIME64__) + unsigned long int __sem_ctime_internal_1; /* last time changed by semctl() */ + unsigned long int __sem_ctime_internal_2; +#else __time_t sem_ctime; /* last time changed by semctl() */ +#endif unsigned long int sem_nsems; /* number of semaphores in set */ +#if defined(__UCLIBC_USE_TIME64__) + __time_t sem_otime; + __time_t sem_ctime; +#endif unsigned long __uclibc_unused3; unsigned long __uclibc_unused4; };
+ /* The user should define a union like the following to use it for arguments for `semctl'.
diff --git a/libpthread/nptl/pthread_mutex_timedlock.c b/libpthread/nptl/pthread_mutex_timedlock.c index 25f9ec3b2..d55495683 100644 --- a/libpthread/nptl/pthread_mutex_timedlock.c +++ b/libpthread/nptl/pthread_mutex_timedlock.c @@ -23,6 +23,15 @@ #include <lowlevellock.h> #include <not-cancel.h>
+#if defined(__UCLIBC_USE_TIME64__) + +struct ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; + +#endif + /* We need to build this function with optimization to avoid * lll_timedlock erroring out with * error: can't find a register in class ‘GENERAL_REGS’ while reloading ‘asm’ @@ -265,10 +274,14 @@ pthread_mutex_timedlock ( INTERNAL_SYSCALL_DECL (__err);
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64) + struct ts64_struct __ts64 = { + .tv_sec = abstime ? abstime->tv_sec : 0, + .tv_nsec = abstime ? abstime->tv_nsec : 0 + }; int e = INTERNAL_SYSCALL (futex_time64, __err, 4, &mutex->__data.__lock, __lll_private_flag (FUTEX_LOCK_PI, private), 1, - abstime); + &__ts64); #else int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock, __lll_private_flag (FUTEX_LOCK_PI, @@ -454,7 +467,7 @@ pthread_mutex_timedlock ( }
struct timeval tv; - struct timespec rt; + struct timespec rt, *rtp;
/* Get the current time. */ (void) gettimeofday (&tv, NULL); @@ -475,8 +488,9 @@ pthread_mutex_timedlock ( goto failpp; }
+ rtp = &rt; lll_futex_timed_wait (&mutex->__data.__lock, - ceilval | 2, &rt, + ceilval | 2, rtp, PTHREAD_MUTEX_PSHARED (mutex)); } } diff --git a/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c b/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c index 49aab0293..1ea2a888a 100644 --- a/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c +++ b/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c @@ -95,7 +95,7 @@ __pthread_cond_timedwait (
while (1) { - struct timespec rt; + struct timespec rt, *rtp; { #ifdef __NR_clock_gettime INTERNAL_SYSCALL_DECL (err); @@ -164,8 +164,9 @@ __pthread_cond_timedwait ( cbuffer.oldtype = __pthread_enable_asynccancel ();
/* Wait until woken by signal or broadcast. */ + rtp = &rt; err = lll_futex_timed_wait (&cond->__data.__futex, - futex_val, &rt, pshared); + futex_val, rtp, pshared);
/* Disable asynchronous cancellation. */ __pthread_disable_asynccancel (cbuffer.oldtype); diff --git a/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c b/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c index 596f5df51..379e92b43 100644 --- a/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c +++ b/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c @@ -81,7 +81,7 @@ pthread_rwlock_timedrdlock ( (void) gettimeofday (&tv, NULL);
/* Convert the absolute timeout value to a relative timeout. */ - struct timespec rt; + struct timespec rt, *rtp; rt.tv_sec = abstime->tv_sec - tv.tv_sec; rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000; if (rt.tv_nsec < 0) @@ -112,8 +112,9 @@ pthread_rwlock_timedrdlock ( lll_unlock (rwlock->__data.__lock, rwlock->__data.__shared);
/* Wait for the writer to finish. */ + rtp = &rt; err = lll_futex_timed_wait (&rwlock->__data.__readers_wakeup, - waitval, &rt, rwlock->__data.__shared); + waitval, rtp, rwlock->__data.__shared);
/* Get the lock. */ lll_lock (rwlock->__data.__lock, rwlock->__data.__shared); diff --git a/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c b/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c index 0b04b357a..3ce9f9b13 100644 --- a/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c +++ b/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c @@ -72,7 +72,7 @@ pthread_rwlock_timedwrlock ( (void) gettimeofday (&tv, NULL);
/* Convert the absolute timeout value to a relative timeout. */ - struct timespec rt; + struct timespec rt, *rtp; rt.tv_sec = abstime->tv_sec - tv.tv_sec; rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000; if (rt.tv_nsec < 0) @@ -102,8 +102,9 @@ pthread_rwlock_timedwrlock ( lll_unlock (rwlock->__data.__lock, rwlock->__data.__shared);
/* Wait for the writer or reader(s) to finish. */ + rtp = &rt; err = lll_futex_timed_wait (&rwlock->__data.__writer_wakeup, - waitval, &rt, rwlock->__data.__shared); + waitval, rtp, rwlock->__data.__shared);
/* Get the lock. */ lll_lock (rwlock->__data.__lock, rwlock->__data.__shared); diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c index 4294a20b0..5f7301976 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c @@ -63,7 +63,7 @@ __lll_timedlock_wait (int *futex, const struct timespec *abstime, int private) (void) gettimeofday (&tv, NULL);
/* Compute relative timeout. */ - struct timespec rt; + struct timespec rt, *rtp; rt.tv_sec = abstime->tv_sec - tv.tv_sec; rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000; if (rt.tv_nsec < 0) @@ -76,7 +76,8 @@ __lll_timedlock_wait (int *futex, const struct timespec *abstime, int private) return ETIMEDOUT;
/* Wait. */ - lll_futex_timed_wait (futex, 2, &rt, private); + rtp = &rt; + lll_futex_timed_wait (futex, 2, rtp, private); }
return 0; @@ -95,7 +96,7 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime) while ((tid = *tidp) != 0) { struct timeval tv; - struct timespec rt; + struct timespec rt, *rtp;
/* Get the current time. */ (void) __gettimeofday (&tv, NULL); @@ -115,7 +116,8 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime)
/* Wait until thread terminates. The kernel so far does not use the private futex operations for this. */ - if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) == -ETIMEDOUT) + rtp = &rt; + if (lll_futex_timed_wait (tidp, tid, rtp, LLL_SHARED) == -ETIMEDOUT) return ETIMEDOUT; }
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h index e72fe5234..4209a21d3 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h @@ -71,18 +71,49 @@ # endif #endif
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64) + #define lll_futex_wait(futexp, val, private) \ - lll_futex_timed_wait(futexp, val, NULL, private) + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAIT, private), \ + (val), NULL); \ + __ret; \ + }) + +#else + +#define lll_futex_wait(futexp, val, private) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAIT, private), \ + (val), NULL); \ + __ret; \ + }) + +#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+struct __ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; + +#define ptr_timespec_to_ts64(ts) \ + (&(struct __ts64_struct) {.tv_sec = ts->tv_sec, .tv_nsec = ts->tv_nsec}) + #define lll_futex_timed_wait(futexp, val, timespec, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ long int __ret; \ __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \ __lll_private_flag (FUTEX_WAIT, private), \ - (val), (timespec)); \ + (val), (ptr_timespec_to_ts64(timespec))); \ __ret; \ })
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c index 7b4e84343..5781359fb 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c @@ -73,7 +73,7 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime, do { struct timeval tv; - struct timespec rt; + struct timespec rt, *rtp;
/* Get the current time. */ (void) __gettimeofday (&tv, NULL); @@ -99,8 +99,8 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime, if (oldval != newval && atomic_compare_and_exchange_bool_acq (futex, newval, oldval)) continue; - - lll_futex_timed_wait (futex, newval, &rt, private); + rtp = &rt; + lll_futex_timed_wait (futex, newval, rtp, private);
try: ; diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c index 8c3ef47c5..05ba5bc13 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c @@ -51,7 +51,7 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime) while (1) { struct timeval tv; - struct timespec rt; + struct timespec rt, *rtp; int sec, nsec;
/* Get the current time. */ @@ -79,10 +79,12 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime) rt.tv_sec = sec; rt.tv_nsec = nsec;
+ rtp = &rt; + /* Enable asynchronous cancellation. Required by the standard. */ int oldtype = __pthread_enable_asynccancel ();
- err = lll_futex_timed_wait (&isem->value, 0, &rt, + err = lll_futex_timed_wait (&isem->value, 0, rtp, isem->private ^ FUTEX_PRIVATE_FLAG);
/* Disable asynchronous cancellation. */ diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c index 80d242f21..d7c2aa804 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c @@ -38,6 +38,17 @@ static int compat_timer_settime (timer_t timerid, int flags, # define timer_settime timer_settime_alias # endif
+#if defined(__UCLIBC_USE_TIME64__) + +struct its64_struct { + __S64_TYPE interval_tv_sec; + __S64_TYPE interval_tv_nsec; + __S64_TYPE value_tv_sec; + __S64_TYPE value_tv_nsec; +}; + +#endif +
int timer_settime ( @@ -55,8 +66,14 @@ timer_settime (
/* Delete the kernel timer object. */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) + struct its64_struct __its64 = { + .interval_tv_sec = value->it_interval.tv_sec, + .interval_tv_nsec = value->it_interval.tv_nsec, + .value_tv_sec = value->it_value.tv_sec, + .value_tv_nsec = value->it_value.tv_nsec, + }; int res = INLINE_SYSCALL (timer_settime64, 4, kt->ktimerid, flags, - value, ovalue); + value ? &__its64 : 0, ovalue); # else int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags, value, ovalue); diff --git a/librt/clock_gettime.c b/librt/clock_gettime.c index b66b60231..eff40d68f 100644 --- a/librt/clock_gettime.c +++ b/librt/clock_gettime.c @@ -22,10 +22,26 @@ #include <sys/time.h> #include "kernel-posix-cpu-timers.h"
+#if defined(__UCLIBC_USE_TIME64__) + +struct ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; + +#endif + #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) #define SYSCALL_GETTIME \ - retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, tp); \ - break + { \ + struct ts64_struct __ts64; \ + retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, &__ts64); \ + if (tp) { \ + tp->tv_sec = __ts64.tv_sec; \ + tp->tv_nsec = __ts64.tv_nsec; \ + } \ + break; \ + } #else #define SYSCALL_GETTIME \ retval = INLINE_SYSCALL (clock_gettime, 2, clock_id, tp); \ diff --git a/librt/clock_nanosleep.c b/librt/clock_nanosleep.c index eaae75720..786f7eede 100644 --- a/librt/clock_nanosleep.c +++ b/librt/clock_nanosleep.c @@ -21,6 +21,14 @@
#include "kernel-posix-cpu-timers.h"
+#if defined(__UCLIBC_USE_TIME64__) + +struct ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; + +#endif
/* We can simply use the syscall. The CPU clocks are not supported with this function. */ @@ -36,18 +44,27 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, if (clock_id == CLOCK_PROCESS_CPUTIME_ID) clock_id = MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED);
- if (SINGLE_THREAD_P) + if (SINGLE_THREAD_P) { #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64) - r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem); + struct ts64_struct __ts64 = { + .tv_sec = req ? req->tv_sec : 0, + .tv_nsec = req ? req->tv_nsec : 0 + }; + r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req ? &__ts64 : 0, rem); #else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); #endif + } else { #ifdef __NEW_THREADS int oldstate = LIBC_CANCEL_ASYNC (); #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64) - r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem); + struct ts64_struct __ts64_2 = { + .tv_sec = req ? req->tv_sec : 0, + .tv_nsec = req ? req->tv_nsec : 0 + }; + r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req ? &__ts64_2 : 0, rem); #else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); diff --git a/librt/mq_timedreceive.c b/librt/mq_timedreceive.c index db1ae1aa8..818f54faa 100644 --- a/librt/mq_timedreceive.c +++ b/librt/mq_timedreceive.c @@ -8,13 +8,29 @@ #include <unistd.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__) + +struct ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; + +#endif + #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedreceive_time64) -#define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive_time64 +int _NC(mq_timedreceive)(mqd_t mqdes, char *restrict msg_ptr, size_t msg_len, unsigned int *restrict msq_prio, const struct timespec *restrict abs_timeout) +{ + struct ts64_struct __ts64 = { + .tv_sec = abs_timeout ? abs_timeout->tv_sec : 0, + .tv_nsec = abs_timeout ? abs_timeout->tv_nsec : 0, + }; + + return INLINE_SYSCALL(mq_timedreceive_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, abs_timeout ? &__ts64 : 0); +} #else #define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive -#endif - _syscall5(ssize_t, __NC(mq_timedreceive), mqd_t, mqdes, char *__restrict, msg_ptr, size_t, msg_len, unsigned int *__restrict, msq_prio, const struct timespec *__restrict, abs_timeout) +#endif
CANCELLABLE_SYSCALL(ssize_t, mq_timedreceive, (mqd_t mqdes, char *__restrict msg_ptr, size_t msq_len, unsigned int *__restrict msq_prio, const struct timespec *__restrict abs_timeout), (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) diff --git a/librt/mq_timedsend.c b/librt/mq_timedsend.c index 6afaf5157..e8deea9cb 100644 --- a/librt/mq_timedsend.c +++ b/librt/mq_timedsend.c @@ -8,13 +8,31 @@ #include <unistd.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__) + +struct ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; + +#endif + #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedsend_time64) #define __NR___mq_timedsend_nocancel __NR_mq_timedsend_time64 +int _NC(mq_timedsend)(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msq_prio, const struct timespec *abs_timeout) +{ + struct ts64_struct __ts64 = { + .tv_sec = abs_timeout ? abs_timeout->tv_sec : 0, + .tv_nsec = abs_timeout ? abs_timeout->tv_nsec : 0, + }; + + return INLINE_SYSCALL(mq_timedsend_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, abs_timeout ? &__ts64 : 0); +} #else #define __NR___mq_timedsend_nocancel __NR_mq_timedsend +_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) #endif
-_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) CANCELLABLE_SYSCALL(int, mq_timedsend, (mqd_t mqdes, const char *msg_ptr, size_t msq_len, unsigned int msq_prio, const struct timespec *abs_timeout), (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) lt_libc_hidden(mq_timedsend) diff --git a/librt/timer_settime.c b/librt/timer_settime.c index 022880297..31202b07a 100644 --- a/librt/timer_settime.c +++ b/librt/timer_settime.c @@ -9,13 +9,36 @@
#include "kernel-posix-timers.h"
+#if defined(__UCLIBC_USE_TIME64__) + +struct its64_struct { + __S64_TYPE interval_tv_sec; + __S64_TYPE interval_tv_nsec; + __S64_TYPE value_tv_sec; + __S64_TYPE value_tv_nsec; +}; + +#endif + #if defined(__NR_timer_settime) || defined(__NR_timer_settime64)
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) -#define __NR___syscall_timer_settime __NR_timer_settime64 +int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue) +{ + struct timer *kt = (struct timer *)timerid; + + struct its64_struct __its64 = { + .interval_tv_sec = value->it_interval.tv_sec, + .interval_tv_nsec = value->it_interval.tv_nsec, + .value_tv_sec = value->it_value.tv_sec, + .value_tv_nsec = value->it_value.tv_nsec, + }; + + return INLINE_SYSCALL(timer_settime64, 4, kt->ktimerid, flags, value ? &__its64: 0, ovalue); +} #else + #define __NR___syscall_timer_settime __NR_timer_settime -#endif
static __inline__ _syscall4(int, __syscall_timer_settime, kernel_timer_t, ktimerid, int, flags, const void *, value, void *, ovalue); @@ -31,3 +54,4 @@ int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, }
#endif +#endif
On Sat, Feb 24, 2024 at 7:01 AM Dmitry Chestnykh dm.chestnykh@gmail.com wrote:
PowerPC is big-endian architecture, so there are some significant differences in comparison with time64 support for little-endian architectures like ARM and xtensa.
JFYI xtensa supports both little and big endianness. Which suggests that it needs similar treatment as a BE PPC.
The main difference is that we strictly need to pass two 64bit values to system calls because Linux Kernel internally uses `struct __ketnel_timespec` and similar, which consists of two 64bit fields. For this reason many files have been changed to convert timespec-family structures (mixed of 64bit and 32bit values) to the 64bit-only structures for using as system calls args. Now time64 syscalls works properly both for LE (ARM, xtensa) and BE (PPC) memory layouts.
I'd suggest splitting this change into two parts: generic arch-independent changes followed by PPC-specific changes.
Signed-off-by: Dmitry Chestnykh dm.chestnykh@gmail.com
extra/Configs/Config.in | 2 +- libc/inet/socketcalls.c | 16 ++++++++- libc/misc/sysvipc/sem.c | 16 ++++++++- libc/signal/sigwait.c | 3 +- libc/sysdeps/linux/common/__rt_sigtimedwait.c | 23 ++++++++++-- libc/sysdeps/linux/common/__rt_sigwaitinfo.c | 2 +- libc/sysdeps/linux/common/alarm.c | 2 +- libc/sysdeps/linux/common/clock_getres.c | 20 ++++++++++- libc/sysdeps/linux/common/clock_gettime.c | 21 ++++++++++- libc/sysdeps/linux/common/clock_settime.c | 17 ++++++++- libc/sysdeps/linux/common/ppoll.c | 15 +++++++- libc/sysdeps/linux/common/pselect.c | 15 +++++++- libc/sysdeps/linux/common/select.c | 23 +++++++++--- libc/sysdeps/linux/common/time.c | 2 +- libc/sysdeps/linux/common/timerfd.c | 23 +++++++++++- libc/sysdeps/linux/common/utimensat.c | 23 +++++++++++- libc/sysdeps/linux/powerpc/bits/kernel_stat.h | 28 +++++++++++++-- libc/sysdeps/linux/powerpc/bits/sem.h | 16 +++++++++ libpthread/nptl/pthread_mutex_timedlock.c | 20 +++++++++-- .../sysdeps/pthread/pthread_cond_timedwait.c | 5 +-- .../pthread/pthread_rwlock_timedrdlock.c | 5 +-- .../pthread/pthread_rwlock_timedwrlock.c | 5 +-- .../sysdeps/unix/sysv/linux/lowlevellock.c | 10 +++--- .../sysdeps/unix/sysv/linux/lowlevellock.h | 35 +++++++++++++++++-- .../unix/sysv/linux/lowlevelrobustlock.c | 6 ++-- .../sysdeps/unix/sysv/linux/sem_timedwait.c | 6 ++-- .../sysdeps/unix/sysv/linux/timer_settime.c | 19 +++++++++- librt/clock_gettime.c | 20 +++++++++-- librt/clock_nanosleep.c | 23 ++++++++++-- librt/mq_timedreceive.c | 22 ++++++++++-- librt/mq_timedsend.c | 20 ++++++++++- librt/timer_settime.c | 28 +++++++++++++-- 32 files changed, 435 insertions(+), 56 deletions(-)
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index 9351dffc8..f11a63b79 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -1026,7 +1026,7 @@ config UCLIBC_FALLBACK_TO_ETC_LOCALTIME
config UCLIBC_USE_TIME64 bool "Use *time64 syscalls instead of 32bit ones (if possible)"
depends on TARGET_arm || TARGET_xtensa
depends on TARGET_arm || TARGET_powerpc || TARGET_xtensa # TODO: add support for other architectures default n
diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c index eb0983698..7ec439887 100644 --- a/libc/inet/socketcalls.c +++ b/libc/inet/socketcalls.c @@ -268,12 +268,26 @@ lt_libc_hidden(recvmsg) #endif
#ifdef L_recvmmsg
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#endif
This pattern and a similar pattern with struct its64_struct is repeated multiple times in this patch. It seems that this repetition can be easily avoided?
#ifdef __ASSUME_RECVMMSG_SYSCALL static ssize_t __NC(recvmmsg)(int sockfd, struct mmsghdr *msg, size_t vlen, int flags, struct timespec *tmo) { # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_recvmmsg_time64)
return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo);
struct ts64_struct __ts64 = {
.tv_sec = tmo ? tmo->tv_sec : 0,
.tv_nsec = tmo ? tmo->tv_nsec : 0
};
return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo ? &__ts64 : 0);
# elif defined(__NR_recvmmsg) return (ssize_t)INLINE_SYSCALL(recvmmsg, 5, sockfd, msg, vlen, flags, tmo); # elif __NR_socketcall diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c index cd541761c..d0bd0ba28 100644 --- a/libc/misc/sysvipc/sem.c +++ b/libc/misc/sysvipc/sem.c @@ -96,7 +96,21 @@ int semop (int semid, struct sembuf *sops, size_t nsops) #ifdef L_semtimedop
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_semtimedop_time64) -_syscall4_time64(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+int semtimedop(int semid, struct sembuf *sops, size_t nsops, const struct timespec *timeout) {
- struct ts64_struct __ts64 = {
.tv_sec = timeout ? timeout->tv_sec : 0,
.tv_nsec = timeout ? timeout->tv_nsec : 0
- };
- return INLINE_SYSCALL(semtimedop_time64, 4, semid, sops, nsops, timeout ? &__ts64 : 0);
+}
#elif defined(__NR_semtimedop) _syscall4(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout)
diff --git a/libc/signal/sigwait.c b/libc/signal/sigwait.c index 3557a039e..b237534cd 100644 --- a/libc/signal/sigwait.c +++ b/libc/signal/sigwait.c @@ -24,7 +24,8 @@ #include <signal.h> #include <cancel.h>
-#if defined __NR_rt_sigtimedwait && defined __UCLIBC_HAS_REALTIME__ +#if (defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64))) && \
- defined(__UCLIBC_HAS_REALTIME__)
#include <string.h>
diff --git a/libc/sysdeps/linux/common/__rt_sigtimedwait.c b/libc/sysdeps/linux/common/__rt_sigtimedwait.c index bd82ca6d5..cd25fe177 100644 --- a/libc/sysdeps/linux/common/__rt_sigtimedwait.c +++ b/libc/sysdeps/linux/common/__rt_sigtimedwait.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__NR_rt_sigtimedwait_time64) && defined(__UCLIBC_USE_TIME64__)) # include <signal.h> # include <cancel.h> # ifdef __UCLIBC_HAS_THREADS_NATIVE__ @@ -21,6 +21,15 @@ # include <string.h> # endif
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
__S64_TYPE tv_sec;
__S64_TYPE tv_nsec;
+};
+#endif
int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, const struct timespec *timeout) { @@ -53,8 +62,12 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, real size of the user-level sigset_t. */ /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)
struct ts64_struct __ts64 = {
.tv_sec = timeout ? timeout->tv_sec : 0,
.tv_nsec = timeout ? timeout->tv_nsec : 0
}; result = INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
timeout, __SYSCALL_SIGSET_T_SIZE);
timeout ? &__ts64 : 0, __SYSCALL_SIGSET_T_SIZE);
# else result = INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); @@ -71,8 +84,12 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, # else /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)
struct ts64_struct __ts64 = {
.tv_sec = timeout ? timeout->tv_sec : 0,
.tv_nsec = timeout ? timeout->tv_nsec : 0
}; return INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
timeout, __SYSCALL_SIGSET_T_SIZE);
timeout ? &__ts64 : 0, __SYSCALL_SIGSET_T_SIZE);
# else return INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); diff --git a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c index d2d176a64..7830b2e2c 100644 --- a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c +++ b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)) # define __need_NULL # include <stddef.h> # include <signal.h> diff --git a/libc/sysdeps/linux/common/alarm.c b/libc/sysdeps/linux/common/alarm.c index 4e6e2215b..861f6ad8e 100644 --- a/libc/sysdeps/linux/common/alarm.c +++ b/libc/sysdeps/linux/common/alarm.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <unistd.h>
-#ifdef __NR_alarm && !defined(__UCLIBC_USE_TIME64__) +#if defined(__NR_alarm) && !defined(__UCLIBC_USE_TIME64__) _syscall1(unsigned int, alarm, unsigned int, seconds) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/clock_getres.c b/libc/sysdeps/linux/common/clock_getres.c index d4b989958..c72b0a21c 100644 --- a/libc/sysdeps/linux/common/clock_getres.c +++ b/libc/sysdeps/linux/common/clock_getres.c @@ -10,9 +10,27 @@ #include <sys/syscall.h> #include <time.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
__S64_TYPE tv_sec;
__S64_TYPE tv_nsec;
+};
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64) -_syscall2_time64(int, clock_getres, clockid_t, clock_id, struct timespec*, res) +int clock_getres(clockid_t clock_id, struct timespec *res) +{
struct ts64_struct __ts64;
int __ret = INLINE_SYSCALL(clock_getres_time64, 2, clock_id, &__ts64);
if (__ret == 0 && res) {
res->tv_sec = __ts64.tv_sec;
res->tv_nsec = __ts64.tv_nsec;
};
return __ret;
+} #elif defined(__NR_clock_getres) _syscall2(int, clock_getres, clockid_t, clock_id, struct timespec*, res) #else diff --git a/libc/sysdeps/linux/common/clock_gettime.c b/libc/sysdeps/linux/common/clock_gettime.c index a595bd691..dbb767c94 100644 --- a/libc/sysdeps/linux/common/clock_gettime.c +++ b/libc/sysdeps/linux/common/clock_gettime.c @@ -11,8 +11,27 @@ #include <sys/syscall.h> #include <time.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
__S64_TYPE tv_sec;
__S64_TYPE tv_nsec;
+};
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) -_syscall2_64(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) +int clock_gettime(clockid_t clock_id, struct timespec *tp) +{
struct ts64_struct __ts64;
int __ret = INLINE_SYSCALL(clock_gettime64, 2, clock_id, &__ts64);
if (tp) {
tp->tv_sec = __ts64.tv_sec;
tp->tv_nsec = __ts64.tv_nsec;
}
return __ret;
+} #elif defined(__NR_clock_gettime) _syscall2(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/clock_settime.c b/libc/sysdeps/linux/common/clock_settime.c index 89550af5a..54bfa20e8 100644 --- a/libc/sysdeps/linux/common/clock_settime.c +++ b/libc/sysdeps/linux/common/clock_settime.c @@ -12,7 +12,22 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_settime64) -_syscall2_64(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp)
+struct ts64_struct {
__S64_TYPE tv_sec;
__S64_TYPE tv_nsec;
+};
+int clock_settime(clockid_t clock_id, const struct timespec *tp) +{
struct ts64_struct __ts64 = {
.tv_sec = tp->tv_sec,
.tv_nsec = tp->tv_nsec
};
return INLINE_SYSCALL(clock_settime64, 2, clock_id, &__ts64);
+}
#elif defined(__NR_clock_settime) _syscall2(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/ppoll.c b/libc/sysdeps/linux/common/ppoll.c index cb36149c5..16d836b6f 100644 --- a/libc/sysdeps/linux/common/ppoll.c +++ b/libc/sysdeps/linux/common/ppoll.c @@ -26,6 +26,15 @@ #include <sys/poll.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#endif
static int __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, const sigset_t *sigmask) @@ -38,7 +47,11 @@ __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, timeout = &tval; } #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_ppoll_time64)
return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE);
- struct ts64_struct __ts64 = {
.tv_sec = timeout ? timeout->tv_sec : 0,
.tv_nsec = timeout ? timeout->tv_nsec : 0
- };
return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout ? &__ts64 : 0, sigmask, __SYSCALL_SIGSET_T_SIZE);
#else return INLINE_SYSCALL(ppoll, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE); #endif diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c index 23bdab5cf..a189624ec 100644 --- a/libc/sysdeps/linux/common/pselect.c +++ b/libc/sysdeps/linux/common/pselect.c @@ -26,6 +26,15 @@ #include <signal.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#endif
static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask) @@ -57,7 +66,11 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, sigmask = (void *)&data; } #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64)
return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask);
struct ts64_struct __ts64 = {
.tv_sec = timeout ? timeout->tv_sec : 0,
.tv_nsec = timeout ? timeout->tv_nsec : 0
};
return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout ? &__ts64 : 0, sigmask);
#else return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask); #endif diff --git a/libc/sysdeps/linux/common/select.c b/libc/sysdeps/linux/common/select.c index 3132a109c..a55a61df1 100644 --- a/libc/sysdeps/linux/common/select.c +++ b/libc/sysdeps/linux/common/select.c @@ -15,17 +15,22 @@ # define __NR_select __NR__newselect #endif
-#if !defined __NR_select && defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) # include <stdint.h> # define USEC_PER_SEC 1000000L #endif
+#if defined(__UCLIBC_USE_TIME64__) +struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+}; +#endif
int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { -#ifdef __NR_select
return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, timeout);
-#elif defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) struct timespec _ts, *ts = 0; if (timeout) { uint32_t usec; @@ -47,8 +52,18 @@ int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
ts = &_ts; }
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64)
struct ts64_struct __ts64 = {
.tv_sec = ts ? ts->tv_sec : 0,
.tv_nsec = ts ? ts->tv_nsec : 0
};
return INLINE_SYSCALL(pselect6_time64, 6, n, readfds, writefds, exceptfds, timeout ? &__ts64 : 0, 0);
+#else return INLINE_SYSCALL(pselect6, 6, n, readfds, writefds, exceptfds, ts, 0); #endif +#elif defined(__NR_select)
return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, timeout);
+#endif } /* we should guard it, but we need it in other files, so let it fail
- if we miss any of the syscalls */
diff --git a/libc/sysdeps/linux/common/time.c b/libc/sysdeps/linux/common/time.c index 22403f174..d084ffaad 100644 --- a/libc/sysdeps/linux/common/time.c +++ b/libc/sysdeps/linux/common/time.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <time.h>
-#ifdef __NR_time +#if defined(__NR_time) && !defined(__UCLIBC_USE_TIME64__) _syscall_noerr1(time_t, time, time_t *, t) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/timerfd.c b/libc/sysdeps/linux/common/timerfd.c index 0f19b44ed..04db6ed00 100644 --- a/libc/sysdeps/linux/common/timerfd.c +++ b/libc/sysdeps/linux/common/timerfd.c @@ -16,12 +16,33 @@ _syscall2(int, timerfd_create, int, clockid, int, flags) #endif
+#if defined(__UCLIBC_USE_TIME64__)
+struct its64_struct {
- __S64_TYPE interval_tv_sec;
- __S64_TYPE interval_tv_nsec;
- __S64_TYPE value_tv_sec;
- __S64_TYPE value_tv_nsec;
+};
+#endif
/*
- timerfd_settime()
*/ #if defined(__NR_timerfd_settime) || defined(__NR_timerfd_settime64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timerfd_settime64) -_syscall4_64(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) +int timerfd_settime(int ufd, int flags, const struct itimerspec *utmr, struct itimerspec *otmr) +{
- struct its64_struct __its64 = {
.interval_tv_sec = utmr->it_interval.tv_sec,
.interval_tv_nsec = utmr->it_interval.tv_nsec,
.value_tv_sec = utmr->it_value.tv_sec,
.value_tv_nsec = utmr->it_value.tv_nsec,
- };
- return INLINE_SYSCALL(timerfd_settime64, 4, ufd, flags, &__its64, otmr);
+} #else _syscall4(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) #endif diff --git a/libc/sysdeps/linux/common/utimensat.c b/libc/sysdeps/linux/common/utimensat.c index 6a78ebb4f..0c87b5c45 100644 --- a/libc/sysdeps/linux/common/utimensat.c +++ b/libc/sysdeps/linux/common/utimensat.c @@ -9,9 +9,30 @@ #include <sys/syscall.h> #include <sys/stat.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct uts64_struct {
- __S64_TYPE tv_sec1;
- __S64_TYPE tv_nsec1;
- __S64_TYPE tv_sec2;
- __S64_TYPE tv_nsec2;
+};
+#endif
#if defined(__NR_utimensat) || defined(__NR_utimensat_time64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_utimensat_time64) -_syscall4_time64(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) +int utimensat(int fd, const char *path, const struct timespec times[2], int flags) +{
- struct uts64_struct __uts64 = {
.tv_sec1 = times ? times[0].tv_sec : 0,
.tv_nsec1 = times ? times[0].tv_nsec : 0,
.tv_sec2 = times ? times[1].tv_sec : 0,
.tv_nsec2 = times ? times[1].tv_nsec : 0
- };
- return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ? &__uts64 : 0, flags);
+} #else _syscall4(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) #endif diff --git a/libc/sysdeps/linux/powerpc/bits/kernel_stat.h b/libc/sysdeps/linux/powerpc/bits/kernel_stat.h index ce62b2ba2..0e76120ab 100644 --- a/libc/sysdeps/linux/powerpc/bits/kernel_stat.h +++ b/libc/sysdeps/linux/powerpc/bits/kernel_stat.h @@ -5,6 +5,16 @@
- struct kernel_stat should look like... It turns out each arch has a
- different opinion on the subject... */
+#if defined(__UCLIBC_USE_TIME64__) +#include <bits/types.h>
+struct ts32_struct {
__S32_TYPE tv_sec;
__S32_TYPE tv_nsec;
+};
+#endif
#if __WORDSIZE == 64 #define kernel_stat kernel_stat64 #else @@ -19,9 +29,15 @@ struct kernel_stat { __kernel_off_t st_size; unsigned long st_blksize; unsigned long st_blocks; +#if defined(__UCLIBC_USE_TIME64__)
struct ts32_struct __st_atim32;
struct ts32_struct __st_mtim32;
struct ts32_struct __st_ctim32;
+#else struct timespec st_atim; struct timespec st_mtim; struct timespec st_ctim; +#endif unsigned long __unused4; unsigned long __unused5; }; @@ -39,9 +55,15 @@ struct kernel_stat64 { long long st_size; /* Size of file, in bytes. */ long st_blksize; /* Optimal block size for I/O. */ long long st_blocks; /* Number 512-byte blocks allocated. */
struct timespec st_atim; /* Time of last access. */
struct timespec st_mtim; /* Time of last modification. */
struct timespec st_ctim; /* Time of last status change. */
+#if defined(__UCLIBC_USE_TIME64__)
struct ts32_struct __st_atim32;
struct ts32_struct __st_mtim32;
struct ts32_struct __st_ctim32;
+#else
struct timespec st_atim;
struct timespec st_mtim;
struct timespec st_ctim;
+#endif unsigned long int __uclibc_unused4; unsigned long int __uclibc_unused5; }; diff --git a/libc/sysdeps/linux/powerpc/bits/sem.h b/libc/sysdeps/linux/powerpc/bits/sem.h index a9d895374..8d338eac0 100644 --- a/libc/sysdeps/linux/powerpc/bits/sem.h +++ b/libc/sysdeps/linux/powerpc/bits/sem.h @@ -35,6 +35,7 @@ #define SETALL 17 /* set all semval's */
/* Data structure describing a set of semaphores. */ struct semid_ds { @@ -42,16 +43,31 @@ struct semid_ds #if __WORDSIZE == 32 unsigned int __uclibc_unused1; #endif +#if defined(__UCLIBC_USE_TIME64__)
- unsigned long int __sem_otime_internal_1; /* last semop() time */
- unsigned long int __sem_otime_internal_2;
+#else __time_t sem_otime; /* last semop() time */ +#endif #if __WORDSIZE == 32 unsigned int __uclibc_unused2; #endif +#if defined(__UCLIBC_USE_TIME64__)
- unsigned long int __sem_ctime_internal_1; /* last time changed by semctl() */
- unsigned long int __sem_ctime_internal_2;
+#else __time_t sem_ctime; /* last time changed by semctl() */ +#endif unsigned long int sem_nsems; /* number of semaphores in set */ +#if defined(__UCLIBC_USE_TIME64__)
- __time_t sem_otime;
- __time_t sem_ctime;
+#endif unsigned long __uclibc_unused3; unsigned long __uclibc_unused4; };
/* The user should define a union like the following to use it for arguments for `semctl'.
diff --git a/libpthread/nptl/pthread_mutex_timedlock.c b/libpthread/nptl/pthread_mutex_timedlock.c index 25f9ec3b2..d55495683 100644 --- a/libpthread/nptl/pthread_mutex_timedlock.c +++ b/libpthread/nptl/pthread_mutex_timedlock.c @@ -23,6 +23,15 @@ #include <lowlevellock.h> #include <not-cancel.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#endif
/* We need to build this function with optimization to avoid
- lll_timedlock erroring out with
- error: can't find a register in class ‘GENERAL_REGS’ while reloading ‘asm’
@@ -265,10 +274,14 @@ pthread_mutex_timedlock ( INTERNAL_SYSCALL_DECL (__err);
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
struct ts64_struct __ts64 = {
.tv_sec = abstime ? abstime->tv_sec : 0,
.tv_nsec = abstime ? abstime->tv_nsec : 0
}; int e = INTERNAL_SYSCALL (futex_time64, __err, 4, &mutex->__data.__lock, __lll_private_flag (FUTEX_LOCK_PI, private), 1,
abstime);
&__ts64);
#else int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock, __lll_private_flag (FUTEX_LOCK_PI, @@ -454,7 +467,7 @@ pthread_mutex_timedlock ( }
struct timeval tv;
struct timespec rt;
struct timespec rt, *rtp; /* Get the current time. */ (void) gettimeofday (&tv, NULL);
@@ -475,8 +488,9 @@ pthread_mutex_timedlock (
Starting from this hunk...
goto failpp; }
rtp = &rt; lll_futex_timed_wait (&mutex->__data.__lock,
ceilval | 2, &rt,
ceilval | 2, rtp, PTHREAD_MUTEX_PSHARED (mutex)); } }
diff --git a/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c b/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c index 49aab0293..1ea2a888a 100644 --- a/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c +++ b/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c @@ -95,7 +95,7 @@ __pthread_cond_timedwait (
while (1) {
struct timespec rt;
struct timespec rt, *rtp; {
#ifdef __NR_clock_gettime INTERNAL_SYSCALL_DECL (err); @@ -164,8 +164,9 @@ __pthread_cond_timedwait ( cbuffer.oldtype = __pthread_enable_asynccancel ();
/* Wait until woken by signal or broadcast. */
rtp = &rt; err = lll_futex_timed_wait (&cond->__data.__futex,
futex_val, &rt, pshared);
futex_val, rtp, pshared); /* Disable asynchronous cancellation. */ __pthread_disable_asynccancel (cbuffer.oldtype);
diff --git a/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c b/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c index 596f5df51..379e92b43 100644 --- a/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c +++ b/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c @@ -81,7 +81,7 @@ pthread_rwlock_timedrdlock ( (void) gettimeofday (&tv, NULL);
/* Convert the absolute timeout value to a relative timeout. */
struct timespec rt;
struct timespec rt, *rtp; rt.tv_sec = abstime->tv_sec - tv.tv_sec; rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000; if (rt.tv_nsec < 0)
@@ -112,8 +112,9 @@ pthread_rwlock_timedrdlock ( lll_unlock (rwlock->__data.__lock, rwlock->__data.__shared);
/* Wait for the writer to finish. */
rtp = &rt; err = lll_futex_timed_wait (&rwlock->__data.__readers_wakeup,
waitval, &rt, rwlock->__data.__shared);
waitval, rtp, rwlock->__data.__shared); /* Get the lock. */ lll_lock (rwlock->__data.__lock, rwlock->__data.__shared);
diff --git a/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c b/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c index 0b04b357a..3ce9f9b13 100644 --- a/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c +++ b/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c @@ -72,7 +72,7 @@ pthread_rwlock_timedwrlock ( (void) gettimeofday (&tv, NULL);
/* Convert the absolute timeout value to a relative timeout. */
struct timespec rt;
struct timespec rt, *rtp; rt.tv_sec = abstime->tv_sec - tv.tv_sec; rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000; if (rt.tv_nsec < 0)
@@ -102,8 +102,9 @@ pthread_rwlock_timedwrlock ( lll_unlock (rwlock->__data.__lock, rwlock->__data.__shared);
/* Wait for the writer or reader(s) to finish. */
rtp = &rt; err = lll_futex_timed_wait (&rwlock->__data.__writer_wakeup,
waitval, &rt, rwlock->__data.__shared);
waitval, rtp, rwlock->__data.__shared); /* Get the lock. */ lll_lock (rwlock->__data.__lock, rwlock->__data.__shared);
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c index 4294a20b0..5f7301976 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c @@ -63,7 +63,7 @@ __lll_timedlock_wait (int *futex, const struct timespec *abstime, int private) (void) gettimeofday (&tv, NULL);
/* Compute relative timeout. */
struct timespec rt;
struct timespec rt, *rtp; rt.tv_sec = abstime->tv_sec - tv.tv_sec; rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000; if (rt.tv_nsec < 0)
@@ -76,7 +76,8 @@ __lll_timedlock_wait (int *futex, const struct timespec *abstime, int private) return ETIMEDOUT;
/* Wait. */
lll_futex_timed_wait (futex, 2, &rt, private);
rtp = &rt;
lll_futex_timed_wait (futex, 2, rtp, private);
}
return 0;
@@ -95,7 +96,7 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime) while ((tid = *tidp) != 0) { struct timeval tv;
struct timespec rt;
struct timespec rt, *rtp; /* Get the current time. */ (void) __gettimeofday (&tv, NULL);
@@ -115,7 +116,8 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime)
/* Wait until thread terminates. The kernel so far does not use the private futex operations for this. */
if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) == -ETIMEDOUT)
rtp = &rt;
}if (lll_futex_timed_wait (tidp, tid, rtp, LLL_SHARED) == -ETIMEDOUT) return ETIMEDOUT;
...and up to here: why are all these changes adding an intermediate pointer needed?
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h index e72fe5234..4209a21d3 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h @@ -71,18 +71,49 @@ # endif #endif
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
#define lll_futex_wait(futexp, val, private) \
- lll_futex_timed_wait(futexp, val, NULL, private)
- ({ \
- INTERNAL_SYSCALL_DECL (__err); \
- long int __ret; \
- __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \
__lll_private_flag (FUTEX_WAIT, private), \
(val), NULL); \
- __ret; \
- })
+#else
+#define lll_futex_wait(futexp, val, private) \
- ({ \
- INTERNAL_SYSCALL_DECL (__err); \
- long int __ret; \
- __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \
__lll_private_flag (FUTEX_WAIT, private), \
(val), NULL); \
- __ret; \
- })
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+struct __ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#define ptr_timespec_to_ts64(ts) \
- (&(struct __ts64_struct) {.tv_sec = ts->tv_sec, .tv_nsec = ts->tv_nsec})
#define lll_futex_timed_wait(futexp, val, timespec, private) \ ({ \ INTERNAL_SYSCALL_DECL (__err); \ long int __ret; \ __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \ __lll_private_flag (FUTEX_WAIT, private), \
(val), (timespec)); \
__ret; \ })(val), (ptr_timespec_to_ts64(timespec))); \
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c index 7b4e84343..5781359fb 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c @@ -73,7 +73,7 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime, do { struct timeval tv;
struct timespec rt;
struct timespec rt, *rtp; /* Get the current time. */ (void) __gettimeofday (&tv, NULL);
@@ -99,8 +99,8 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime, if (oldval != newval && atomic_compare_and_exchange_bool_acq (futex, newval, oldval)) continue;
lll_futex_timed_wait (futex, newval, &rt, private);
rtp = &rt;
lll_futex_timed_wait (futex, newval, rtp, private);
try: ;
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c b/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c index 8c3ef47c5..05ba5bc13 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c @@ -51,7 +51,7 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime) while (1) { struct timeval tv;
struct timespec rt;
struct timespec rt, *rtp; int sec, nsec; /* Get the current time. */
@@ -79,10 +79,12 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime) rt.tv_sec = sec; rt.tv_nsec = nsec;
rtp = &rt;
/* Enable asynchronous cancellation. Required by the standard. */ int oldtype = __pthread_enable_asynccancel ();
err = lll_futex_timed_wait (&isem->value, 0, &rt,
err = lll_futex_timed_wait (&isem->value, 0, rtp, isem->private ^ FUTEX_PRIVATE_FLAG); /* Disable asynchronous cancellation. */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c index 80d242f21..d7c2aa804 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c @@ -38,6 +38,17 @@ static int compat_timer_settime (timer_t timerid, int flags, # define timer_settime timer_settime_alias # endif
+#if defined(__UCLIBC_USE_TIME64__)
+struct its64_struct {
- __S64_TYPE interval_tv_sec;
- __S64_TYPE interval_tv_nsec;
- __S64_TYPE value_tv_sec;
- __S64_TYPE value_tv_nsec;
+};
+#endif
int timer_settime ( @@ -55,8 +66,14 @@ timer_settime (
/* Delete the kernel timer object. */
# if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64)
struct its64_struct __its64 = {
.interval_tv_sec = value->it_interval.tv_sec,
.interval_tv_nsec = value->it_interval.tv_nsec,
.value_tv_sec = value->it_value.tv_sec,
.value_tv_nsec = value->it_value.tv_nsec,
}; int res = INLINE_SYSCALL (timer_settime64, 4, kt->ktimerid, flags,
value, ovalue);
value ? &__its64 : 0, ovalue);
# else int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags, value, ovalue); diff --git a/librt/clock_gettime.c b/librt/clock_gettime.c index b66b60231..eff40d68f 100644 --- a/librt/clock_gettime.c +++ b/librt/clock_gettime.c @@ -22,10 +22,26 @@ #include <sys/time.h> #include "kernel-posix-cpu-timers.h"
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) #define SYSCALL_GETTIME \
- retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, tp); \
- break
- { \
- struct ts64_struct __ts64; \
- retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, &__ts64); \
- if (tp) { \
- tp->tv_sec = __ts64.tv_sec; \
- tp->tv_nsec = __ts64.tv_nsec; \
- } \
- break; \
- }
#else #define SYSCALL_GETTIME \ retval = INLINE_SYSCALL (clock_gettime, 2, clock_id, tp); \ diff --git a/librt/clock_nanosleep.c b/librt/clock_nanosleep.c index eaae75720..786f7eede 100644 --- a/librt/clock_nanosleep.c +++ b/librt/clock_nanosleep.c @@ -21,6 +21,14 @@
#include "kernel-posix-cpu-timers.h"
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#endif
/* We can simply use the syscall. The CPU clocks are not supported with this function. */ @@ -36,18 +44,27 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, if (clock_id == CLOCK_PROCESS_CPUTIME_ID) clock_id = MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED);
- if (SINGLE_THREAD_P)
- if (SINGLE_THREAD_P) {
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64)
- r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem);
- struct ts64_struct __ts64 = {
.tv_sec = req ? req->tv_sec : 0,
.tv_nsec = req ? req->tv_nsec : 0
- };
- r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req ? &__ts64 : 0, rem);
#else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); #endif
- } else {
#ifdef __NEW_THREADS int oldstate = LIBC_CANCEL_ASYNC (); #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64)
r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem);
struct ts64_struct __ts64_2 = {
.tv_sec = req ? req->tv_sec : 0,
.tv_nsec = req ? req->tv_nsec : 0
};
r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req ? &__ts64_2 : 0, rem);
#else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); diff --git a/librt/mq_timedreceive.c b/librt/mq_timedreceive.c index db1ae1aa8..818f54faa 100644 --- a/librt/mq_timedreceive.c +++ b/librt/mq_timedreceive.c @@ -8,13 +8,29 @@ #include <unistd.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
__S64_TYPE tv_sec;
__S64_TYPE tv_nsec;
+};
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedreceive_time64) -#define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive_time64 +int _NC(mq_timedreceive)(mqd_t mqdes, char *restrict msg_ptr, size_t msg_len, unsigned int *restrict msq_prio, const struct timespec *restrict abs_timeout) +{
struct ts64_struct __ts64 = {
.tv_sec = abs_timeout ? abs_timeout->tv_sec : 0,
.tv_nsec = abs_timeout ? abs_timeout->tv_nsec : 0,
};
return INLINE_SYSCALL(mq_timedreceive_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, abs_timeout ? &__ts64 : 0);
+} #else #define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive -#endif
_syscall5(ssize_t, __NC(mq_timedreceive), mqd_t, mqdes, char *__restrict, msg_ptr, size_t, msg_len, unsigned int *__restrict, msq_prio, const struct timespec *__restrict, abs_timeout) +#endif
CANCELLABLE_SYSCALL(ssize_t, mq_timedreceive, (mqd_t mqdes, char *__restrict msg_ptr, size_t msq_len, unsigned int *__restrict msq_prio, const struct timespec *__restrict abs_timeout), (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) diff --git a/librt/mq_timedsend.c b/librt/mq_timedsend.c index 6afaf5157..e8deea9cb 100644 --- a/librt/mq_timedsend.c +++ b/librt/mq_timedsend.c @@ -8,13 +8,31 @@ #include <unistd.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
__S64_TYPE tv_sec;
__S64_TYPE tv_nsec;
+};
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedsend_time64) #define __NR___mq_timedsend_nocancel __NR_mq_timedsend_time64 +int _NC(mq_timedsend)(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msq_prio, const struct timespec *abs_timeout) +{
struct ts64_struct __ts64 = {
.tv_sec = abs_timeout ? abs_timeout->tv_sec : 0,
.tv_nsec = abs_timeout ? abs_timeout->tv_nsec : 0,
};
return INLINE_SYSCALL(mq_timedsend_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, abs_timeout ? &__ts64 : 0);
+} #else #define __NR___mq_timedsend_nocancel __NR_mq_timedsend +_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) #endif
-_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) CANCELLABLE_SYSCALL(int, mq_timedsend, (mqd_t mqdes, const char *msg_ptr, size_t msq_len, unsigned int msq_prio, const struct timespec *abs_timeout), (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) lt_libc_hidden(mq_timedsend) diff --git a/librt/timer_settime.c b/librt/timer_settime.c index 022880297..31202b07a 100644 --- a/librt/timer_settime.c +++ b/librt/timer_settime.c @@ -9,13 +9,36 @@
#include "kernel-posix-timers.h"
+#if defined(__UCLIBC_USE_TIME64__)
+struct its64_struct {
- __S64_TYPE interval_tv_sec;
- __S64_TYPE interval_tv_nsec;
- __S64_TYPE value_tv_sec;
- __S64_TYPE value_tv_nsec;
+};
+#endif
#if defined(__NR_timer_settime) || defined(__NR_timer_settime64)
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) -#define __NR___syscall_timer_settime __NR_timer_settime64 +int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue) +{
struct timer *kt = (struct timer *)timerid;
- struct its64_struct __its64 = {
.interval_tv_sec = value->it_interval.tv_sec,
.interval_tv_nsec = value->it_interval.tv_nsec,
.value_tv_sec = value->it_value.tv_sec,
.value_tv_nsec = value->it_value.tv_nsec,
- };
return INLINE_SYSCALL(timer_settime64, 4, kt->ktimerid, flags, value ? &__its64: 0, ovalue);
+} #else
#define __NR___syscall_timer_settime __NR_timer_settime -#endif
static __inline__ _syscall4(int, __syscall_timer_settime, kernel_timer_t, ktimerid, int, flags, const void *, value, void *, ovalue); @@ -31,3 +54,4 @@ int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, }
#endif
+#endif
2.43.2
devel mailing list -- devel@uclibc-ng.org To unsubscribe send an email to devel-leave@uclibc-ng.org
Thanks for the review, okay, i will rework the patch. Answering to your question about intermediate pointer, is it needed to use inside ptr_timespec_to_ts64 macro (&rt doesn't work because of producing &rt->tv_sec and &rt->tv_nsec), but i got that it can be avoided via transforming `ts->tv_sec` to `(ts)->tv_sec` and the similar for nsec.
сб, 24 февр. 2024 г. в 19:09, Max Filippov jcmvbkbc@gmail.com:
On Sat, Feb 24, 2024 at 7:01 AM Dmitry Chestnykh dm.chestnykh@gmail.com wrote:
PowerPC is big-endian architecture, so there are some significant differences in comparison with time64 support for little-endian architectures like ARM and xtensa.
JFYI xtensa supports both little and big endianness. Which suggests that it needs similar treatment as a BE PPC.
The main difference is that we strictly need to pass two 64bit values to system calls because Linux Kernel internally uses `struct __ketnel_timespec` and similar, which consists of two 64bit fields. For this reason many files have been changed to convert timespec-family structures (mixed of 64bit and 32bit values) to the 64bit-only structures for using as system calls args. Now time64 syscalls works properly both for LE (ARM, xtensa) and BE (PPC) memory layouts.
I'd suggest splitting this change into two parts: generic arch-independent changes followed by PPC-specific changes.
Signed-off-by: Dmitry Chestnykh dm.chestnykh@gmail.com
extra/Configs/Config.in | 2 +- libc/inet/socketcalls.c | 16 ++++++++- libc/misc/sysvipc/sem.c | 16 ++++++++- libc/signal/sigwait.c | 3 +- libc/sysdeps/linux/common/__rt_sigtimedwait.c | 23 ++++++++++-- libc/sysdeps/linux/common/__rt_sigwaitinfo.c | 2 +- libc/sysdeps/linux/common/alarm.c | 2 +- libc/sysdeps/linux/common/clock_getres.c | 20 ++++++++++- libc/sysdeps/linux/common/clock_gettime.c | 21 ++++++++++- libc/sysdeps/linux/common/clock_settime.c | 17 ++++++++- libc/sysdeps/linux/common/ppoll.c | 15 +++++++- libc/sysdeps/linux/common/pselect.c | 15 +++++++- libc/sysdeps/linux/common/select.c | 23 +++++++++--- libc/sysdeps/linux/common/time.c | 2 +- libc/sysdeps/linux/common/timerfd.c | 23 +++++++++++- libc/sysdeps/linux/common/utimensat.c | 23 +++++++++++- libc/sysdeps/linux/powerpc/bits/kernel_stat.h | 28 +++++++++++++-- libc/sysdeps/linux/powerpc/bits/sem.h | 16 +++++++++ libpthread/nptl/pthread_mutex_timedlock.c | 20 +++++++++-- .../sysdeps/pthread/pthread_cond_timedwait.c | 5 +-- .../pthread/pthread_rwlock_timedrdlock.c | 5 +-- .../pthread/pthread_rwlock_timedwrlock.c | 5 +-- .../sysdeps/unix/sysv/linux/lowlevellock.c | 10 +++--- .../sysdeps/unix/sysv/linux/lowlevellock.h | 35 +++++++++++++++++-- .../unix/sysv/linux/lowlevelrobustlock.c | 6 ++-- .../sysdeps/unix/sysv/linux/sem_timedwait.c | 6 ++-- .../sysdeps/unix/sysv/linux/timer_settime.c | 19 +++++++++- librt/clock_gettime.c | 20 +++++++++-- librt/clock_nanosleep.c | 23 ++++++++++-- librt/mq_timedreceive.c | 22 ++++++++++-- librt/mq_timedsend.c | 20 ++++++++++- librt/timer_settime.c | 28 +++++++++++++-- 32 files changed, 435 insertions(+), 56 deletions(-)
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index 9351dffc8..f11a63b79 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -1026,7 +1026,7 @@ config UCLIBC_FALLBACK_TO_ETC_LOCALTIME
config UCLIBC_USE_TIME64 bool "Use *time64 syscalls instead of 32bit ones (if possible)"
depends on TARGET_arm || TARGET_xtensa
depends on TARGET_arm || TARGET_powerpc || TARGET_xtensa # TODO: add support for other architectures default n
diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c index eb0983698..7ec439887 100644 --- a/libc/inet/socketcalls.c +++ b/libc/inet/socketcalls.c @@ -268,12 +268,26 @@ lt_libc_hidden(recvmsg) #endif
#ifdef L_recvmmsg
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#endif
This pattern and a similar pattern with struct its64_struct is repeated multiple times in this patch. It seems that this repetition can be easily avoided?
#ifdef __ASSUME_RECVMMSG_SYSCALL static ssize_t __NC(recvmmsg)(int sockfd, struct mmsghdr *msg, size_t
vlen,
int flags, struct timespec *tmo)
{ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_recvmmsg_time64)
return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg,
vlen, flags, tmo);
struct ts64_struct __ts64 = {
.tv_sec = tmo ? tmo->tv_sec : 0,
.tv_nsec = tmo ? tmo->tv_nsec : 0
};
return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg,
vlen, flags, tmo ? &__ts64 : 0);
# elif defined(__NR_recvmmsg) return (ssize_t)INLINE_SYSCALL(recvmmsg, 5, sockfd, msg, vlen,
flags, tmo);
# elif __NR_socketcall diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c index cd541761c..d0bd0ba28 100644 --- a/libc/misc/sysvipc/sem.c +++ b/libc/misc/sysvipc/sem.c @@ -96,7 +96,21 @@ int semop (int semid, struct sembuf *sops, size_t
nsops)
#ifdef L_semtimedop
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_semtimedop_time64) -_syscall4_time64(int, semtimedop, int, semid, struct sembuf *, sops,
size_t, nsops, const struct timespec *, timeout)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+int semtimedop(int semid, struct sembuf *sops, size_t nsops, const
struct timespec *timeout) {
- struct ts64_struct __ts64 = {
.tv_sec = timeout ? timeout->tv_sec : 0,
.tv_nsec = timeout ? timeout->tv_nsec : 0
- };
- return INLINE_SYSCALL(semtimedop_time64, 4, semid, sops, nsops,
timeout ? &__ts64 : 0);
+}
#elif defined(__NR_semtimedop) _syscall4(int, semtimedop, int, semid, struct sembuf *, sops, size_t,
nsops, const struct timespec *, timeout)
diff --git a/libc/signal/sigwait.c b/libc/signal/sigwait.c index 3557a039e..b237534cd 100644 --- a/libc/signal/sigwait.c +++ b/libc/signal/sigwait.c @@ -24,7 +24,8 @@ #include <signal.h> #include <cancel.h>
-#if defined __NR_rt_sigtimedwait && defined __UCLIBC_HAS_REALTIME__ +#if (defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__)
&& defined(__NR_rt_sigtimedwait_time64))) && \
- defined(__UCLIBC_HAS_REALTIME__)
#include <string.h>
diff --git a/libc/sysdeps/linux/common/__rt_sigtimedwait.c
b/libc/sysdeps/linux/common/__rt_sigtimedwait.c
index bd82ca6d5..cd25fe177 100644 --- a/libc/sysdeps/linux/common/__rt_sigtimedwait.c +++ b/libc/sysdeps/linux/common/__rt_sigtimedwait.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) ||
(defined(__NR_rt_sigtimedwait_time64) && defined(__UCLIBC_USE_TIME64__))
# include <signal.h> # include <cancel.h> # ifdef __UCLIBC_HAS_THREADS_NATIVE__ @@ -21,6 +21,15 @@ # include <string.h> # endif
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
__S64_TYPE tv_sec;
__S64_TYPE tv_nsec;
+};
+#endif
int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, const struct timespec *timeout) { @@ -53,8 +62,12 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t
*info,
real size of the user-level sigset_t. */ /* on uClibc we use the kernel sigset_t size */
# if defined(__UCLIBC_USE_TIME64__) &&
defined(__NR_rt_sigtimedwait_time64)
struct ts64_struct __ts64 = {
.tv_sec = timeout ? timeout->tv_sec : 0,
.tv_nsec = timeout ? timeout->tv_nsec : 0
}; result = INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
timeout, __SYSCALL_SIGSET_T_SIZE);
timeout ? &__ts64 : 0,
__SYSCALL_SIGSET_T_SIZE);
# else result = INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); @@ -71,8 +84,12 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t
*info,
# else /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) &&
defined(__NR_rt_sigtimedwait_time64)
struct ts64_struct __ts64 = {
.tv_sec = timeout ? timeout->tv_sec : 0,
.tv_nsec = timeout ? timeout->tv_nsec : 0
}; return INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
timeout, __SYSCALL_SIGSET_T_SIZE);
timeout ? &__ts64 : 0,
__SYSCALL_SIGSET_T_SIZE);
# else return INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); diff --git a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c
b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c
index d2d176a64..7830b2e2c 100644 --- a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c +++ b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) &&
defined(__NR_rt_sigtimedwait_time64))
# define __need_NULL # include <stddef.h> # include <signal.h> diff --git a/libc/sysdeps/linux/common/alarm.c
b/libc/sysdeps/linux/common/alarm.c
index 4e6e2215b..861f6ad8e 100644 --- a/libc/sysdeps/linux/common/alarm.c +++ b/libc/sysdeps/linux/common/alarm.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <unistd.h>
-#ifdef __NR_alarm && !defined(__UCLIBC_USE_TIME64__) +#if defined(__NR_alarm) && !defined(__UCLIBC_USE_TIME64__) _syscall1(unsigned int, alarm, unsigned int, seconds) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/clock_getres.c
b/libc/sysdeps/linux/common/clock_getres.c
index d4b989958..c72b0a21c 100644 --- a/libc/sysdeps/linux/common/clock_getres.c +++ b/libc/sysdeps/linux/common/clock_getres.c @@ -10,9 +10,27 @@ #include <sys/syscall.h> #include <time.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
__S64_TYPE tv_sec;
__S64_TYPE tv_nsec;
+};
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64) -_syscall2_time64(int, clock_getres, clockid_t, clock_id, struct
timespec*, res)
+int clock_getres(clockid_t clock_id, struct timespec *res) +{
struct ts64_struct __ts64;
int __ret = INLINE_SYSCALL(clock_getres_time64, 2, clock_id,
&__ts64);
if (__ret == 0 && res) {
res->tv_sec = __ts64.tv_sec;
res->tv_nsec = __ts64.tv_nsec;
};
return __ret;
+} #elif defined(__NR_clock_getres) _syscall2(int, clock_getres, clockid_t, clock_id, struct timespec*, res) #else diff --git a/libc/sysdeps/linux/common/clock_gettime.c
b/libc/sysdeps/linux/common/clock_gettime.c
index a595bd691..dbb767c94 100644 --- a/libc/sysdeps/linux/common/clock_gettime.c +++ b/libc/sysdeps/linux/common/clock_gettime.c @@ -11,8 +11,27 @@ #include <sys/syscall.h> #include <time.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
__S64_TYPE tv_sec;
__S64_TYPE tv_nsec;
+};
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) -_syscall2_64(int, clock_gettime, clockid_t, clock_id, struct timespec*,
tp)
+int clock_gettime(clockid_t clock_id, struct timespec *tp) +{
struct ts64_struct __ts64;
int __ret = INLINE_SYSCALL(clock_gettime64, 2, clock_id,
&__ts64);
if (tp) {
tp->tv_sec = __ts64.tv_sec;
tp->tv_nsec = __ts64.tv_nsec;
}
return __ret;
+} #elif defined(__NR_clock_gettime) _syscall2(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/clock_settime.c
b/libc/sysdeps/linux/common/clock_settime.c
index 89550af5a..54bfa20e8 100644 --- a/libc/sysdeps/linux/common/clock_settime.c +++ b/libc/sysdeps/linux/common/clock_settime.c @@ -12,7 +12,22 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_settime64) -_syscall2_64(int, clock_settime, clockid_t, clock_id, const struct
timespec*, tp)
+struct ts64_struct {
__S64_TYPE tv_sec;
__S64_TYPE tv_nsec;
+};
+int clock_settime(clockid_t clock_id, const struct timespec *tp) +{
struct ts64_struct __ts64 = {
.tv_sec = tp->tv_sec,
.tv_nsec = tp->tv_nsec
};
return INLINE_SYSCALL(clock_settime64, 2, clock_id, &__ts64);
+}
#elif defined(__NR_clock_settime) _syscall2(int, clock_settime, clockid_t, clock_id, const struct
timespec*, tp)
#else diff --git a/libc/sysdeps/linux/common/ppoll.c
b/libc/sysdeps/linux/common/ppoll.c
index cb36149c5..16d836b6f 100644 --- a/libc/sysdeps/linux/common/ppoll.c +++ b/libc/sysdeps/linux/common/ppoll.c @@ -26,6 +26,15 @@ #include <sys/poll.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#endif
static int __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec
*timeout,
const sigset_t *sigmask)
@@ -38,7 +47,11 @@ __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const
struct timespec *timeout,
timeout = &tval; }
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_ppoll_time64)
return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout,
sigmask, __SYSCALL_SIGSET_T_SIZE);
- struct ts64_struct __ts64 = {
.tv_sec = timeout ? timeout->tv_sec : 0,
.tv_nsec = timeout ? timeout->tv_nsec : 0
- };
return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout ?
&__ts64 : 0, sigmask, __SYSCALL_SIGSET_T_SIZE);
#else return INLINE_SYSCALL(ppoll, 5, fds, nfds, timeout, sigmask,
__SYSCALL_SIGSET_T_SIZE);
#endif diff --git a/libc/sysdeps/linux/common/pselect.c
b/libc/sysdeps/linux/common/pselect.c
index 23bdab5cf..a189624ec 100644 --- a/libc/sysdeps/linux/common/pselect.c +++ b/libc/sysdeps/linux/common/pselect.c @@ -26,6 +26,15 @@ #include <signal.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#endif
static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec
*timeout,
const sigset_t *sigmask)
@@ -57,7 +66,11 @@ static int __NC(pselect)(int nfds, fd_set *readfds,
fd_set *writefds,
sigmask = (void *)&data; }
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64)
return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds,
writefds, exceptfds, timeout, sigmask);
struct ts64_struct __ts64 = {
.tv_sec = timeout ? timeout->tv_sec : 0,
.tv_nsec = timeout ? timeout->tv_nsec : 0
};
return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds,
writefds, exceptfds, timeout ? &__ts64 : 0, sigmask);
#else return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds,
exceptfds, timeout, sigmask);
#endif diff --git a/libc/sysdeps/linux/common/select.c
b/libc/sysdeps/linux/common/select.c
index 3132a109c..a55a61df1 100644 --- a/libc/sysdeps/linux/common/select.c +++ b/libc/sysdeps/linux/common/select.c @@ -15,17 +15,22 @@ # define __NR_select __NR__newselect #endif
-#if !defined __NR_select && defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) # include <stdint.h> # define USEC_PER_SEC 1000000L #endif
+#if defined(__UCLIBC_USE_TIME64__) +struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+}; +#endif
int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set
*exceptfds,
struct timeval *timeout)
{ -#ifdef __NR_select
return INLINE_SYSCALL(select, 5, n, readfds, writefds,
exceptfds, timeout);
-#elif defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) struct timespec _ts, *ts = 0; if (timeout) { uint32_t usec; @@ -47,8 +52,18 @@ int __NC(select)(int n, fd_set *readfds, fd_set
*writefds, fd_set *exceptfds,
ts = &_ts; }
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64)
struct ts64_struct __ts64 = {
.tv_sec = ts ? ts->tv_sec : 0,
.tv_nsec = ts ? ts->tv_nsec : 0
};
return INLINE_SYSCALL(pselect6_time64, 6, n, readfds, writefds,
exceptfds, timeout ? &__ts64 : 0, 0);
+#else return INLINE_SYSCALL(pselect6, 6, n, readfds, writefds,
exceptfds, ts, 0);
#endif +#elif defined(__NR_select)
return INLINE_SYSCALL(select, 5, n, readfds, writefds,
exceptfds, timeout);
+#endif } /* we should guard it, but we need it in other files, so let it fail
- if we miss any of the syscalls */
diff --git a/libc/sysdeps/linux/common/time.c
b/libc/sysdeps/linux/common/time.c
index 22403f174..d084ffaad 100644 --- a/libc/sysdeps/linux/common/time.c +++ b/libc/sysdeps/linux/common/time.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <time.h>
-#ifdef __NR_time +#if defined(__NR_time) && !defined(__UCLIBC_USE_TIME64__) _syscall_noerr1(time_t, time, time_t *, t) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/timerfd.c
b/libc/sysdeps/linux/common/timerfd.c
index 0f19b44ed..04db6ed00 100644 --- a/libc/sysdeps/linux/common/timerfd.c +++ b/libc/sysdeps/linux/common/timerfd.c @@ -16,12 +16,33 @@ _syscall2(int, timerfd_create, int, clockid, int, flags) #endif
+#if defined(__UCLIBC_USE_TIME64__)
+struct its64_struct {
- __S64_TYPE interval_tv_sec;
- __S64_TYPE interval_tv_nsec;
- __S64_TYPE value_tv_sec;
- __S64_TYPE value_tv_nsec;
+};
+#endif
/*
- timerfd_settime()
*/ #if defined(__NR_timerfd_settime) || defined(__NR_timerfd_settime64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timerfd_settime64) -_syscall4_64(int, timerfd_settime, int, ufd, int, flags, const struct
itimerspec *, utmr, struct itimerspec *, otmr)
+int timerfd_settime(int ufd, int flags, const struct itimerspec *utmr,
struct itimerspec *otmr)
+{
- struct its64_struct __its64 = {
.interval_tv_sec = utmr->it_interval.tv_sec,
.interval_tv_nsec = utmr->it_interval.tv_nsec,
.value_tv_sec = utmr->it_value.tv_sec,
.value_tv_nsec = utmr->it_value.tv_nsec,
- };
- return INLINE_SYSCALL(timerfd_settime64, 4, ufd, flags, &__its64,
otmr);
+} #else _syscall4(int, timerfd_settime, int, ufd, int, flags, const struct
itimerspec *, utmr, struct itimerspec *, otmr)
#endif diff --git a/libc/sysdeps/linux/common/utimensat.c
b/libc/sysdeps/linux/common/utimensat.c
index 6a78ebb4f..0c87b5c45 100644 --- a/libc/sysdeps/linux/common/utimensat.c +++ b/libc/sysdeps/linux/common/utimensat.c @@ -9,9 +9,30 @@ #include <sys/syscall.h> #include <sys/stat.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct uts64_struct {
- __S64_TYPE tv_sec1;
- __S64_TYPE tv_nsec1;
- __S64_TYPE tv_sec2;
- __S64_TYPE tv_nsec2;
+};
+#endif
#if defined(__NR_utimensat) || defined(__NR_utimensat_time64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_utimensat_time64) -_syscall4_time64(int, utimensat, int, fd, const char *, path, const
struct timespec *, times, int, flags)
+int utimensat(int fd, const char *path, const struct timespec times[2],
int flags)
+{
- struct uts64_struct __uts64 = {
.tv_sec1 = times ? times[0].tv_sec : 0,
.tv_nsec1 = times ? times[0].tv_nsec : 0,
.tv_sec2 = times ? times[1].tv_sec : 0,
.tv_nsec2 = times ? times[1].tv_nsec : 0
- };
- return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ?
&__uts64 : 0, flags);
+} #else _syscall4(int, utimensat, int, fd, const char *, path, const struct
timespec *, times, int, flags)
#endif diff --git a/libc/sysdeps/linux/powerpc/bits/kernel_stat.h
b/libc/sysdeps/linux/powerpc/bits/kernel_stat.h
index ce62b2ba2..0e76120ab 100644 --- a/libc/sysdeps/linux/powerpc/bits/kernel_stat.h +++ b/libc/sysdeps/linux/powerpc/bits/kernel_stat.h @@ -5,6 +5,16 @@
- struct kernel_stat should look like... It turns out each arch has a
- different opinion on the subject... */
+#if defined(__UCLIBC_USE_TIME64__) +#include <bits/types.h>
+struct ts32_struct {
__S32_TYPE tv_sec;
__S32_TYPE tv_nsec;
+};
+#endif
#if __WORDSIZE == 64 #define kernel_stat kernel_stat64 #else @@ -19,9 +29,15 @@ struct kernel_stat { __kernel_off_t st_size; unsigned long st_blksize; unsigned long st_blocks; +#if defined(__UCLIBC_USE_TIME64__)
struct ts32_struct __st_atim32;
struct ts32_struct __st_mtim32;
struct ts32_struct __st_ctim32;
+#else struct timespec st_atim; struct timespec st_mtim; struct timespec st_ctim; +#endif unsigned long __unused4; unsigned long __unused5; }; @@ -39,9 +55,15 @@ struct kernel_stat64 { long long st_size; /* Size of file, in bytes. */ long st_blksize; /* Optimal block size for I/O.
*/
long long st_blocks; /* Number 512-byte blocks
allocated. */
struct timespec st_atim; /* Time of last access. */
struct timespec st_mtim; /* Time of last modification. */
struct timespec st_ctim; /* Time of last status change.
*/
+#if defined(__UCLIBC_USE_TIME64__)
struct ts32_struct __st_atim32;
struct ts32_struct __st_mtim32;
struct ts32_struct __st_ctim32;
+#else
struct timespec st_atim;
struct timespec st_mtim;
struct timespec st_ctim;
+#endif unsigned long int __uclibc_unused4; unsigned long int __uclibc_unused5; }; diff --git a/libc/sysdeps/linux/powerpc/bits/sem.h
b/libc/sysdeps/linux/powerpc/bits/sem.h
index a9d895374..8d338eac0 100644 --- a/libc/sysdeps/linux/powerpc/bits/sem.h +++ b/libc/sysdeps/linux/powerpc/bits/sem.h @@ -35,6 +35,7 @@ #define SETALL 17 /* set all semval's */
/* Data structure describing a set of semaphores. */ struct semid_ds { @@ -42,16 +43,31 @@ struct semid_ds #if __WORDSIZE == 32 unsigned int __uclibc_unused1; #endif +#if defined(__UCLIBC_USE_TIME64__)
- unsigned long int __sem_otime_internal_1; /* last semop() time */
- unsigned long int __sem_otime_internal_2;
+#else __time_t sem_otime; /* last semop() time */ +#endif #if __WORDSIZE == 32 unsigned int __uclibc_unused2; #endif +#if defined(__UCLIBC_USE_TIME64__)
- unsigned long int __sem_ctime_internal_1; /* last time changed by
semctl() */
- unsigned long int __sem_ctime_internal_2;
+#else __time_t sem_ctime; /* last time changed by semctl()
*/
+#endif unsigned long int sem_nsems; /* number of semaphores in set */ +#if defined(__UCLIBC_USE_TIME64__)
- __time_t sem_otime;
- __time_t sem_ctime;
+#endif unsigned long __uclibc_unused3; unsigned long __uclibc_unused4; };
/* The user should define a union like the following to use it for
arguments
for `semctl'.
diff --git a/libpthread/nptl/pthread_mutex_timedlock.c
b/libpthread/nptl/pthread_mutex_timedlock.c
index 25f9ec3b2..d55495683 100644 --- a/libpthread/nptl/pthread_mutex_timedlock.c +++ b/libpthread/nptl/pthread_mutex_timedlock.c @@ -23,6 +23,15 @@ #include <lowlevellock.h> #include <not-cancel.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#endif
/* We need to build this function with optimization to avoid
- lll_timedlock erroring out with
- error: can't find a register in class ‘GENERAL_REGS’ while reloading
‘asm’
@@ -265,10 +274,14 @@ pthread_mutex_timedlock ( INTERNAL_SYSCALL_DECL (__err);
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
struct ts64_struct __ts64 = {
.tv_sec = abstime ? abstime->tv_sec : 0,
.tv_nsec = abstime ? abstime->tv_nsec : 0
}; int e = INTERNAL_SYSCALL (futex_time64, __err, 4,
&mutex->__data.__lock,
__lll_private_flag (FUTEX_LOCK_PI, private), 1,
abstime);
&__ts64);
#else int e = INTERNAL_SYSCALL (futex, __err, 4,
&mutex->__data.__lock,
__lll_private_flag (FUTEX_LOCK_PI,
@@ -454,7 +467,7 @@ pthread_mutex_timedlock ( }
struct timeval tv;
struct timespec rt;
struct timespec rt, *rtp; /* Get the current time. */ (void) gettimeofday (&tv, NULL);
@@ -475,8 +488,9 @@ pthread_mutex_timedlock (
Starting from this hunk...
goto failpp; }
rtp = &rt; lll_futex_timed_wait (&mutex->__data.__lock,
ceilval | 2, &rt,
ceilval | 2, rtp, PTHREAD_MUTEX_PSHARED (mutex)); } }
diff --git a/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c
b/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c
index 49aab0293..1ea2a888a 100644 --- a/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c +++ b/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c @@ -95,7 +95,7 @@ __pthread_cond_timedwait (
while (1) {
struct timespec rt;
struct timespec rt, *rtp; {
#ifdef __NR_clock_gettime INTERNAL_SYSCALL_DECL (err); @@ -164,8 +164,9 @@ __pthread_cond_timedwait ( cbuffer.oldtype = __pthread_enable_asynccancel ();
/* Wait until woken by signal or broadcast. */
rtp = &rt; err = lll_futex_timed_wait (&cond->__data.__futex,
futex_val, &rt, pshared);
futex_val, rtp, pshared); /* Disable asynchronous cancellation. */ __pthread_disable_asynccancel (cbuffer.oldtype);
diff --git
a/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c b/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c
index 596f5df51..379e92b43 100644 --- a/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c +++ b/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c @@ -81,7 +81,7 @@ pthread_rwlock_timedrdlock ( (void) gettimeofday (&tv, NULL);
/* Convert the absolute timeout value to a relative timeout. */
struct timespec rt;
struct timespec rt, *rtp; rt.tv_sec = abstime->tv_sec - tv.tv_sec; rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000; if (rt.tv_nsec < 0)
@@ -112,8 +112,9 @@ pthread_rwlock_timedrdlock ( lll_unlock (rwlock->__data.__lock, rwlock->__data.__shared);
/* Wait for the writer to finish. */
rtp = &rt; err = lll_futex_timed_wait (&rwlock->__data.__readers_wakeup,
waitval, &rt, rwlock->__data.__shared);
waitval, rtp, rwlock->__data.__shared); /* Get the lock. */ lll_lock (rwlock->__data.__lock, rwlock->__data.__shared);
diff --git
a/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c b/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c
index 0b04b357a..3ce9f9b13 100644 --- a/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c +++ b/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c @@ -72,7 +72,7 @@ pthread_rwlock_timedwrlock ( (void) gettimeofday (&tv, NULL);
/* Convert the absolute timeout value to a relative timeout. */
struct timespec rt;
struct timespec rt, *rtp; rt.tv_sec = abstime->tv_sec - tv.tv_sec; rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000; if (rt.tv_nsec < 0)
@@ -102,8 +102,9 @@ pthread_rwlock_timedwrlock ( lll_unlock (rwlock->__data.__lock, rwlock->__data.__shared);
/* Wait for the writer or reader(s) to finish. */
rtp = &rt; err = lll_futex_timed_wait (&rwlock->__data.__writer_wakeup,
waitval, &rt, rwlock->__data.__shared);
waitval, rtp, rwlock->__data.__shared); /* Get the lock. */ lll_lock (rwlock->__data.__lock, rwlock->__data.__shared);
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c
b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c
index 4294a20b0..5f7301976 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c @@ -63,7 +63,7 @@ __lll_timedlock_wait (int *futex, const struct
timespec *abstime, int private)
(void) gettimeofday (&tv, NULL); /* Compute relative timeout. */
struct timespec rt;
struct timespec rt, *rtp; rt.tv_sec = abstime->tv_sec - tv.tv_sec; rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000; if (rt.tv_nsec < 0)
@@ -76,7 +76,8 @@ __lll_timedlock_wait (int *futex, const struct
timespec *abstime, int private)
return ETIMEDOUT; /* Wait. */
lll_futex_timed_wait (futex, 2, &rt, private);
rtp = &rt;
lll_futex_timed_wait (futex, 2, rtp, private);
}
return 0;
@@ -95,7 +96,7 @@ __lll_timedwait_tid (int *tidp, const struct timespec
*abstime)
while ((tid = *tidp) != 0) { struct timeval tv;
struct timespec rt;
struct timespec rt, *rtp; /* Get the current time. */ (void) __gettimeofday (&tv, NULL);
@@ -115,7 +116,8 @@ __lll_timedwait_tid (int *tidp, const struct
timespec *abstime)
/* Wait until thread terminates. The kernel so far does not use the private futex operations for this. */
if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) ==
-ETIMEDOUT)
rtp = &rt;
if (lll_futex_timed_wait (tidp, tid, rtp, LLL_SHARED) ==
-ETIMEDOUT)
return ETIMEDOUT; }
...and up to here: why are all these changes adding an intermediate pointer needed?
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h
b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h
index e72fe5234..4209a21d3 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h @@ -71,18 +71,49 @@ # endif #endif
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
#define lll_futex_wait(futexp, val, private) \
- lll_futex_timed_wait(futexp, val, NULL, private)
- ({
\
- INTERNAL_SYSCALL_DECL (__err);
\
- long int __ret;
\
- __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp),
\
__lll_private_flag (FUTEX_WAIT, private),
\
(val), NULL); \
- __ret;
\
- })
+#else
+#define lll_futex_wait(futexp, val, private) \
- ({
\
- INTERNAL_SYSCALL_DECL (__err);
\
- long int __ret;
\
- __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp),
\
__lll_private_flag (FUTEX_WAIT, private),
\
(val), NULL); \
- __ret;
\
- })
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+struct __ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#define ptr_timespec_to_ts64(ts) \
- (&(struct __ts64_struct) {.tv_sec = ts->tv_sec, .tv_nsec =
ts->tv_nsec})
#define lll_futex_timed_wait(futexp, val, timespec, private) \ ({
\
INTERNAL_SYSCALL_DECL (__err);
\
long int __ret;
\
__ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp),
\
__lll_private_flag (FUTEX_WAIT, private),
\
(val), (timespec));
\
(val), (ptr_timespec_to_ts64(timespec)));
\
__ret;
\
})
diff --git
a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
index 7b4e84343..5781359fb 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c @@ -73,7 +73,7 @@ __lll_robust_timedlock_wait (int *futex, const struct
timespec *abstime,
do { struct timeval tv;
struct timespec rt;
struct timespec rt, *rtp; /* Get the current time. */ (void) __gettimeofday (&tv, NULL);
@@ -99,8 +99,8 @@ __lll_robust_timedlock_wait (int *futex, const struct
timespec *abstime,
if (oldval != newval && atomic_compare_and_exchange_bool_acq (futex, newval,
oldval))
continue;
lll_futex_timed_wait (futex, newval, &rt, private);
rtp = &rt;
lll_futex_timed_wait (futex, newval, rtp, private);
try: ;
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
b/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
index 8c3ef47c5..05ba5bc13 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c @@ -51,7 +51,7 @@ sem_timedwait (sem_t *sem, const struct timespec
*abstime)
while (1) { struct timeval tv;
struct timespec rt;
struct timespec rt, *rtp; int sec, nsec; /* Get the current time. */
@@ -79,10 +79,12 @@ sem_timedwait (sem_t *sem, const struct timespec
*abstime)
rt.tv_sec = sec; rt.tv_nsec = nsec;
rtp = &rt;
/* Enable asynchronous cancellation. Required by the standard.
*/
int oldtype = __pthread_enable_asynccancel ();
err = lll_futex_timed_wait (&isem->value, 0, &rt,
err = lll_futex_timed_wait (&isem->value, 0, rtp, isem->private ^ FUTEX_PRIVATE_FLAG); /* Disable asynchronous cancellation. */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c
b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c
index 80d242f21..d7c2aa804 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c @@ -38,6 +38,17 @@ static int compat_timer_settime (timer_t timerid, int
flags,
# define timer_settime timer_settime_alias # endif
+#if defined(__UCLIBC_USE_TIME64__)
+struct its64_struct {
- __S64_TYPE interval_tv_sec;
- __S64_TYPE interval_tv_nsec;
- __S64_TYPE value_tv_sec;
- __S64_TYPE value_tv_nsec;
+};
+#endif
int timer_settime ( @@ -55,8 +66,14 @@ timer_settime (
/* Delete the kernel timer object. */
# if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64)
struct its64_struct __its64 = {
.interval_tv_sec = value->it_interval.tv_sec,
.interval_tv_nsec = value->it_interval.tv_nsec,
.value_tv_sec = value->it_value.tv_sec,
.value_tv_nsec = value->it_value.tv_nsec,
}; int res = INLINE_SYSCALL (timer_settime64, 4, kt->ktimerid, flags,
value, ovalue);
value ? &__its64 : 0, ovalue);
# else int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags, value, ovalue); diff --git a/librt/clock_gettime.c b/librt/clock_gettime.c index b66b60231..eff40d68f 100644 --- a/librt/clock_gettime.c +++ b/librt/clock_gettime.c @@ -22,10 +22,26 @@ #include <sys/time.h> #include "kernel-posix-cpu-timers.h"
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) #define SYSCALL_GETTIME \
- retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, tp); \
- break
- { \
- struct ts64_struct __ts64; \
- retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, &__ts64); \
- if (tp) { \
- tp->tv_sec = __ts64.tv_sec; \
- tp->tv_nsec = __ts64.tv_nsec; \
- } \
- break; \
- }
#else #define SYSCALL_GETTIME \ retval = INLINE_SYSCALL (clock_gettime, 2, clock_id, tp); \ diff --git a/librt/clock_nanosleep.c b/librt/clock_nanosleep.c index eaae75720..786f7eede 100644 --- a/librt/clock_nanosleep.c +++ b/librt/clock_nanosleep.c @@ -21,6 +21,14 @@
#include "kernel-posix-cpu-timers.h"
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#endif
/* We can simply use the syscall. The CPU clocks are not supported with this function. */ @@ -36,18 +44,27 @@ clock_nanosleep (clockid_t clock_id, int flags,
const struct timespec *req,
if (clock_id == CLOCK_PROCESS_CPUTIME_ID) clock_id = MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED);
- if (SINGLE_THREAD_P)
- if (SINGLE_THREAD_P) {
#if defined(__UCLIBC_USE_TIME64__) &&
defined(__NR_clock_nanosleep_time64)
- r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id,
flags, req, rem);
- struct ts64_struct __ts64 = {
.tv_sec = req ? req->tv_sec : 0,
.tv_nsec = req ? req->tv_nsec : 0
- };
- r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id,
flags, req ? &__ts64 : 0, rem);
#else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags,
req, rem);
#endif
- } else {
#ifdef __NEW_THREADS int oldstate = LIBC_CANCEL_ASYNC (); #if defined(__UCLIBC_USE_TIME64__) &&
defined(__NR_clock_nanosleep_time64)
r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id,
flags, req, rem);
struct ts64_struct __ts64_2 = {
.tv_sec = req ? req->tv_sec : 0,
.tv_nsec = req ? req->tv_nsec : 0
};
r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id,
flags, req ? &__ts64_2 : 0, rem);
#else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags,
req,
rem);
diff --git a/librt/mq_timedreceive.c b/librt/mq_timedreceive.c index db1ae1aa8..818f54faa 100644 --- a/librt/mq_timedreceive.c +++ b/librt/mq_timedreceive.c @@ -8,13 +8,29 @@ #include <unistd.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
__S64_TYPE tv_sec;
__S64_TYPE tv_nsec;
+};
+#endif
#if defined(__UCLIBC_USE_TIME64__) &&
defined(__NR_mq_timedreceive_time64)
-#define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive_time64 +int _NC(mq_timedreceive)(mqd_t mqdes, char *restrict msg_ptr, size_t
msg_len, unsigned int *restrict msq_prio, const struct timespec *restrict abs_timeout)
+{
struct ts64_struct __ts64 = {
.tv_sec = abs_timeout ? abs_timeout->tv_sec : 0,
.tv_nsec = abs_timeout ? abs_timeout->tv_nsec : 0,
};
return INLINE_SYSCALL(mq_timedreceive_time64, 5, mqdes, msg_ptr,
msg_len, msq_prio, abs_timeout ? &__ts64 : 0);
+} #else #define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive -#endif
_syscall5(ssize_t, __NC(mq_timedreceive), mqd_t, mqdes, char
*__restrict, msg_ptr, size_t, msg_len, unsigned int *__restrict, msq_prio, const struct timespec *__restrict, abs_timeout)
+#endif
CANCELLABLE_SYSCALL(ssize_t, mq_timedreceive, (mqd_t mqdes, char
*__restrict msg_ptr, size_t msq_len, unsigned int *__restrict msq_prio, const struct timespec *__restrict abs_timeout),
(mqdes, msg_ptr, msq_len, msq_prio, abs_timeout))
diff --git a/librt/mq_timedsend.c b/librt/mq_timedsend.c index 6afaf5157..e8deea9cb 100644 --- a/librt/mq_timedsend.c +++ b/librt/mq_timedsend.c @@ -8,13 +8,31 @@ #include <unistd.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
__S64_TYPE tv_sec;
__S64_TYPE tv_nsec;
+};
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedsend_time64) #define __NR___mq_timedsend_nocancel __NR_mq_timedsend_time64 +int _NC(mq_timedsend)(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
unsigned int msq_prio, const struct timespec *abs_timeout)
+{
struct ts64_struct __ts64 = {
.tv_sec = abs_timeout ? abs_timeout->tv_sec : 0,
.tv_nsec = abs_timeout ? abs_timeout->tv_nsec : 0,
};
return INLINE_SYSCALL(mq_timedsend_time64, 5, mqdes, msg_ptr,
msg_len, msq_prio, abs_timeout ? &__ts64 : 0);
+} #else #define __NR___mq_timedsend_nocancel __NR_mq_timedsend +_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr,
size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout)
#endif
-_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr,
size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout)
CANCELLABLE_SYSCALL(int, mq_timedsend, (mqd_t mqdes, const char
*msg_ptr, size_t msq_len, unsigned int msq_prio, const struct timespec *abs_timeout),
(mqdes, msg_ptr, msq_len, msq_prio, abs_timeout))
lt_libc_hidden(mq_timedsend) diff --git a/librt/timer_settime.c b/librt/timer_settime.c index 022880297..31202b07a 100644 --- a/librt/timer_settime.c +++ b/librt/timer_settime.c @@ -9,13 +9,36 @@
#include "kernel-posix-timers.h"
+#if defined(__UCLIBC_USE_TIME64__)
+struct its64_struct {
- __S64_TYPE interval_tv_sec;
- __S64_TYPE interval_tv_nsec;
- __S64_TYPE value_tv_sec;
- __S64_TYPE value_tv_nsec;
+};
+#endif
#if defined(__NR_timer_settime) || defined(__NR_timer_settime64)
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) -#define __NR___syscall_timer_settime __NR_timer_settime64 +int timer_settime(timer_t timerid, int flags, const struct itimerspec
*value, struct itimerspec *ovalue)
+{
struct timer *kt = (struct timer *)timerid;
- struct its64_struct __its64 = {
.interval_tv_sec = value->it_interval.tv_sec,
.interval_tv_nsec = value->it_interval.tv_nsec,
.value_tv_sec = value->it_value.tv_sec,
.value_tv_nsec = value->it_value.tv_nsec,
- };
return INLINE_SYSCALL(timer_settime64, 4, kt->ktimerid, flags,
value ? &__its64: 0, ovalue);
+} #else
#define __NR___syscall_timer_settime __NR_timer_settime -#endif
static __inline__ _syscall4(int, __syscall_timer_settime,
kernel_timer_t, ktimerid,
int, flags, const void *, value, void *, ovalue);
@@ -31,3 +54,4 @@ int timer_settime(timer_t timerid, int flags, const
struct itimerspec *value,
}
#endif
+#endif
2.43.2
devel mailing list -- devel@uclibc-ng.org To unsubscribe send an email to devel-leave@uclibc-ng.org
-- Thanks. -- Max
For BE architectures there is one significant difference in comparison with time64 support for little-endian architectures like ARMv7. The difference is that we strictly need to pass two 64bit values to system calls because Linux Kernel internally uses `struct __kernel_timespec` and similar, which consists of two 64bit fields. For this reason many files have been changed to convert pointers to timespec-family structures (mixed of 64bit and 32bit values) to the pointer of the similar but 64bit-only structures for using as system calls args. This is general prerequisite for any BE architecture.
Signed-off-by: Dmitry Chestnykh dm.chestnykh@gmail.com --- include/time.h | 27 +++++++++++++++++++ libc/inet/socketcalls.c | 2 +- libc/misc/sysvipc/sem.c | 6 ++++- libc/signal/sigwait.c | 3 ++- libc/sysdeps/linux/common/__rt_sigtimedwait.c | 6 ++--- libc/sysdeps/linux/common/__rt_sigwaitinfo.c | 2 +- libc/sysdeps/linux/common/alarm.c | 2 +- libc/sysdeps/linux/common/clock_getres.c | 13 +++++++-- libc/sysdeps/linux/common/clock_gettime.c | 12 ++++++++- libc/sysdeps/linux/common/clock_settime.c | 5 +++- libc/sysdeps/linux/common/ppoll.c | 2 +- libc/sysdeps/linux/common/pselect.c | 2 +- libc/sysdeps/linux/common/select.c | 12 ++++++--- libc/sysdeps/linux/common/time.c | 2 +- libc/sysdeps/linux/common/timerfd.c | 5 +++- libc/sysdeps/linux/common/utimensat.c | 16 ++++++++++- libpthread/nptl/pthread_mutex_timedlock.c | 2 +- .../sysdeps/unix/sysv/linux/lowlevellock.c | 5 ++-- .../sysdeps/unix/sysv/linux/lowlevellock.h | 27 +++++++++++++++++-- .../unix/sysv/linux/lowlevelrobustlock.c | 1 - .../sysdeps/unix/sysv/linux/timer_settime.c | 2 +- librt/clock_gettime.c | 11 ++++++-- librt/clock_nanosleep.c | 5 ++-- librt/mq_timedreceive.c | 8 +++--- librt/mq_timedsend.c | 6 ++++- librt/timer_settime.c | 9 +++++-- 26 files changed, 154 insertions(+), 39 deletions(-)
diff --git a/include/time.h b/include/time.h index 1a1408990..880a80d85 100644 --- a/include/time.h +++ b/include/time.h @@ -122,6 +122,16 @@ struct timespec long int tv_nsec; /* Nanoseconds. */ };
+#if defined(__UCLIBC_USE_TIME64__) + +struct __ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; + +#define TO_TS64_P(__ts) (&(struct __ts64_struct) {.tv_sec = (__ts)->tv_sec, .tv_nsec = (__ts)->tv_nsec}) +#endif + #endif /* timespec not defined and <time.h> or need timespec. */ #undef __need_timespec
@@ -165,6 +175,23 @@ struct itimerspec struct timespec it_value; };
+#if defined(__UCLIBC_USE_TIME64__) + +struct __its64_struct { + __S64_TYPE interval_tv_sec; + __S64_TYPE interval_tv_nsec; + __S64_TYPE value_tv_sec; + __S64_TYPE value_tv_nsec; +}; + +#define TO_ITS64_P(__its) (&(struct __its64_struct) {.interval_tv_sec = (__its)->it_interval.tv_sec, \ + .interval_tv_nsec = (__its)->it_interval.tv_nsec, \ + .value_tv_sec = (__its)->it_value.tv_sec, \ + .value_tv_nsec = (__its)->it_value.tv_nsec}) + +#endif + + /* We can use a simple forward declaration. */ struct sigevent;
diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c index eb0983698..ea623878a 100644 --- a/libc/inet/socketcalls.c +++ b/libc/inet/socketcalls.c @@ -273,7 +273,7 @@ static ssize_t __NC(recvmmsg)(int sockfd, struct mmsghdr *msg, size_t vlen, int flags, struct timespec *tmo) { # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_recvmmsg_time64) - return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo); + return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo ? TO_TS64_P(tmo) : 0); # elif defined(__NR_recvmmsg) return (ssize_t)INLINE_SYSCALL(recvmmsg, 5, sockfd, msg, vlen, flags, tmo); # elif __NR_socketcall diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c index cd541761c..48d345984 100644 --- a/libc/misc/sysvipc/sem.c +++ b/libc/misc/sysvipc/sem.c @@ -96,7 +96,11 @@ int semop (int semid, struct sembuf *sops, size_t nsops) #ifdef L_semtimedop
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_semtimedop_time64) -_syscall4_time64(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout) +int semtimedop(int semid, struct sembuf *sops, size_t nsops, const struct timespec *timeout) +{ + return INLINE_SYSCALL(semtimedop_time64, 4, semid, sops, nsops, timeout ? TO_TS64_P(timeout) : 0); +} + #elif defined(__NR_semtimedop) _syscall4(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout)
diff --git a/libc/signal/sigwait.c b/libc/signal/sigwait.c index 3557a039e..b237534cd 100644 --- a/libc/signal/sigwait.c +++ b/libc/signal/sigwait.c @@ -24,7 +24,8 @@ #include <signal.h> #include <cancel.h>
-#if defined __NR_rt_sigtimedwait && defined __UCLIBC_HAS_REALTIME__ +#if (defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64))) && \ + defined(__UCLIBC_HAS_REALTIME__)
#include <string.h>
diff --git a/libc/sysdeps/linux/common/__rt_sigtimedwait.c b/libc/sysdeps/linux/common/__rt_sigtimedwait.c index bd82ca6d5..44e1ce928 100644 --- a/libc/sysdeps/linux/common/__rt_sigtimedwait.c +++ b/libc/sysdeps/linux/common/__rt_sigtimedwait.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__NR_rt_sigtimedwait_time64) && defined(__UCLIBC_USE_TIME64__)) # include <signal.h> # include <cancel.h> # ifdef __UCLIBC_HAS_THREADS_NATIVE__ @@ -54,7 +54,7 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64) result = INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info, - timeout, __SYSCALL_SIGSET_T_SIZE); + timeout ? TO_TS64_P(timeout) : 0, __SYSCALL_SIGSET_T_SIZE); # else result = INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); @@ -72,7 +72,7 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64) return INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info, - timeout, __SYSCALL_SIGSET_T_SIZE); + timeout ? TO_TS64_P(timeout) : 0, __SYSCALL_SIGSET_T_SIZE); # else return INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); diff --git a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c index d2d176a64..7830b2e2c 100644 --- a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c +++ b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)) # define __need_NULL # include <stddef.h> # include <signal.h> diff --git a/libc/sysdeps/linux/common/alarm.c b/libc/sysdeps/linux/common/alarm.c index 4e6e2215b..861f6ad8e 100644 --- a/libc/sysdeps/linux/common/alarm.c +++ b/libc/sysdeps/linux/common/alarm.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <unistd.h>
-#ifdef __NR_alarm && !defined(__UCLIBC_USE_TIME64__) +#if defined(__NR_alarm) && !defined(__UCLIBC_USE_TIME64__) _syscall1(unsigned int, alarm, unsigned int, seconds) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/clock_getres.c b/libc/sysdeps/linux/common/clock_getres.c index d4b989958..c1818f9ce 100644 --- a/libc/sysdeps/linux/common/clock_getres.c +++ b/libc/sysdeps/linux/common/clock_getres.c @@ -10,9 +10,18 @@ #include <sys/syscall.h> #include <time.h>
- #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64) -_syscall2_time64(int, clock_getres, clockid_t, clock_id, struct timespec*, res) +int clock_getres(clockid_t clock_id, struct timespec *res) +{ + struct __ts64_struct __ts64; + int __ret = INLINE_SYSCALL(clock_getres_time64, 2, clock_id, &__ts64); + if (__ret == 0 && res) { + res->tv_sec = __ts64.tv_sec; + res->tv_nsec = __ts64.tv_nsec; + }; + + return __ret; +} #elif defined(__NR_clock_getres) _syscall2(int, clock_getres, clockid_t, clock_id, struct timespec*, res) #else diff --git a/libc/sysdeps/linux/common/clock_gettime.c b/libc/sysdeps/linux/common/clock_gettime.c index a595bd691..00212a9ef 100644 --- a/libc/sysdeps/linux/common/clock_gettime.c +++ b/libc/sysdeps/linux/common/clock_gettime.c @@ -12,7 +12,17 @@ #include <time.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) -_syscall2_64(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) +int clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + struct __ts64_struct __ts64; + int __ret = INLINE_SYSCALL(clock_gettime64, 2, clock_id, &__ts64); + if (tp) { + tp->tv_sec = __ts64.tv_sec; + tp->tv_nsec = __ts64.tv_nsec; + } + + return __ret; +} #elif defined(__NR_clock_gettime) _syscall2(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/clock_settime.c b/libc/sysdeps/linux/common/clock_settime.c index 89550af5a..666ae4075 100644 --- a/libc/sysdeps/linux/common/clock_settime.c +++ b/libc/sysdeps/linux/common/clock_settime.c @@ -12,7 +12,10 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_settime64) -_syscall2_64(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) +int clock_settime(clockid_t clock_id, const struct timespec *tp) +{ + return INLINE_SYSCALL(clock_settime64, 2, clock_id, tp ? TO_TS64_P(tp) : 0); +} #elif defined(__NR_clock_settime) _syscall2(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/ppoll.c b/libc/sysdeps/linux/common/ppoll.c index cb36149c5..3b98a2760 100644 --- a/libc/sysdeps/linux/common/ppoll.c +++ b/libc/sysdeps/linux/common/ppoll.c @@ -38,7 +38,7 @@ __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, timeout = &tval; } #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_ppoll_time64) - return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE); + return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout ? TO_TS64_P(timeout) : 0, sigmask, __SYSCALL_SIGSET_T_SIZE); #else return INLINE_SYSCALL(ppoll, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE); #endif diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c index 23bdab5cf..3ceb51012 100644 --- a/libc/sysdeps/linux/common/pselect.c +++ b/libc/sysdeps/linux/common/pselect.c @@ -57,7 +57,7 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, sigmask = (void *)&data; } #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64) - return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask); + return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout ? TO_TS64_P(timeout) : 0, sigmask); #else return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask); #endif diff --git a/libc/sysdeps/linux/common/select.c b/libc/sysdeps/linux/common/select.c index 3132a109c..05d2b55b2 100644 --- a/libc/sysdeps/linux/common/select.c +++ b/libc/sysdeps/linux/common/select.c @@ -15,7 +15,7 @@ # define __NR_select __NR__newselect #endif
-#if !defined __NR_select && defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) # include <stdint.h> # define USEC_PER_SEC 1000000L #endif @@ -23,9 +23,7 @@ int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { -#ifdef __NR_select - return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, timeout); -#elif defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) struct timespec _ts, *ts = 0; if (timeout) { uint32_t usec; @@ -47,8 +45,14 @@ int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
ts = &_ts; } +#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64) + return INLINE_SYSCALL(pselect6_time64, 6, n, readfds, writefds, exceptfds, ts ? TO_TS64_P(ts) : 0, 0); +#else return INLINE_SYSCALL(pselect6, 6, n, readfds, writefds, exceptfds, ts, 0); #endif +#elif defined(__NR_select) + return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, ts); +#endif } /* we should guard it, but we need it in other files, so let it fail * if we miss any of the syscalls */ diff --git a/libc/sysdeps/linux/common/time.c b/libc/sysdeps/linux/common/time.c index 22403f174..d084ffaad 100644 --- a/libc/sysdeps/linux/common/time.c +++ b/libc/sysdeps/linux/common/time.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <time.h>
-#ifdef __NR_time +#if defined(__NR_time) && !defined(__UCLIBC_USE_TIME64__) _syscall_noerr1(time_t, time, time_t *, t) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/timerfd.c b/libc/sysdeps/linux/common/timerfd.c index 0f19b44ed..07bfb09b7 100644 --- a/libc/sysdeps/linux/common/timerfd.c +++ b/libc/sysdeps/linux/common/timerfd.c @@ -21,7 +21,10 @@ _syscall2(int, timerfd_create, int, clockid, int, flags) */ #if defined(__NR_timerfd_settime) || defined(__NR_timerfd_settime64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timerfd_settime64) -_syscall4_64(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) +int timerfd_settime(int ufd, int flags, const struct itimerspec *utmr, struct itimerspec *otmr) +{ + return INLINE_SYSCALL(timerfd_settime64, 4, ufd, flags, utmr ? TO_ITS64_P(utmr) : 0, otmr); +} #else _syscall4(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) #endif diff --git a/libc/sysdeps/linux/common/utimensat.c b/libc/sysdeps/linux/common/utimensat.c index 6a78ebb4f..339a35559 100644 --- a/libc/sysdeps/linux/common/utimensat.c +++ b/libc/sysdeps/linux/common/utimensat.c @@ -11,7 +11,21 @@
#if defined(__NR_utimensat) || defined(__NR_utimensat_time64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_utimensat_time64) -_syscall4_time64(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) +int utimensat(int fd, const char *path, const struct timespec times[2], int flags) +{ + struct __ts64_struct __times64[2] = { + { + .tv_sec = times ? times[0].tv_sec : 0, + .tv_nsec = times ? times[0].tv_nsec : 0 + }, + { + .tv_sec = times ? times[1].tv_sec : 0, + .tv_nsec = times ? times[1].tv_nsec : 0 + } + }; + + return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ? &__times64 : 0, flags); +} #else _syscall4(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) #endif diff --git a/libpthread/nptl/pthread_mutex_timedlock.c b/libpthread/nptl/pthread_mutex_timedlock.c index 25f9ec3b2..7bb9a0aaf 100644 --- a/libpthread/nptl/pthread_mutex_timedlock.c +++ b/libpthread/nptl/pthread_mutex_timedlock.c @@ -268,7 +268,7 @@ pthread_mutex_timedlock ( int e = INTERNAL_SYSCALL (futex_time64, __err, 4, &mutex->__data.__lock, __lll_private_flag (FUTEX_LOCK_PI, private), 1, - abstime); + abstime ? TO_TS64_P(abstime) : 0); #else int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock, __lll_private_flag (FUTEX_LOCK_PI, diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c index 4294a20b0..e168b3925 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c @@ -95,7 +95,7 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime) while ((tid = *tidp) != 0) { struct timeval tv; - struct timespec rt; + struct timespec rt, *rtp;
/* Get the current time. */ (void) __gettimeofday (&tv, NULL); @@ -115,7 +115,8 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime)
/* Wait until thread terminates. The kernel so far does not use the private futex operations for this. */ - if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) == -ETIMEDOUT) + rtp = &rt; + if (lll_futex_timed_wait (tidp, tid, rtp, LLL_SHARED) == -ETIMEDOUT) return ETIMEDOUT; }
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h index e72fe5234..909b0aad3 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h @@ -71,8 +71,31 @@ # endif #endif
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64) + #define lll_futex_wait(futexp, val, private) \ - lll_futex_timed_wait(futexp, val, NULL, private) + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAIT, private), \ + (val), NULL); \ + __ret; \ + }) + +#else + +#define lll_futex_wait(futexp, val, private) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAIT, private), \ + (val), NULL); \ + __ret; \ + }) + +#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
@@ -82,7 +105,7 @@ long int __ret; \ __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \ __lll_private_flag (FUTEX_WAIT, private), \ - (val), (timespec)); \ + (val), (TO_TS64_P(timespec))); \ __ret; \ })
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c index 7b4e84343..6403f7ea0 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c @@ -99,7 +99,6 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime, if (oldval != newval && atomic_compare_and_exchange_bool_acq (futex, newval, oldval)) continue; - lll_futex_timed_wait (futex, newval, &rt, private);
try: diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c index 80d242f21..4fa600cb6 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c @@ -56,7 +56,7 @@ timer_settime ( /* Delete the kernel timer object. */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) int res = INLINE_SYSCALL (timer_settime64, 4, kt->ktimerid, flags, - value, ovalue); + value ? TO_ITS64_P(value) : 0, ovalue); # else int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags, value, ovalue); diff --git a/librt/clock_gettime.c b/librt/clock_gettime.c index b66b60231..c514e1a54 100644 --- a/librt/clock_gettime.c +++ b/librt/clock_gettime.c @@ -24,8 +24,15 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) #define SYSCALL_GETTIME \ - retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, tp); \ - break + { \ + struct __ts64_struct __ts64; \ + retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, &__ts64); \ + if (tp) { \ + tp->tv_sec = __ts64.tv_sec; \ + tp->tv_nsec = __ts64.tv_nsec; \ + } \ + break; \ + } #else #define SYSCALL_GETTIME \ retval = INLINE_SYSCALL (clock_gettime, 2, clock_id, tp); \ diff --git a/librt/clock_nanosleep.c b/librt/clock_nanosleep.c index eaae75720..cb7b2afa3 100644 --- a/librt/clock_nanosleep.c +++ b/librt/clock_nanosleep.c @@ -21,7 +21,6 @@
#include "kernel-posix-cpu-timers.h"
- /* We can simply use the syscall. The CPU clocks are not supported with this function. */ int @@ -38,7 +37,7 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
if (SINGLE_THREAD_P) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64) - r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem); + r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req ? TO_TS64_P(req) : 0, rem); #else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); #endif @@ -47,7 +46,7 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, #ifdef __NEW_THREADS int oldstate = LIBC_CANCEL_ASYNC (); #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64) - r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem); + r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req ? TO_TS64_P(req): 0, rem); #else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); diff --git a/librt/mq_timedreceive.c b/librt/mq_timedreceive.c index db1ae1aa8..2570b6f9e 100644 --- a/librt/mq_timedreceive.c +++ b/librt/mq_timedreceive.c @@ -9,12 +9,14 @@ #include <cancel.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedreceive_time64) -#define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive_time64 +int _NC(mq_timedreceive)(mqd_t mqdes, char *restrict msg_ptr, size_t msg_len, unsigned int *restrict msq_prio, const struct timespec *restrict abs_timeout) +{ + return INLINE_SYSCALL(mq_timedreceive_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, abs_timeout ? TO_TS64_P(abs_timeout) : 0); +} #else #define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive -#endif - _syscall5(ssize_t, __NC(mq_timedreceive), mqd_t, mqdes, char *__restrict, msg_ptr, size_t, msg_len, unsigned int *__restrict, msq_prio, const struct timespec *__restrict, abs_timeout) +#endif
CANCELLABLE_SYSCALL(ssize_t, mq_timedreceive, (mqd_t mqdes, char *__restrict msg_ptr, size_t msq_len, unsigned int *__restrict msq_prio, const struct timespec *__restrict abs_timeout), (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) diff --git a/librt/mq_timedsend.c b/librt/mq_timedsend.c index 6afaf5157..bcbc0685f 100644 --- a/librt/mq_timedsend.c +++ b/librt/mq_timedsend.c @@ -10,11 +10,15 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedsend_time64) #define __NR___mq_timedsend_nocancel __NR_mq_timedsend_time64 +int _NC(mq_timedsend)(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msq_prio, const struct timespec *abs_timeout) +{ + return INLINE_SYSCALL(mq_timedsend_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, abs_timeout ? TO_TS64_P(abs_timeout) : 0); +} #else #define __NR___mq_timedsend_nocancel __NR_mq_timedsend +_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) #endif
-_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) CANCELLABLE_SYSCALL(int, mq_timedsend, (mqd_t mqdes, const char *msg_ptr, size_t msq_len, unsigned int msq_prio, const struct timespec *abs_timeout), (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) lt_libc_hidden(mq_timedsend) diff --git a/librt/timer_settime.c b/librt/timer_settime.c index 022880297..6bf5f8307 100644 --- a/librt/timer_settime.c +++ b/librt/timer_settime.c @@ -12,10 +12,14 @@ #if defined(__NR_timer_settime) || defined(__NR_timer_settime64)
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) -#define __NR___syscall_timer_settime __NR_timer_settime64 +int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue) +{ + struct timer *kt = (struct timer *)timerid; + + return INLINE_SYSCALL(timer_settime64, 4, kt->ktimerid, flags, value ? TO_ITS64_P(value) : 0, ovalue); +} #else #define __NR___syscall_timer_settime __NR_timer_settime -#endif
static __inline__ _syscall4(int, __syscall_timer_settime, kernel_timer_t, ktimerid, int, flags, const void *, value, void *, ovalue); @@ -31,3 +35,4 @@ int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, }
#endif +#endif
Signed-off-by: Dmitry Chestnykh dm.chestnykh@gmail.com --- extra/Configs/Config.in | 2 +- libc/sysdeps/linux/powerpc/bits/kernel_stat.h | 28 +++++++++++++++++-- libc/sysdeps/linux/powerpc/bits/sem.h | 16 +++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index 9351dffc8..f11a63b79 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -1026,7 +1026,7 @@ config UCLIBC_FALLBACK_TO_ETC_LOCALTIME
config UCLIBC_USE_TIME64 bool "Use *time64 syscalls instead of 32bit ones (if possible)" - depends on TARGET_arm || TARGET_xtensa + depends on TARGET_arm || TARGET_powerpc || TARGET_xtensa # TODO: add support for other architectures default n
diff --git a/libc/sysdeps/linux/powerpc/bits/kernel_stat.h b/libc/sysdeps/linux/powerpc/bits/kernel_stat.h index ce62b2ba2..0e76120ab 100644 --- a/libc/sysdeps/linux/powerpc/bits/kernel_stat.h +++ b/libc/sysdeps/linux/powerpc/bits/kernel_stat.h @@ -5,6 +5,16 @@ * struct kernel_stat should look like... It turns out each arch has a * different opinion on the subject... */
+#if defined(__UCLIBC_USE_TIME64__) +#include <bits/types.h> + +struct ts32_struct { + __S32_TYPE tv_sec; + __S32_TYPE tv_nsec; +}; + +#endif + #if __WORDSIZE == 64 #define kernel_stat kernel_stat64 #else @@ -19,9 +29,15 @@ struct kernel_stat { __kernel_off_t st_size; unsigned long st_blksize; unsigned long st_blocks; +#if defined(__UCLIBC_USE_TIME64__) + struct ts32_struct __st_atim32; + struct ts32_struct __st_mtim32; + struct ts32_struct __st_ctim32; +#else struct timespec st_atim; struct timespec st_mtim; struct timespec st_ctim; +#endif unsigned long __unused4; unsigned long __unused5; }; @@ -39,9 +55,15 @@ struct kernel_stat64 { long long st_size; /* Size of file, in bytes. */ long st_blksize; /* Optimal block size for I/O. */ long long st_blocks; /* Number 512-byte blocks allocated. */ - struct timespec st_atim; /* Time of last access. */ - struct timespec st_mtim; /* Time of last modification. */ - struct timespec st_ctim; /* Time of last status change. */ +#if defined(__UCLIBC_USE_TIME64__) + struct ts32_struct __st_atim32; + struct ts32_struct __st_mtim32; + struct ts32_struct __st_ctim32; +#else + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; +#endif unsigned long int __uclibc_unused4; unsigned long int __uclibc_unused5; }; diff --git a/libc/sysdeps/linux/powerpc/bits/sem.h b/libc/sysdeps/linux/powerpc/bits/sem.h index a9d895374..8d338eac0 100644 --- a/libc/sysdeps/linux/powerpc/bits/sem.h +++ b/libc/sysdeps/linux/powerpc/bits/sem.h @@ -35,6 +35,7 @@ #define SETALL 17 /* set all semval's */
+ /* Data structure describing a set of semaphores. */ struct semid_ds { @@ -42,16 +43,31 @@ struct semid_ds #if __WORDSIZE == 32 unsigned int __uclibc_unused1; #endif +#if defined(__UCLIBC_USE_TIME64__) + unsigned long int __sem_otime_internal_1; /* last semop() time */ + unsigned long int __sem_otime_internal_2; +#else __time_t sem_otime; /* last semop() time */ +#endif #if __WORDSIZE == 32 unsigned int __uclibc_unused2; #endif +#if defined(__UCLIBC_USE_TIME64__) + unsigned long int __sem_ctime_internal_1; /* last time changed by semctl() */ + unsigned long int __sem_ctime_internal_2; +#else __time_t sem_ctime; /* last time changed by semctl() */ +#endif unsigned long int sem_nsems; /* number of semaphores in set */ +#if defined(__UCLIBC_USE_TIME64__) + __time_t sem_otime; + __time_t sem_ctime; +#endif unsigned long __uclibc_unused3; unsigned long __uclibc_unused4; };
+ /* The user should define a union like the following to use it for arguments for `semctl'.
Hi Dmitry,
Thanks! applied and pushed, best regards Waldemar
Dmitry Chestnykh wrote,
Signed-off-by: Dmitry Chestnykh dm.chestnykh@gmail.com
extra/Configs/Config.in | 2 +- libc/sysdeps/linux/powerpc/bits/kernel_stat.h | 28 +++++++++++++++++-- libc/sysdeps/linux/powerpc/bits/sem.h | 16 +++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index 9351dffc8..f11a63b79 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -1026,7 +1026,7 @@ config UCLIBC_FALLBACK_TO_ETC_LOCALTIME
config UCLIBC_USE_TIME64 bool "Use *time64 syscalls instead of 32bit ones (if possible)"
- depends on TARGET_arm || TARGET_xtensa
- depends on TARGET_arm || TARGET_powerpc || TARGET_xtensa # TODO: add support for other architectures default n
diff --git a/libc/sysdeps/linux/powerpc/bits/kernel_stat.h b/libc/sysdeps/linux/powerpc/bits/kernel_stat.h index ce62b2ba2..0e76120ab 100644 --- a/libc/sysdeps/linux/powerpc/bits/kernel_stat.h +++ b/libc/sysdeps/linux/powerpc/bits/kernel_stat.h @@ -5,6 +5,16 @@
- struct kernel_stat should look like... It turns out each arch has a
- different opinion on the subject... */
+#if defined(__UCLIBC_USE_TIME64__) +#include <bits/types.h>
+struct ts32_struct {
- __S32_TYPE tv_sec;
- __S32_TYPE tv_nsec;
+};
+#endif
#if __WORDSIZE == 64 #define kernel_stat kernel_stat64 #else @@ -19,9 +29,15 @@ struct kernel_stat { __kernel_off_t st_size; unsigned long st_blksize; unsigned long st_blocks; +#if defined(__UCLIBC_USE_TIME64__)
- struct ts32_struct __st_atim32;
- struct ts32_struct __st_mtim32;
- struct ts32_struct __st_ctim32;
+#else struct timespec st_atim; struct timespec st_mtim; struct timespec st_ctim; +#endif unsigned long __unused4; unsigned long __unused5; }; @@ -39,9 +55,15 @@ struct kernel_stat64 { long long st_size; /* Size of file, in bytes. */ long st_blksize; /* Optimal block size for I/O. */ long long st_blocks; /* Number 512-byte blocks allocated. */
- struct timespec st_atim; /* Time of last access. */
- struct timespec st_mtim; /* Time of last modification. */
- struct timespec st_ctim; /* Time of last status change. */
+#if defined(__UCLIBC_USE_TIME64__)
- struct ts32_struct __st_atim32;
- struct ts32_struct __st_mtim32;
- struct ts32_struct __st_ctim32;
+#else
- struct timespec st_atim;
- struct timespec st_mtim;
- struct timespec st_ctim;
+#endif unsigned long int __uclibc_unused4; unsigned long int __uclibc_unused5; }; diff --git a/libc/sysdeps/linux/powerpc/bits/sem.h b/libc/sysdeps/linux/powerpc/bits/sem.h index a9d895374..8d338eac0 100644 --- a/libc/sysdeps/linux/powerpc/bits/sem.h +++ b/libc/sysdeps/linux/powerpc/bits/sem.h @@ -35,6 +35,7 @@ #define SETALL 17 /* set all semval's */
/* Data structure describing a set of semaphores. */ struct semid_ds { @@ -42,16 +43,31 @@ struct semid_ds #if __WORDSIZE == 32 unsigned int __uclibc_unused1; #endif +#if defined(__UCLIBC_USE_TIME64__)
- unsigned long int __sem_otime_internal_1; /* last semop() time */
- unsigned long int __sem_otime_internal_2;
+#else __time_t sem_otime; /* last semop() time */ +#endif #if __WORDSIZE == 32 unsigned int __uclibc_unused2; #endif +#if defined(__UCLIBC_USE_TIME64__)
- unsigned long int __sem_ctime_internal_1; /* last time changed by semctl() */
- unsigned long int __sem_ctime_internal_2;
+#else __time_t sem_ctime; /* last time changed by semctl() */ +#endif unsigned long int sem_nsems; /* number of semaphores in set */ +#if defined(__UCLIBC_USE_TIME64__)
- __time_t sem_otime;
- __time_t sem_ctime;
+#endif unsigned long __uclibc_unused3; unsigned long __uclibc_unused4; };
/* The user should define a union like the following to use it for arguments for `semctl'.
-- 2.43.2
devel mailing list -- devel@uclibc-ng.org To unsubscribe send an email to devel-leave@uclibc-ng.org
On Sat, Feb 24, 2024 at 10:22 AM Dmitry Chestnykh dm.chestnykh@gmail.com wrote:
For BE architectures there is one significant difference in comparison with time64 support for little-endian architectures like ARMv7. The difference is that we strictly need to pass two 64bit values to system calls because Linux Kernel internally uses `struct __kernel_timespec` and similar, which consists of two 64bit fields. For this reason many files have been changed to convert pointers to timespec-family structures (mixed of 64bit and 32bit values) to the pointer of the similar but 64bit-only structures for using as system calls args. This is general prerequisite for any BE architecture.
Signed-off-by: Dmitry Chestnykh dm.chestnykh@gmail.com
include/time.h | 27 +++++++++++++++++++ libc/inet/socketcalls.c | 2 +- libc/misc/sysvipc/sem.c | 6 ++++- libc/signal/sigwait.c | 3 ++- libc/sysdeps/linux/common/__rt_sigtimedwait.c | 6 ++--- libc/sysdeps/linux/common/__rt_sigwaitinfo.c | 2 +- libc/sysdeps/linux/common/alarm.c | 2 +- libc/sysdeps/linux/common/clock_getres.c | 13 +++++++-- libc/sysdeps/linux/common/clock_gettime.c | 12 ++++++++- libc/sysdeps/linux/common/clock_settime.c | 5 +++- libc/sysdeps/linux/common/ppoll.c | 2 +- libc/sysdeps/linux/common/pselect.c | 2 +- libc/sysdeps/linux/common/select.c | 12 ++++++--- libc/sysdeps/linux/common/time.c | 2 +- libc/sysdeps/linux/common/timerfd.c | 5 +++- libc/sysdeps/linux/common/utimensat.c | 16 ++++++++++- libpthread/nptl/pthread_mutex_timedlock.c | 2 +- .../sysdeps/unix/sysv/linux/lowlevellock.c | 5 ++-- .../sysdeps/unix/sysv/linux/lowlevellock.h | 27 +++++++++++++++++-- .../unix/sysv/linux/lowlevelrobustlock.c | 1 - .../sysdeps/unix/sysv/linux/timer_settime.c | 2 +- librt/clock_gettime.c | 11 ++++++-- librt/clock_nanosleep.c | 5 ++-- librt/mq_timedreceive.c | 8 +++--- librt/mq_timedsend.c | 6 ++++- librt/timer_settime.c | 9 +++++-- 26 files changed, 154 insertions(+), 39 deletions(-)
diff --git a/include/time.h b/include/time.h index 1a1408990..880a80d85 100644 --- a/include/time.h +++ b/include/time.h @@ -122,6 +122,16 @@ struct timespec long int tv_nsec; /* Nanoseconds. */ };
+#if defined(__UCLIBC_USE_TIME64__)
+struct __ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#define TO_TS64_P(__ts) (&(struct __ts64_struct) {.tv_sec = (__ts)->tv_sec, .tv_nsec = (__ts)->tv_nsec})
This doesn't look like a reserved name, so I'm not sure you can use this name in the time.h. Also I think that checking whether __ts is NULL is better done inside this macro.
+#endif
#endif /* timespec not defined and <time.h> or need timespec. */ #undef __need_timespec
@@ -165,6 +175,23 @@ struct itimerspec struct timespec it_value; };
+#if defined(__UCLIBC_USE_TIME64__)
+struct __its64_struct {
- __S64_TYPE interval_tv_sec;
- __S64_TYPE interval_tv_nsec;
- __S64_TYPE value_tv_sec;
- __S64_TYPE value_tv_nsec;
+};
+#define TO_ITS64_P(__its) (&(struct __its64_struct) {.interval_tv_sec = (__its)->it_interval.tv_sec, \
.interval_tv_nsec = (__its)->it_interval.tv_nsec, \
.value_tv_sec = (__its)->it_value.tv_sec, \
.value_tv_nsec = (__its)->it_value.tv_nsec})
Same here.
+#endif
/* We can use a simple forward declaration. */ struct sigevent;
diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c index eb0983698..ea623878a 100644 --- a/libc/inet/socketcalls.c +++ b/libc/inet/socketcalls.c @@ -273,7 +273,7 @@ static ssize_t __NC(recvmmsg)(int sockfd, struct mmsghdr *msg, size_t vlen, int flags, struct timespec *tmo) { # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_recvmmsg_time64)
return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo);
return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo ? TO_TS64_P(tmo) : 0);
# elif defined(__NR_recvmmsg) return (ssize_t)INLINE_SYSCALL(recvmmsg, 5, sockfd, msg, vlen, flags, tmo); # elif __NR_socketcall diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c index cd541761c..48d345984 100644 --- a/libc/misc/sysvipc/sem.c +++ b/libc/misc/sysvipc/sem.c @@ -96,7 +96,11 @@ int semop (int semid, struct sembuf *sops, size_t nsops) #ifdef L_semtimedop
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_semtimedop_time64) -_syscall4_time64(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout) +int semtimedop(int semid, struct sembuf *sops, size_t nsops, const struct timespec *timeout) +{
- return INLINE_SYSCALL(semtimedop_time64, 4, semid, sops, nsops, timeout ? TO_TS64_P(timeout) : 0);
+}
#elif defined(__NR_semtimedop) _syscall4(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout)
diff --git a/libc/signal/sigwait.c b/libc/signal/sigwait.c index 3557a039e..b237534cd 100644 --- a/libc/signal/sigwait.c +++ b/libc/signal/sigwait.c @@ -24,7 +24,8 @@ #include <signal.h> #include <cancel.h>
-#if defined __NR_rt_sigtimedwait && defined __UCLIBC_HAS_REALTIME__ +#if (defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64))) && \
- defined(__UCLIBC_HAS_REALTIME__)
#include <string.h>
diff --git a/libc/sysdeps/linux/common/__rt_sigtimedwait.c b/libc/sysdeps/linux/common/__rt_sigtimedwait.c index bd82ca6d5..44e1ce928 100644 --- a/libc/sysdeps/linux/common/__rt_sigtimedwait.c +++ b/libc/sysdeps/linux/common/__rt_sigtimedwait.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__NR_rt_sigtimedwait_time64) && defined(__UCLIBC_USE_TIME64__)) # include <signal.h> # include <cancel.h> # ifdef __UCLIBC_HAS_THREADS_NATIVE__ @@ -54,7 +54,7 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64) result = INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
timeout, __SYSCALL_SIGSET_T_SIZE);
timeout ? TO_TS64_P(timeout) : 0, __SYSCALL_SIGSET_T_SIZE);
# else result = INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); @@ -72,7 +72,7 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64) return INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
timeout, __SYSCALL_SIGSET_T_SIZE);
timeout ? TO_TS64_P(timeout) : 0, __SYSCALL_SIGSET_T_SIZE);
# else return INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); diff --git a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c index d2d176a64..7830b2e2c 100644 --- a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c +++ b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)) # define __need_NULL # include <stddef.h> # include <signal.h> diff --git a/libc/sysdeps/linux/common/alarm.c b/libc/sysdeps/linux/common/alarm.c index 4e6e2215b..861f6ad8e 100644 --- a/libc/sysdeps/linux/common/alarm.c +++ b/libc/sysdeps/linux/common/alarm.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <unistd.h>
-#ifdef __NR_alarm && !defined(__UCLIBC_USE_TIME64__) +#if defined(__NR_alarm) && !defined(__UCLIBC_USE_TIME64__) _syscall1(unsigned int, alarm, unsigned int, seconds) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/clock_getres.c b/libc/sysdeps/linux/common/clock_getres.c index d4b989958..c1818f9ce 100644 --- a/libc/sysdeps/linux/common/clock_getres.c +++ b/libc/sysdeps/linux/common/clock_getres.c @@ -10,9 +10,18 @@ #include <sys/syscall.h> #include <time.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64) -_syscall2_time64(int, clock_getres, clockid_t, clock_id, struct timespec*, res) +int clock_getres(clockid_t clock_id, struct timespec *res) +{
struct __ts64_struct __ts64;
int __ret = INLINE_SYSCALL(clock_getres_time64, 2, clock_id, &__ts64);
if (__ret == 0 && res) {
res->tv_sec = __ts64.tv_sec;
res->tv_nsec = __ts64.tv_nsec;
};
return __ret;
+} #elif defined(__NR_clock_getres) _syscall2(int, clock_getres, clockid_t, clock_id, struct timespec*, res) #else diff --git a/libc/sysdeps/linux/common/clock_gettime.c b/libc/sysdeps/linux/common/clock_gettime.c index a595bd691..00212a9ef 100644 --- a/libc/sysdeps/linux/common/clock_gettime.c +++ b/libc/sysdeps/linux/common/clock_gettime.c @@ -12,7 +12,17 @@ #include <time.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) -_syscall2_64(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) +int clock_gettime(clockid_t clock_id, struct timespec *tp) +{
struct __ts64_struct __ts64;
int __ret = INLINE_SYSCALL(clock_gettime64, 2, clock_id, &__ts64);
if (tp) {
tp->tv_sec = __ts64.tv_sec;
tp->tv_nsec = __ts64.tv_nsec;
}
return __ret;
+} #elif defined(__NR_clock_gettime) _syscall2(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/clock_settime.c b/libc/sysdeps/linux/common/clock_settime.c index 89550af5a..666ae4075 100644 --- a/libc/sysdeps/linux/common/clock_settime.c +++ b/libc/sysdeps/linux/common/clock_settime.c @@ -12,7 +12,10 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_settime64) -_syscall2_64(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) +int clock_settime(clockid_t clock_id, const struct timespec *tp) +{
return INLINE_SYSCALL(clock_settime64, 2, clock_id, tp ? TO_TS64_P(tp) : 0);
+} #elif defined(__NR_clock_settime) _syscall2(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/ppoll.c b/libc/sysdeps/linux/common/ppoll.c index cb36149c5..3b98a2760 100644 --- a/libc/sysdeps/linux/common/ppoll.c +++ b/libc/sysdeps/linux/common/ppoll.c @@ -38,7 +38,7 @@ __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, timeout = &tval; } #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_ppoll_time64)
return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE);
return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout ? TO_TS64_P(timeout) : 0, sigmask, __SYSCALL_SIGSET_T_SIZE);
#else return INLINE_SYSCALL(ppoll, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE); #endif diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c index 23bdab5cf..3ceb51012 100644 --- a/libc/sysdeps/linux/common/pselect.c +++ b/libc/sysdeps/linux/common/pselect.c @@ -57,7 +57,7 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, sigmask = (void *)&data; } #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64)
return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask);
return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout ? TO_TS64_P(timeout) : 0, sigmask);
#else return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask); #endif diff --git a/libc/sysdeps/linux/common/select.c b/libc/sysdeps/linux/common/select.c index 3132a109c..05d2b55b2 100644 --- a/libc/sysdeps/linux/common/select.c +++ b/libc/sysdeps/linux/common/select.c @@ -15,7 +15,7 @@ # define __NR_select __NR__newselect #endif
-#if !defined __NR_select && defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) # include <stdint.h> # define USEC_PER_SEC 1000000L #endif @@ -23,9 +23,7 @@ int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { -#ifdef __NR_select
return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, timeout);
-#elif defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) struct timespec _ts, *ts = 0; if (timeout) { uint32_t usec; @@ -47,8 +45,14 @@ int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
ts = &_ts; }
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64)
return INLINE_SYSCALL(pselect6_time64, 6, n, readfds, writefds, exceptfds, ts ? TO_TS64_P(ts) : 0, 0);
+#else return INLINE_SYSCALL(pselect6, 6, n, readfds, writefds, exceptfds, ts, 0); #endif +#elif defined(__NR_select)
return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, ts);
+#endif } /* we should guard it, but we need it in other files, so let it fail
- if we miss any of the syscalls */
diff --git a/libc/sysdeps/linux/common/time.c b/libc/sysdeps/linux/common/time.c index 22403f174..d084ffaad 100644 --- a/libc/sysdeps/linux/common/time.c +++ b/libc/sysdeps/linux/common/time.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <time.h>
-#ifdef __NR_time +#if defined(__NR_time) && !defined(__UCLIBC_USE_TIME64__) _syscall_noerr1(time_t, time, time_t *, t) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/timerfd.c b/libc/sysdeps/linux/common/timerfd.c index 0f19b44ed..07bfb09b7 100644 --- a/libc/sysdeps/linux/common/timerfd.c +++ b/libc/sysdeps/linux/common/timerfd.c @@ -21,7 +21,10 @@ _syscall2(int, timerfd_create, int, clockid, int, flags) */ #if defined(__NR_timerfd_settime) || defined(__NR_timerfd_settime64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timerfd_settime64) -_syscall4_64(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) +int timerfd_settime(int ufd, int flags, const struct itimerspec *utmr, struct itimerspec *otmr) +{
- return INLINE_SYSCALL(timerfd_settime64, 4, ufd, flags, utmr ? TO_ITS64_P(utmr) : 0, otmr);
+} #else _syscall4(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) #endif diff --git a/libc/sysdeps/linux/common/utimensat.c b/libc/sysdeps/linux/common/utimensat.c index 6a78ebb4f..339a35559 100644 --- a/libc/sysdeps/linux/common/utimensat.c +++ b/libc/sysdeps/linux/common/utimensat.c @@ -11,7 +11,21 @@
#if defined(__NR_utimensat) || defined(__NR_utimensat_time64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_utimensat_time64) -_syscall4_time64(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) +int utimensat(int fd, const char *path, const struct timespec times[2], int flags) +{
- struct __ts64_struct __times64[2] = {
{
.tv_sec = times ? times[0].tv_sec : 0,
.tv_nsec = times ? times[0].tv_nsec : 0
},
{
.tv_sec = times ? times[1].tv_sec : 0,
.tv_nsec = times ? times[1].tv_nsec : 0
}
- };
- return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ? &__times64 : 0, flags);
+} #else _syscall4(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) #endif diff --git a/libpthread/nptl/pthread_mutex_timedlock.c b/libpthread/nptl/pthread_mutex_timedlock.c index 25f9ec3b2..7bb9a0aaf 100644 --- a/libpthread/nptl/pthread_mutex_timedlock.c +++ b/libpthread/nptl/pthread_mutex_timedlock.c @@ -268,7 +268,7 @@ pthread_mutex_timedlock ( int e = INTERNAL_SYSCALL (futex_time64, __err, 4, &mutex->__data.__lock, __lll_private_flag (FUTEX_LOCK_PI, private), 1,
abstime);
abstime ? TO_TS64_P(abstime) : 0);
#else int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock, __lll_private_flag (FUTEX_LOCK_PI, diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c index 4294a20b0..e168b3925 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c @@ -95,7 +95,7 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime) while ((tid = *tidp) != 0) { struct timeval tv;
struct timespec rt;
struct timespec rt, *rtp; /* Get the current time. */ (void) __gettimeofday (&tv, NULL);
@@ -115,7 +115,8 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime)
/* Wait until thread terminates. The kernel so far does not use the private futex operations for this. */
if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) == -ETIMEDOUT)
rtp = &rt;
if (lll_futex_timed_wait (tidp, tid, rtp, LLL_SHARED) == -ETIMEDOUT)
Not needed, right?
return ETIMEDOUT; }
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h index e72fe5234..909b0aad3 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h @@ -71,8 +71,31 @@ # endif #endif
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
#define lll_futex_wait(futexp, val, private) \
- lll_futex_timed_wait(futexp, val, NULL, private)
- ({ \
- INTERNAL_SYSCALL_DECL (__err); \
- long int __ret; \
- __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \
__lll_private_flag (FUTEX_WAIT, private), \
(val), NULL); \
- __ret; \
- })
+#else
+#define lll_futex_wait(futexp, val, private) \
- ({ \
- INTERNAL_SYSCALL_DECL (__err); \
- long int __ret; \
- __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \
__lll_private_flag (FUTEX_WAIT, private), \
(val), NULL); \
- __ret; \
- })
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
@@ -82,7 +105,7 @@ long int __ret; \ __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \ __lll_private_flag (FUTEX_WAIT, private), \
(val), (timespec)); \
(val), (TO_TS64_P(timespec))); \
This is missing the 'timespec is non-NULL' check. Which should be inside the macro anyway.
__ret; \
})
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c index 7b4e84343..6403f7ea0 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c @@ -99,7 +99,6 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime, if (oldval != newval && atomic_compare_and_exchange_bool_acq (futex, newval, oldval)) continue;
Please don't do random formatting changes.
lll_futex_timed_wait (futex, newval, &rt, private); try:
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c index 80d242f21..4fa600cb6 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c @@ -56,7 +56,7 @@ timer_settime ( /* Delete the kernel timer object. */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) int res = INLINE_SYSCALL (timer_settime64, 4, kt->ktimerid, flags,
value, ovalue);
value ? TO_ITS64_P(value) : 0, ovalue);
# else int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags, value, ovalue); diff --git a/librt/clock_gettime.c b/librt/clock_gettime.c index b66b60231..c514e1a54 100644 --- a/librt/clock_gettime.c +++ b/librt/clock_gettime.c @@ -24,8 +24,15 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) #define SYSCALL_GETTIME \
- retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, tp); \
- break
- { \
- struct __ts64_struct __ts64; \
- retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, &__ts64); \
- if (tp) { \
- tp->tv_sec = __ts64.tv_sec; \
- tp->tv_nsec = __ts64.tv_nsec; \
- } \
- break; \
- }
#else #define SYSCALL_GETTIME \ retval = INLINE_SYSCALL (clock_gettime, 2, clock_id, tp); \ diff --git a/librt/clock_nanosleep.c b/librt/clock_nanosleep.c index eaae75720..cb7b2afa3 100644 --- a/librt/clock_nanosleep.c +++ b/librt/clock_nanosleep.c @@ -21,7 +21,6 @@
#include "kernel-posix-cpu-timers.h"
Please don't do random formatting changes.
/* We can simply use the syscall. The CPU clocks are not supported with this function. */ int @@ -38,7 +37,7 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
if (SINGLE_THREAD_P) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64)
- r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem);
- r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req ? TO_TS64_P(req) : 0, rem);
#else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); #endif @@ -47,7 +46,7 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, #ifdef __NEW_THREADS int oldstate = LIBC_CANCEL_ASYNC (); #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64)
r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem);
r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req ? TO_TS64_P(req): 0, rem);
#else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); diff --git a/librt/mq_timedreceive.c b/librt/mq_timedreceive.c index db1ae1aa8..2570b6f9e 100644 --- a/librt/mq_timedreceive.c +++ b/librt/mq_timedreceive.c @@ -9,12 +9,14 @@ #include <cancel.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedreceive_time64) -#define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive_time64 +int _NC(mq_timedreceive)(mqd_t mqdes, char *restrict msg_ptr, size_t msg_len, unsigned int *restrict msq_prio, const struct timespec *restrict abs_timeout) +{
return INLINE_SYSCALL(mq_timedreceive_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, abs_timeout ? TO_TS64_P(abs_timeout) : 0);
+} #else #define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive -#endif
_syscall5(ssize_t, __NC(mq_timedreceive), mqd_t, mqdes, char *__restrict, msg_ptr, size_t, msg_len, unsigned int *__restrict, msq_prio, const struct timespec *__restrict, abs_timeout) +#endif
CANCELLABLE_SYSCALL(ssize_t, mq_timedreceive, (mqd_t mqdes, char *__restrict msg_ptr, size_t msq_len, unsigned int *__restrict msq_prio, const struct timespec *__restrict abs_timeout), (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) diff --git a/librt/mq_timedsend.c b/librt/mq_timedsend.c index 6afaf5157..bcbc0685f 100644 --- a/librt/mq_timedsend.c +++ b/librt/mq_timedsend.c @@ -10,11 +10,15 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedsend_time64) #define __NR___mq_timedsend_nocancel __NR_mq_timedsend_time64 +int _NC(mq_timedsend)(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msq_prio, const struct timespec *abs_timeout) +{
return INLINE_SYSCALL(mq_timedsend_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, abs_timeout ? TO_TS64_P(abs_timeout) : 0);
+} #else #define __NR___mq_timedsend_nocancel __NR_mq_timedsend +_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) #endif
-_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) CANCELLABLE_SYSCALL(int, mq_timedsend, (mqd_t mqdes, const char *msg_ptr, size_t msq_len, unsigned int msq_prio, const struct timespec *abs_timeout), (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) lt_libc_hidden(mq_timedsend) diff --git a/librt/timer_settime.c b/librt/timer_settime.c index 022880297..6bf5f8307 100644 --- a/librt/timer_settime.c +++ b/librt/timer_settime.c @@ -12,10 +12,14 @@ #if defined(__NR_timer_settime) || defined(__NR_timer_settime64)
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) -#define __NR___syscall_timer_settime __NR_timer_settime64 +int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue) +{
struct timer *kt = (struct timer *)timerid;
return INLINE_SYSCALL(timer_settime64, 4, kt->ktimerid, flags, value ? TO_ITS64_P(value) : 0, ovalue);
+} #else #define __NR___syscall_timer_settime __NR_timer_settime -#endif
static __inline__ _syscall4(int, __syscall_timer_settime, kernel_timer_t, ktimerid, int, flags, const void *, value, void *, ovalue); @@ -31,3 +35,4 @@ int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, }
#endif
+#endif
2.43.2
devel mailing list -- devel@uclibc-ng.org To unsubscribe send an email to devel-leave@uclibc-ng.org
What name should we use instead of __ts? I suggest ____uclibc_ts_internal, it starts with four underscores, so it seems to be okay. As another option we can put these macroses inside some private header.
сб, 24 февр. 2024 г., 21:58 Max Filippov jcmvbkbc@gmail.com:
On Sat, Feb 24, 2024 at 10:22 AM Dmitry Chestnykh dm.chestnykh@gmail.com wrote:
For BE architectures there is one significant difference in comparison with time64 support for little-endian architectures like ARMv7. The difference is that we strictly need to pass two 64bit values to system calls because Linux Kernel internally uses `struct __kernel_timespec` and similar, which consists of two 64bit fields. For this reason many files have been changed to convert pointers to timespec-family structures (mixed of 64bit and 32bit values) to the pointer of the similar but 64bit-only structures for using as system calls args. This is general prerequisite for any BE architecture.
Signed-off-by: Dmitry Chestnykh dm.chestnykh@gmail.com
include/time.h | 27 +++++++++++++++++++ libc/inet/socketcalls.c | 2 +- libc/misc/sysvipc/sem.c | 6 ++++- libc/signal/sigwait.c | 3 ++- libc/sysdeps/linux/common/__rt_sigtimedwait.c | 6 ++--- libc/sysdeps/linux/common/__rt_sigwaitinfo.c | 2 +- libc/sysdeps/linux/common/alarm.c | 2 +- libc/sysdeps/linux/common/clock_getres.c | 13 +++++++-- libc/sysdeps/linux/common/clock_gettime.c | 12 ++++++++- libc/sysdeps/linux/common/clock_settime.c | 5 +++- libc/sysdeps/linux/common/ppoll.c | 2 +- libc/sysdeps/linux/common/pselect.c | 2 +- libc/sysdeps/linux/common/select.c | 12 ++++++--- libc/sysdeps/linux/common/time.c | 2 +- libc/sysdeps/linux/common/timerfd.c | 5 +++- libc/sysdeps/linux/common/utimensat.c | 16 ++++++++++- libpthread/nptl/pthread_mutex_timedlock.c | 2 +- .../sysdeps/unix/sysv/linux/lowlevellock.c | 5 ++-- .../sysdeps/unix/sysv/linux/lowlevellock.h | 27 +++++++++++++++++-- .../unix/sysv/linux/lowlevelrobustlock.c | 1 - .../sysdeps/unix/sysv/linux/timer_settime.c | 2 +- librt/clock_gettime.c | 11 ++++++-- librt/clock_nanosleep.c | 5 ++-- librt/mq_timedreceive.c | 8 +++--- librt/mq_timedsend.c | 6 ++++- librt/timer_settime.c | 9 +++++-- 26 files changed, 154 insertions(+), 39 deletions(-)
diff --git a/include/time.h b/include/time.h index 1a1408990..880a80d85 100644 --- a/include/time.h +++ b/include/time.h @@ -122,6 +122,16 @@ struct timespec long int tv_nsec; /* Nanoseconds. */ };
+#if defined(__UCLIBC_USE_TIME64__)
+struct __ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#define TO_TS64_P(__ts) (&(struct __ts64_struct) {.tv_sec =
(__ts)->tv_sec, .tv_nsec = (__ts)->tv_nsec})
This doesn't look like a reserved name, so I'm not sure you can use this name in the time.h. Also I think that checking whether __ts is NULL is better done inside this macro.
+#endif
#endif /* timespec not defined and <time.h> or need timespec. */ #undef __need_timespec
@@ -165,6 +175,23 @@ struct itimerspec struct timespec it_value; };
+#if defined(__UCLIBC_USE_TIME64__)
+struct __its64_struct {
- __S64_TYPE interval_tv_sec;
- __S64_TYPE interval_tv_nsec;
- __S64_TYPE value_tv_sec;
- __S64_TYPE value_tv_nsec;
+};
+#define TO_ITS64_P(__its) (&(struct __its64_struct) {.interval_tv_sec =
(__its)->it_interval.tv_sec, \
.interval_tv_nsec
= (__its)->it_interval.tv_nsec, \
.value_tv_sec =
(__its)->it_value.tv_sec, \
.value_tv_nsec =
(__its)->it_value.tv_nsec})
Same here.
+#endif
/* We can use a simple forward declaration. */ struct sigevent;
diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c index eb0983698..ea623878a 100644 --- a/libc/inet/socketcalls.c +++ b/libc/inet/socketcalls.c @@ -273,7 +273,7 @@ static ssize_t __NC(recvmmsg)(int sockfd, struct
mmsghdr *msg, size_t vlen,
int flags, struct timespec *tmo)
{ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_recvmmsg_time64)
return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg,
vlen, flags, tmo);
return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg,
vlen, flags, tmo ? TO_TS64_P(tmo) : 0);
# elif defined(__NR_recvmmsg) return (ssize_t)INLINE_SYSCALL(recvmmsg, 5, sockfd, msg, vlen,
flags, tmo);
# elif __NR_socketcall diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c index cd541761c..48d345984 100644 --- a/libc/misc/sysvipc/sem.c +++ b/libc/misc/sysvipc/sem.c @@ -96,7 +96,11 @@ int semop (int semid, struct sembuf *sops, size_t
nsops)
#ifdef L_semtimedop
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_semtimedop_time64) -_syscall4_time64(int, semtimedop, int, semid, struct sembuf *, sops,
size_t, nsops, const struct timespec *, timeout)
+int semtimedop(int semid, struct sembuf *sops, size_t nsops, const
struct timespec *timeout)
+{
- return INLINE_SYSCALL(semtimedop_time64, 4, semid, sops, nsops,
timeout ? TO_TS64_P(timeout) : 0);
+}
#elif defined(__NR_semtimedop) _syscall4(int, semtimedop, int, semid, struct sembuf *, sops, size_t,
nsops, const struct timespec *, timeout)
diff --git a/libc/signal/sigwait.c b/libc/signal/sigwait.c index 3557a039e..b237534cd 100644 --- a/libc/signal/sigwait.c +++ b/libc/signal/sigwait.c @@ -24,7 +24,8 @@ #include <signal.h> #include <cancel.h>
-#if defined __NR_rt_sigtimedwait && defined __UCLIBC_HAS_REALTIME__ +#if (defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__)
&& defined(__NR_rt_sigtimedwait_time64))) && \
- defined(__UCLIBC_HAS_REALTIME__)
#include <string.h>
diff --git a/libc/sysdeps/linux/common/__rt_sigtimedwait.c
b/libc/sysdeps/linux/common/__rt_sigtimedwait.c
index bd82ca6d5..44e1ce928 100644 --- a/libc/sysdeps/linux/common/__rt_sigtimedwait.c +++ b/libc/sysdeps/linux/common/__rt_sigtimedwait.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) ||
(defined(__NR_rt_sigtimedwait_time64) && defined(__UCLIBC_USE_TIME64__))
# include <signal.h> # include <cancel.h> # ifdef __UCLIBC_HAS_THREADS_NATIVE__ @@ -54,7 +54,7 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t
*info,
/* on uClibc we use the kernel sigset_t size */
# if defined(__UCLIBC_USE_TIME64__) &&
defined(__NR_rt_sigtimedwait_time64)
result = INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
timeout, __SYSCALL_SIGSET_T_SIZE);
timeout ? TO_TS64_P(timeout) : 0,
__SYSCALL_SIGSET_T_SIZE);
# else result = INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); @@ -72,7 +72,7 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t
*info,
/* on uClibc we use the kernel sigset_t size */
# if defined(__UCLIBC_USE_TIME64__) &&
defined(__NR_rt_sigtimedwait_time64)
return INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
timeout, __SYSCALL_SIGSET_T_SIZE);
timeout ? TO_TS64_P(timeout) : 0,
__SYSCALL_SIGSET_T_SIZE);
# else return INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); diff --git a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c
b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c
index d2d176a64..7830b2e2c 100644 --- a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c +++ b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) &&
defined(__NR_rt_sigtimedwait_time64))
# define __need_NULL # include <stddef.h> # include <signal.h> diff --git a/libc/sysdeps/linux/common/alarm.c
b/libc/sysdeps/linux/common/alarm.c
index 4e6e2215b..861f6ad8e 100644 --- a/libc/sysdeps/linux/common/alarm.c +++ b/libc/sysdeps/linux/common/alarm.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <unistd.h>
-#ifdef __NR_alarm && !defined(__UCLIBC_USE_TIME64__) +#if defined(__NR_alarm) && !defined(__UCLIBC_USE_TIME64__) _syscall1(unsigned int, alarm, unsigned int, seconds) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/clock_getres.c
b/libc/sysdeps/linux/common/clock_getres.c
index d4b989958..c1818f9ce 100644 --- a/libc/sysdeps/linux/common/clock_getres.c +++ b/libc/sysdeps/linux/common/clock_getres.c @@ -10,9 +10,18 @@ #include <sys/syscall.h> #include <time.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64) -_syscall2_time64(int, clock_getres, clockid_t, clock_id, struct
timespec*, res)
+int clock_getres(clockid_t clock_id, struct timespec *res) +{
struct __ts64_struct __ts64;
int __ret = INLINE_SYSCALL(clock_getres_time64, 2, clock_id,
&__ts64);
if (__ret == 0 && res) {
res->tv_sec = __ts64.tv_sec;
res->tv_nsec = __ts64.tv_nsec;
};
return __ret;
+} #elif defined(__NR_clock_getres) _syscall2(int, clock_getres, clockid_t, clock_id, struct timespec*, res) #else diff --git a/libc/sysdeps/linux/common/clock_gettime.c
b/libc/sysdeps/linux/common/clock_gettime.c
index a595bd691..00212a9ef 100644 --- a/libc/sysdeps/linux/common/clock_gettime.c +++ b/libc/sysdeps/linux/common/clock_gettime.c @@ -12,7 +12,17 @@ #include <time.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) -_syscall2_64(int, clock_gettime, clockid_t, clock_id, struct timespec*,
tp)
+int clock_gettime(clockid_t clock_id, struct timespec *tp) +{
struct __ts64_struct __ts64;
int __ret = INLINE_SYSCALL(clock_gettime64, 2, clock_id,
&__ts64);
if (tp) {
tp->tv_sec = __ts64.tv_sec;
tp->tv_nsec = __ts64.tv_nsec;
}
return __ret;
+} #elif defined(__NR_clock_gettime) _syscall2(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/clock_settime.c
b/libc/sysdeps/linux/common/clock_settime.c
index 89550af5a..666ae4075 100644 --- a/libc/sysdeps/linux/common/clock_settime.c +++ b/libc/sysdeps/linux/common/clock_settime.c @@ -12,7 +12,10 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_settime64) -_syscall2_64(int, clock_settime, clockid_t, clock_id, const struct
timespec*, tp)
+int clock_settime(clockid_t clock_id, const struct timespec *tp) +{
return INLINE_SYSCALL(clock_settime64, 2, clock_id, tp ?
TO_TS64_P(tp) : 0);
+} #elif defined(__NR_clock_settime) _syscall2(int, clock_settime, clockid_t, clock_id, const struct
timespec*, tp)
#else diff --git a/libc/sysdeps/linux/common/ppoll.c
b/libc/sysdeps/linux/common/ppoll.c
index cb36149c5..3b98a2760 100644 --- a/libc/sysdeps/linux/common/ppoll.c +++ b/libc/sysdeps/linux/common/ppoll.c @@ -38,7 +38,7 @@ __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const
struct timespec *timeout,
timeout = &tval; }
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_ppoll_time64)
return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout,
sigmask, __SYSCALL_SIGSET_T_SIZE);
return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout ?
TO_TS64_P(timeout) : 0, sigmask, __SYSCALL_SIGSET_T_SIZE);
#else return INLINE_SYSCALL(ppoll, 5, fds, nfds, timeout, sigmask,
__SYSCALL_SIGSET_T_SIZE);
#endif diff --git a/libc/sysdeps/linux/common/pselect.c
b/libc/sysdeps/linux/common/pselect.c
index 23bdab5cf..3ceb51012 100644 --- a/libc/sysdeps/linux/common/pselect.c +++ b/libc/sysdeps/linux/common/pselect.c @@ -57,7 +57,7 @@ static int __NC(pselect)(int nfds, fd_set *readfds,
fd_set *writefds,
sigmask = (void *)&data; }
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64)
return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds,
writefds, exceptfds, timeout, sigmask);
return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds,
writefds, exceptfds, timeout ? TO_TS64_P(timeout) : 0, sigmask);
#else return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds,
exceptfds, timeout, sigmask);
#endif diff --git a/libc/sysdeps/linux/common/select.c
b/libc/sysdeps/linux/common/select.c
index 3132a109c..05d2b55b2 100644 --- a/libc/sysdeps/linux/common/select.c +++ b/libc/sysdeps/linux/common/select.c @@ -15,7 +15,7 @@ # define __NR_select __NR__newselect #endif
-#if !defined __NR_select && defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) # include <stdint.h> # define USEC_PER_SEC 1000000L #endif @@ -23,9 +23,7 @@ int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set
*exceptfds,
struct timeval *timeout)
{ -#ifdef __NR_select
return INLINE_SYSCALL(select, 5, n, readfds, writefds,
exceptfds, timeout);
-#elif defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) struct timespec _ts, *ts = 0; if (timeout) { uint32_t usec; @@ -47,8 +45,14 @@ int __NC(select)(int n, fd_set *readfds, fd_set
*writefds, fd_set *exceptfds,
ts = &_ts; }
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64)
return INLINE_SYSCALL(pselect6_time64, 6, n, readfds, writefds,
exceptfds, ts ? TO_TS64_P(ts) : 0, 0);
+#else return INLINE_SYSCALL(pselect6, 6, n, readfds, writefds,
exceptfds, ts, 0);
#endif +#elif defined(__NR_select)
return INLINE_SYSCALL(select, 5, n, readfds, writefds,
exceptfds, ts);
+#endif } /* we should guard it, but we need it in other files, so let it fail
- if we miss any of the syscalls */
diff --git a/libc/sysdeps/linux/common/time.c
b/libc/sysdeps/linux/common/time.c
index 22403f174..d084ffaad 100644 --- a/libc/sysdeps/linux/common/time.c +++ b/libc/sysdeps/linux/common/time.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <time.h>
-#ifdef __NR_time +#if defined(__NR_time) && !defined(__UCLIBC_USE_TIME64__) _syscall_noerr1(time_t, time, time_t *, t) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/timerfd.c
b/libc/sysdeps/linux/common/timerfd.c
index 0f19b44ed..07bfb09b7 100644 --- a/libc/sysdeps/linux/common/timerfd.c +++ b/libc/sysdeps/linux/common/timerfd.c @@ -21,7 +21,10 @@ _syscall2(int, timerfd_create, int, clockid, int,
flags)
*/ #if defined(__NR_timerfd_settime) || defined(__NR_timerfd_settime64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timerfd_settime64) -_syscall4_64(int, timerfd_settime, int, ufd, int, flags, const struct
itimerspec *, utmr, struct itimerspec *, otmr)
+int timerfd_settime(int ufd, int flags, const struct itimerspec *utmr,
struct itimerspec *otmr)
+{
- return INLINE_SYSCALL(timerfd_settime64, 4, ufd, flags, utmr ?
TO_ITS64_P(utmr) : 0, otmr);
+} #else _syscall4(int, timerfd_settime, int, ufd, int, flags, const struct
itimerspec *, utmr, struct itimerspec *, otmr)
#endif diff --git a/libc/sysdeps/linux/common/utimensat.c
b/libc/sysdeps/linux/common/utimensat.c
index 6a78ebb4f..339a35559 100644 --- a/libc/sysdeps/linux/common/utimensat.c +++ b/libc/sysdeps/linux/common/utimensat.c @@ -11,7 +11,21 @@
#if defined(__NR_utimensat) || defined(__NR_utimensat_time64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_utimensat_time64) -_syscall4_time64(int, utimensat, int, fd, const char *, path, const
struct timespec *, times, int, flags)
+int utimensat(int fd, const char *path, const struct timespec times[2],
int flags)
+{
- struct __ts64_struct __times64[2] = {
{
.tv_sec = times ? times[0].tv_sec : 0,
.tv_nsec = times ? times[0].tv_nsec : 0
},
{
.tv_sec = times ? times[1].tv_sec : 0,
.tv_nsec = times ? times[1].tv_nsec : 0
}
- };
- return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ?
&__times64 : 0, flags);
+} #else _syscall4(int, utimensat, int, fd, const char *, path, const struct
timespec *, times, int, flags)
#endif diff --git a/libpthread/nptl/pthread_mutex_timedlock.c
b/libpthread/nptl/pthread_mutex_timedlock.c
index 25f9ec3b2..7bb9a0aaf 100644 --- a/libpthread/nptl/pthread_mutex_timedlock.c +++ b/libpthread/nptl/pthread_mutex_timedlock.c @@ -268,7 +268,7 @@ pthread_mutex_timedlock ( int e = INTERNAL_SYSCALL (futex_time64, __err, 4,
&mutex->__data.__lock,
__lll_private_flag (FUTEX_LOCK_PI, private), 1,
abstime);
abstime ? TO_TS64_P(abstime) : 0);
#else int e = INTERNAL_SYSCALL (futex, __err, 4,
&mutex->__data.__lock,
__lll_private_flag (FUTEX_LOCK_PI,
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c
b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c
index 4294a20b0..e168b3925 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c @@ -95,7 +95,7 @@ __lll_timedwait_tid (int *tidp, const struct timespec
*abstime)
while ((tid = *tidp) != 0) { struct timeval tv;
struct timespec rt;
struct timespec rt, *rtp; /* Get the current time. */ (void) __gettimeofday (&tv, NULL);
@@ -115,7 +115,8 @@ __lll_timedwait_tid (int *tidp, const struct
timespec *abstime)
/* Wait until thread terminates. The kernel so far does not use the private futex operations for this. */
if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) ==
-ETIMEDOUT)
rtp = &rt;
if (lll_futex_timed_wait (tidp, tid, rtp, LLL_SHARED) ==
-ETIMEDOUT)
Not needed, right?
return ETIMEDOUT; }
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h
b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h
index e72fe5234..909b0aad3 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h @@ -71,8 +71,31 @@ # endif #endif
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
#define lll_futex_wait(futexp, val, private) \
- lll_futex_timed_wait(futexp, val, NULL, private)
- ({
\
- INTERNAL_SYSCALL_DECL (__err);
\
- long int __ret;
\
- __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp),
\
__lll_private_flag (FUTEX_WAIT, private),
\
(val), NULL); \
- __ret;
\
- })
+#else
+#define lll_futex_wait(futexp, val, private) \
- ({
\
- INTERNAL_SYSCALL_DECL (__err);
\
- long int __ret;
\
- __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp),
\
__lll_private_flag (FUTEX_WAIT, private),
\
(val), NULL); \
- __ret;
\
- })
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
@@ -82,7 +105,7 @@ long int __ret;
\
__ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp),
\
__lll_private_flag (FUTEX_WAIT, private),
\
(val), (timespec));
\
(val), (TO_TS64_P(timespec)));
\
This is missing the 'timespec is non-NULL' check. Which should be inside the macro anyway.
__ret;
\
})
diff --git
a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
index 7b4e84343..6403f7ea0 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c @@ -99,7 +99,6 @@ __lll_robust_timedlock_wait (int *futex, const struct
timespec *abstime,
if (oldval != newval && atomic_compare_and_exchange_bool_acq (futex, newval,
oldval))
continue;
Please don't do random formatting changes.
lll_futex_timed_wait (futex, newval, &rt, private); try:
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c
b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c
index 80d242f21..4fa600cb6 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c @@ -56,7 +56,7 @@ timer_settime ( /* Delete the kernel timer object. */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) int res = INLINE_SYSCALL (timer_settime64, 4, kt->ktimerid, flags,
value, ovalue);
value ? TO_ITS64_P(value) : 0, ovalue);
# else int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags, value, ovalue); diff --git a/librt/clock_gettime.c b/librt/clock_gettime.c index b66b60231..c514e1a54 100644 --- a/librt/clock_gettime.c +++ b/librt/clock_gettime.c @@ -24,8 +24,15 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) #define SYSCALL_GETTIME \
- retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, tp); \
- break
- { \
- struct __ts64_struct __ts64; \
- retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, &__ts64); \
- if (tp) { \
- tp->tv_sec = __ts64.tv_sec; \
- tp->tv_nsec = __ts64.tv_nsec; \
- } \
- break; \
- }
#else #define SYSCALL_GETTIME \ retval = INLINE_SYSCALL (clock_gettime, 2, clock_id, tp); \ diff --git a/librt/clock_nanosleep.c b/librt/clock_nanosleep.c index eaae75720..cb7b2afa3 100644 --- a/librt/clock_nanosleep.c +++ b/librt/clock_nanosleep.c @@ -21,7 +21,6 @@
#include "kernel-posix-cpu-timers.h"
Please don't do random formatting changes.
/* We can simply use the syscall. The CPU clocks are not supported with this function. */ int @@ -38,7 +37,7 @@ clock_nanosleep (clockid_t clock_id, int flags, const
struct timespec *req,
if (SINGLE_THREAD_P) #if defined(__UCLIBC_USE_TIME64__) &&
defined(__NR_clock_nanosleep_time64)
- r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id,
flags, req, rem);
- r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id,
flags, req ? TO_TS64_P(req) : 0, rem);
#else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags,
req, rem);
#endif @@ -47,7 +46,7 @@ clock_nanosleep (clockid_t clock_id, int flags, const
struct timespec *req,
#ifdef __NEW_THREADS int oldstate = LIBC_CANCEL_ASYNC (); #if defined(__UCLIBC_USE_TIME64__) &&
defined(__NR_clock_nanosleep_time64)
r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id,
flags, req, rem);
r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id,
flags, req ? TO_TS64_P(req): 0, rem);
#else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags,
req,
rem);
diff --git a/librt/mq_timedreceive.c b/librt/mq_timedreceive.c index db1ae1aa8..2570b6f9e 100644 --- a/librt/mq_timedreceive.c +++ b/librt/mq_timedreceive.c @@ -9,12 +9,14 @@ #include <cancel.h>
#if defined(__UCLIBC_USE_TIME64__) &&
defined(__NR_mq_timedreceive_time64)
-#define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive_time64 +int _NC(mq_timedreceive)(mqd_t mqdes, char *restrict msg_ptr, size_t
msg_len, unsigned int *restrict msq_prio, const struct timespec *restrict abs_timeout)
+{
return INLINE_SYSCALL(mq_timedreceive_time64, 5, mqdes, msg_ptr,
msg_len, msq_prio, abs_timeout ? TO_TS64_P(abs_timeout) : 0);
+} #else #define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive -#endif
_syscall5(ssize_t, __NC(mq_timedreceive), mqd_t, mqdes, char
*__restrict, msg_ptr, size_t, msg_len, unsigned int *__restrict, msq_prio, const struct timespec *__restrict, abs_timeout)
+#endif
CANCELLABLE_SYSCALL(ssize_t, mq_timedreceive, (mqd_t mqdes, char
*__restrict msg_ptr, size_t msq_len, unsigned int *__restrict msq_prio, const struct timespec *__restrict abs_timeout),
(mqdes, msg_ptr, msq_len, msq_prio, abs_timeout))
diff --git a/librt/mq_timedsend.c b/librt/mq_timedsend.c index 6afaf5157..bcbc0685f 100644 --- a/librt/mq_timedsend.c +++ b/librt/mq_timedsend.c @@ -10,11 +10,15 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedsend_time64) #define __NR___mq_timedsend_nocancel __NR_mq_timedsend_time64 +int _NC(mq_timedsend)(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
unsigned int msq_prio, const struct timespec *abs_timeout)
+{
return INLINE_SYSCALL(mq_timedsend_time64, 5, mqdes, msg_ptr,
msg_len, msq_prio, abs_timeout ? TO_TS64_P(abs_timeout) : 0);
+} #else #define __NR___mq_timedsend_nocancel __NR_mq_timedsend +_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr,
size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout)
#endif
-_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr,
size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout)
CANCELLABLE_SYSCALL(int, mq_timedsend, (mqd_t mqdes, const char
*msg_ptr, size_t msq_len, unsigned int msq_prio, const struct timespec *abs_timeout),
(mqdes, msg_ptr, msq_len, msq_prio, abs_timeout))
lt_libc_hidden(mq_timedsend) diff --git a/librt/timer_settime.c b/librt/timer_settime.c index 022880297..6bf5f8307 100644 --- a/librt/timer_settime.c +++ b/librt/timer_settime.c @@ -12,10 +12,14 @@ #if defined(__NR_timer_settime) || defined(__NR_timer_settime64)
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) -#define __NR___syscall_timer_settime __NR_timer_settime64 +int timer_settime(timer_t timerid, int flags, const struct itimerspec
*value, struct itimerspec *ovalue)
+{
struct timer *kt = (struct timer *)timerid;
return INLINE_SYSCALL(timer_settime64, 4, kt->ktimerid, flags,
value ? TO_ITS64_P(value) : 0, ovalue);
+} #else #define __NR___syscall_timer_settime __NR_timer_settime -#endif
static __inline__ _syscall4(int, __syscall_timer_settime,
kernel_timer_t, ktimerid,
int, flags, const void *, value, void *, ovalue);
@@ -31,3 +35,4 @@ int timer_settime(timer_t timerid, int flags, const
struct itimerspec *value,
}
#endif
+#endif
2.43.2
devel mailing list -- devel@uclibc-ng.org To unsubscribe send an email to devel-leave@uclibc-ng.org
-- Thanks. -- Max
On Sat, Feb 24, 2024 at 11:25 AM Dmitriy Chestnykh dm.chestnykh@gmail.com wrote:
What name should we use instead of __ts? I suggest ____uclibc_ts_internal, it starts with four underscores, so it seems to be okay. As another option we can put these macroses inside some private header.
__ts looks good to me, it's the TO_TS64_P and TO_ITS64_P that don't look right. They are not a part of the libc interface, so I'd say they just shouldn't be in that header, but in some other, internal-use-only header instead. If there's no other place for them they should have at least the leading underscore.
Okay, I will move these marcoses to some internal header
сб, 24 февр. 2024 г., 22:40 Max Filippov jcmvbkbc@gmail.com:
On Sat, Feb 24, 2024 at 11:25 AM Dmitriy Chestnykh dm.chestnykh@gmail.com wrote:
What name should we use instead of __ts? I suggest
____uclibc_ts_internal, it starts with four underscores, so it seems to be okay. As another option we can put these macroses inside some private header.
__ts looks good to me, it's the TO_TS64_P and TO_ITS64_P that don't look right. They are not a part of the libc interface, so I'd say they just shouldn't be in that header, but in some other, internal-use-only header instead. If there's no other place for them they should have at least the leading underscore.
-- Thanks. -- Max
On Sat, Feb 24, 2024 at 11:43 AM Dmitriy Chestnykh dm.chestnykh@gmail.com wrote:
Okay, I will move these marcoses to some internal header
If you find such place then I guess struct __ts64_struct and struct __its64_struct can go there as well as they're only used internally.
For BE architectures there is one significant difference in comparison with time64 support for little-endian architectures like ARMv7. The difference is that we strictly need to pass two 64bit values to system calls because Linux Kernel internally uses `struct __kernel_timespec` and similar, which consists of two 64bit fields. For this reason many files have been changed to convert pointers to timespec-family structures (mixed of 64bit and 32bit values) to the pointer of the similar but 64bit-only structures for using as system calls args. This is general prerequisite for any BE architecture.
Signed-off-by: Dmitry Chestnykh dm.chestnykh@gmail.com --- include/time.h | 27 +++++++++++++++++++ libc/inet/socketcalls.c | 2 +- libc/misc/sysvipc/sem.c | 6 ++++- libc/signal/sigwait.c | 3 ++- libc/sysdeps/linux/common/__rt_sigtimedwait.c | 6 ++--- libc/sysdeps/linux/common/__rt_sigwaitinfo.c | 2 +- libc/sysdeps/linux/common/alarm.c | 2 +- libc/sysdeps/linux/common/clock_getres.c | 13 +++++++-- libc/sysdeps/linux/common/clock_gettime.c | 12 ++++++++- libc/sysdeps/linux/common/clock_settime.c | 5 +++- libc/sysdeps/linux/common/ppoll.c | 2 +- libc/sysdeps/linux/common/pselect.c | 2 +- libc/sysdeps/linux/common/select.c | 12 ++++++--- libc/sysdeps/linux/common/time.c | 2 +- libc/sysdeps/linux/common/timerfd.c | 5 +++- libc/sysdeps/linux/common/utimensat.c | 16 ++++++++++- libpthread/nptl/pthread_mutex_timedlock.c | 2 +- .../sysdeps/unix/sysv/linux/lowlevellock.c | 5 ++-- .../sysdeps/unix/sysv/linux/lowlevellock.h | 27 +++++++++++++++++-- .../unix/sysv/linux/lowlevelrobustlock.c | 1 - .../sysdeps/unix/sysv/linux/timer_settime.c | 2 +- librt/clock_gettime.c | 11 ++++++-- librt/clock_nanosleep.c | 5 ++-- librt/mq_timedreceive.c | 8 +++--- librt/mq_timedsend.c | 6 ++++- librt/timer_settime.c | 9 +++++-- 26 files changed, 154 insertions(+), 39 deletions(-)
diff --git a/include/time.h b/include/time.h index 1a1408990..880a80d85 100644 --- a/include/time.h +++ b/include/time.h @@ -122,6 +122,16 @@ struct timespec long int tv_nsec; /* Nanoseconds. */ };
+#if defined(__UCLIBC_USE_TIME64__) + +struct __ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; + +#define TO_TS64_P(__ts) (&(struct __ts64_struct) {.tv_sec = (__ts)->tv_sec, .tv_nsec = (__ts)->tv_nsec}) +#endif + #endif /* timespec not defined and <time.h> or need timespec. */ #undef __need_timespec
@@ -165,6 +175,23 @@ struct itimerspec struct timespec it_value; };
+#if defined(__UCLIBC_USE_TIME64__) + +struct __its64_struct { + __S64_TYPE interval_tv_sec; + __S64_TYPE interval_tv_nsec; + __S64_TYPE value_tv_sec; + __S64_TYPE value_tv_nsec; +}; + +#define TO_ITS64_P(__its) (&(struct __its64_struct) {.interval_tv_sec = (__its)->it_interval.tv_sec, \ + .interval_tv_nsec = (__its)->it_interval.tv_nsec, \ + .value_tv_sec = (__its)->it_value.tv_sec, \ + .value_tv_nsec = (__its)->it_value.tv_nsec}) + +#endif + + /* We can use a simple forward declaration. */ struct sigevent;
diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c index eb0983698..ea623878a 100644 --- a/libc/inet/socketcalls.c +++ b/libc/inet/socketcalls.c @@ -273,7 +273,7 @@ static ssize_t __NC(recvmmsg)(int sockfd, struct mmsghdr *msg, size_t vlen, int flags, struct timespec *tmo) { # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_recvmmsg_time64) - return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo); + return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo ? TO_TS64_P(tmo) : 0); # elif defined(__NR_recvmmsg) return (ssize_t)INLINE_SYSCALL(recvmmsg, 5, sockfd, msg, vlen, flags, tmo); # elif __NR_socketcall diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c index cd541761c..48d345984 100644 --- a/libc/misc/sysvipc/sem.c +++ b/libc/misc/sysvipc/sem.c @@ -96,7 +96,11 @@ int semop (int semid, struct sembuf *sops, size_t nsops) #ifdef L_semtimedop
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_semtimedop_time64) -_syscall4_time64(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout) +int semtimedop(int semid, struct sembuf *sops, size_t nsops, const struct timespec *timeout) +{ + return INLINE_SYSCALL(semtimedop_time64, 4, semid, sops, nsops, timeout ? TO_TS64_P(timeout) : 0); +} + #elif defined(__NR_semtimedop) _syscall4(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout)
diff --git a/libc/signal/sigwait.c b/libc/signal/sigwait.c index 3557a039e..b237534cd 100644 --- a/libc/signal/sigwait.c +++ b/libc/signal/sigwait.c @@ -24,7 +24,8 @@ #include <signal.h> #include <cancel.h>
-#if defined __NR_rt_sigtimedwait && defined __UCLIBC_HAS_REALTIME__ +#if (defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64))) && \ + defined(__UCLIBC_HAS_REALTIME__)
#include <string.h>
diff --git a/libc/sysdeps/linux/common/__rt_sigtimedwait.c b/libc/sysdeps/linux/common/__rt_sigtimedwait.c index bd82ca6d5..44e1ce928 100644 --- a/libc/sysdeps/linux/common/__rt_sigtimedwait.c +++ b/libc/sysdeps/linux/common/__rt_sigtimedwait.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__NR_rt_sigtimedwait_time64) && defined(__UCLIBC_USE_TIME64__)) # include <signal.h> # include <cancel.h> # ifdef __UCLIBC_HAS_THREADS_NATIVE__ @@ -54,7 +54,7 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64) result = INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info, - timeout, __SYSCALL_SIGSET_T_SIZE); + timeout ? TO_TS64_P(timeout) : 0, __SYSCALL_SIGSET_T_SIZE); # else result = INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); @@ -72,7 +72,7 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64) return INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info, - timeout, __SYSCALL_SIGSET_T_SIZE); + timeout ? TO_TS64_P(timeout) : 0, __SYSCALL_SIGSET_T_SIZE); # else return INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); diff --git a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c index d2d176a64..7830b2e2c 100644 --- a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c +++ b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)) # define __need_NULL # include <stddef.h> # include <signal.h> diff --git a/libc/sysdeps/linux/common/alarm.c b/libc/sysdeps/linux/common/alarm.c index 4e6e2215b..861f6ad8e 100644 --- a/libc/sysdeps/linux/common/alarm.c +++ b/libc/sysdeps/linux/common/alarm.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <unistd.h>
-#ifdef __NR_alarm && !defined(__UCLIBC_USE_TIME64__) +#if defined(__NR_alarm) && !defined(__UCLIBC_USE_TIME64__) _syscall1(unsigned int, alarm, unsigned int, seconds) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/clock_getres.c b/libc/sysdeps/linux/common/clock_getres.c index d4b989958..c1818f9ce 100644 --- a/libc/sysdeps/linux/common/clock_getres.c +++ b/libc/sysdeps/linux/common/clock_getres.c @@ -10,9 +10,18 @@ #include <sys/syscall.h> #include <time.h>
- #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64) -_syscall2_time64(int, clock_getres, clockid_t, clock_id, struct timespec*, res) +int clock_getres(clockid_t clock_id, struct timespec *res) +{ + struct __ts64_struct __ts64; + int __ret = INLINE_SYSCALL(clock_getres_time64, 2, clock_id, &__ts64); + if (__ret == 0 && res) { + res->tv_sec = __ts64.tv_sec; + res->tv_nsec = __ts64.tv_nsec; + }; + + return __ret; +} #elif defined(__NR_clock_getres) _syscall2(int, clock_getres, clockid_t, clock_id, struct timespec*, res) #else diff --git a/libc/sysdeps/linux/common/clock_gettime.c b/libc/sysdeps/linux/common/clock_gettime.c index a595bd691..00212a9ef 100644 --- a/libc/sysdeps/linux/common/clock_gettime.c +++ b/libc/sysdeps/linux/common/clock_gettime.c @@ -12,7 +12,17 @@ #include <time.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) -_syscall2_64(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) +int clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + struct __ts64_struct __ts64; + int __ret = INLINE_SYSCALL(clock_gettime64, 2, clock_id, &__ts64); + if (tp) { + tp->tv_sec = __ts64.tv_sec; + tp->tv_nsec = __ts64.tv_nsec; + } + + return __ret; +} #elif defined(__NR_clock_gettime) _syscall2(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/clock_settime.c b/libc/sysdeps/linux/common/clock_settime.c index 89550af5a..666ae4075 100644 --- a/libc/sysdeps/linux/common/clock_settime.c +++ b/libc/sysdeps/linux/common/clock_settime.c @@ -12,7 +12,10 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_settime64) -_syscall2_64(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) +int clock_settime(clockid_t clock_id, const struct timespec *tp) +{ + return INLINE_SYSCALL(clock_settime64, 2, clock_id, tp ? TO_TS64_P(tp) : 0); +} #elif defined(__NR_clock_settime) _syscall2(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/ppoll.c b/libc/sysdeps/linux/common/ppoll.c index cb36149c5..3b98a2760 100644 --- a/libc/sysdeps/linux/common/ppoll.c +++ b/libc/sysdeps/linux/common/ppoll.c @@ -38,7 +38,7 @@ __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, timeout = &tval; } #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_ppoll_time64) - return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE); + return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout ? TO_TS64_P(timeout) : 0, sigmask, __SYSCALL_SIGSET_T_SIZE); #else return INLINE_SYSCALL(ppoll, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE); #endif diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c index 23bdab5cf..3ceb51012 100644 --- a/libc/sysdeps/linux/common/pselect.c +++ b/libc/sysdeps/linux/common/pselect.c @@ -57,7 +57,7 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, sigmask = (void *)&data; } #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64) - return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask); + return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout ? TO_TS64_P(timeout) : 0, sigmask); #else return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask); #endif diff --git a/libc/sysdeps/linux/common/select.c b/libc/sysdeps/linux/common/select.c index 3132a109c..05d2b55b2 100644 --- a/libc/sysdeps/linux/common/select.c +++ b/libc/sysdeps/linux/common/select.c @@ -15,7 +15,7 @@ # define __NR_select __NR__newselect #endif
-#if !defined __NR_select && defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) # include <stdint.h> # define USEC_PER_SEC 1000000L #endif @@ -23,9 +23,7 @@ int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { -#ifdef __NR_select - return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, timeout); -#elif defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) struct timespec _ts, *ts = 0; if (timeout) { uint32_t usec; @@ -47,8 +45,14 @@ int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
ts = &_ts; } +#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64) + return INLINE_SYSCALL(pselect6_time64, 6, n, readfds, writefds, exceptfds, ts ? TO_TS64_P(ts) : 0, 0); +#else return INLINE_SYSCALL(pselect6, 6, n, readfds, writefds, exceptfds, ts, 0); #endif +#elif defined(__NR_select) + return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, ts); +#endif } /* we should guard it, but we need it in other files, so let it fail * if we miss any of the syscalls */ diff --git a/libc/sysdeps/linux/common/time.c b/libc/sysdeps/linux/common/time.c index 22403f174..d084ffaad 100644 --- a/libc/sysdeps/linux/common/time.c +++ b/libc/sysdeps/linux/common/time.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <time.h>
-#ifdef __NR_time +#if defined(__NR_time) && !defined(__UCLIBC_USE_TIME64__) _syscall_noerr1(time_t, time, time_t *, t) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/timerfd.c b/libc/sysdeps/linux/common/timerfd.c index 0f19b44ed..07bfb09b7 100644 --- a/libc/sysdeps/linux/common/timerfd.c +++ b/libc/sysdeps/linux/common/timerfd.c @@ -21,7 +21,10 @@ _syscall2(int, timerfd_create, int, clockid, int, flags) */ #if defined(__NR_timerfd_settime) || defined(__NR_timerfd_settime64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timerfd_settime64) -_syscall4_64(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) +int timerfd_settime(int ufd, int flags, const struct itimerspec *utmr, struct itimerspec *otmr) +{ + return INLINE_SYSCALL(timerfd_settime64, 4, ufd, flags, utmr ? TO_ITS64_P(utmr) : 0, otmr); +} #else _syscall4(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) #endif diff --git a/libc/sysdeps/linux/common/utimensat.c b/libc/sysdeps/linux/common/utimensat.c index 6a78ebb4f..339a35559 100644 --- a/libc/sysdeps/linux/common/utimensat.c +++ b/libc/sysdeps/linux/common/utimensat.c @@ -11,7 +11,21 @@
#if defined(__NR_utimensat) || defined(__NR_utimensat_time64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_utimensat_time64) -_syscall4_time64(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) +int utimensat(int fd, const char *path, const struct timespec times[2], int flags) +{ + struct __ts64_struct __times64[2] = { + { + .tv_sec = times ? times[0].tv_sec : 0, + .tv_nsec = times ? times[0].tv_nsec : 0 + }, + { + .tv_sec = times ? times[1].tv_sec : 0, + .tv_nsec = times ? times[1].tv_nsec : 0 + } + }; + + return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ? &__times64 : 0, flags); +} #else _syscall4(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) #endif diff --git a/libpthread/nptl/pthread_mutex_timedlock.c b/libpthread/nptl/pthread_mutex_timedlock.c index 25f9ec3b2..7bb9a0aaf 100644 --- a/libpthread/nptl/pthread_mutex_timedlock.c +++ b/libpthread/nptl/pthread_mutex_timedlock.c @@ -268,7 +268,7 @@ pthread_mutex_timedlock ( int e = INTERNAL_SYSCALL (futex_time64, __err, 4, &mutex->__data.__lock, __lll_private_flag (FUTEX_LOCK_PI, private), 1, - abstime); + abstime ? TO_TS64_P(abstime) : 0); #else int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock, __lll_private_flag (FUTEX_LOCK_PI, diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c index 4294a20b0..e168b3925 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c @@ -95,7 +95,7 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime) while ((tid = *tidp) != 0) { struct timeval tv; - struct timespec rt; + struct timespec rt, *rtp;
/* Get the current time. */ (void) __gettimeofday (&tv, NULL); @@ -115,7 +115,8 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime)
/* Wait until thread terminates. The kernel so far does not use the private futex operations for this. */ - if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) == -ETIMEDOUT) + rtp = &rt; + if (lll_futex_timed_wait (tidp, tid, rtp, LLL_SHARED) == -ETIMEDOUT) return ETIMEDOUT; }
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h index e72fe5234..909b0aad3 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h @@ -71,8 +71,31 @@ # endif #endif
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64) + #define lll_futex_wait(futexp, val, private) \ - lll_futex_timed_wait(futexp, val, NULL, private) + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAIT, private), \ + (val), NULL); \ + __ret; \ + }) + +#else + +#define lll_futex_wait(futexp, val, private) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAIT, private), \ + (val), NULL); \ + __ret; \ + }) + +#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
@@ -82,7 +105,7 @@ long int __ret; \ __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \ __lll_private_flag (FUTEX_WAIT, private), \ - (val), (timespec)); \ + (val), (TO_TS64_P(timespec))); \ __ret; \ })
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c index 7b4e84343..6403f7ea0 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c @@ -99,7 +99,6 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime, if (oldval != newval && atomic_compare_and_exchange_bool_acq (futex, newval, oldval)) continue; - lll_futex_timed_wait (futex, newval, &rt, private);
try: diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c index 80d242f21..4fa600cb6 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c @@ -56,7 +56,7 @@ timer_settime ( /* Delete the kernel timer object. */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) int res = INLINE_SYSCALL (timer_settime64, 4, kt->ktimerid, flags, - value, ovalue); + value ? TO_ITS64_P(value) : 0, ovalue); # else int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags, value, ovalue); diff --git a/librt/clock_gettime.c b/librt/clock_gettime.c index b66b60231..c514e1a54 100644 --- a/librt/clock_gettime.c +++ b/librt/clock_gettime.c @@ -24,8 +24,15 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) #define SYSCALL_GETTIME \ - retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, tp); \ - break + { \ + struct __ts64_struct __ts64; \ + retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, &__ts64); \ + if (tp) { \ + tp->tv_sec = __ts64.tv_sec; \ + tp->tv_nsec = __ts64.tv_nsec; \ + } \ + break; \ + } #else #define SYSCALL_GETTIME \ retval = INLINE_SYSCALL (clock_gettime, 2, clock_id, tp); \ diff --git a/librt/clock_nanosleep.c b/librt/clock_nanosleep.c index eaae75720..cb7b2afa3 100644 --- a/librt/clock_nanosleep.c +++ b/librt/clock_nanosleep.c @@ -21,7 +21,6 @@
#include "kernel-posix-cpu-timers.h"
- /* We can simply use the syscall. The CPU clocks are not supported with this function. */ int @@ -38,7 +37,7 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
if (SINGLE_THREAD_P) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64) - r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem); + r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req ? TO_TS64_P(req) : 0, rem); #else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); #endif @@ -47,7 +46,7 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, #ifdef __NEW_THREADS int oldstate = LIBC_CANCEL_ASYNC (); #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64) - r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem); + r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req ? TO_TS64_P(req): 0, rem); #else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); diff --git a/librt/mq_timedreceive.c b/librt/mq_timedreceive.c index db1ae1aa8..2570b6f9e 100644 --- a/librt/mq_timedreceive.c +++ b/librt/mq_timedreceive.c @@ -9,12 +9,14 @@ #include <cancel.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedreceive_time64) -#define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive_time64 +int _NC(mq_timedreceive)(mqd_t mqdes, char *restrict msg_ptr, size_t msg_len, unsigned int *restrict msq_prio, const struct timespec *restrict abs_timeout) +{ + return INLINE_SYSCALL(mq_timedreceive_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, abs_timeout ? TO_TS64_P(abs_timeout) : 0); +} #else #define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive -#endif - _syscall5(ssize_t, __NC(mq_timedreceive), mqd_t, mqdes, char *__restrict, msg_ptr, size_t, msg_len, unsigned int *__restrict, msq_prio, const struct timespec *__restrict, abs_timeout) +#endif
CANCELLABLE_SYSCALL(ssize_t, mq_timedreceive, (mqd_t mqdes, char *__restrict msg_ptr, size_t msq_len, unsigned int *__restrict msq_prio, const struct timespec *__restrict abs_timeout), (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) diff --git a/librt/mq_timedsend.c b/librt/mq_timedsend.c index 6afaf5157..bcbc0685f 100644 --- a/librt/mq_timedsend.c +++ b/librt/mq_timedsend.c @@ -10,11 +10,15 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedsend_time64) #define __NR___mq_timedsend_nocancel __NR_mq_timedsend_time64 +int _NC(mq_timedsend)(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msq_prio, const struct timespec *abs_timeout) +{ + return INLINE_SYSCALL(mq_timedsend_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, abs_timeout ? TO_TS64_P(abs_timeout) : 0); +} #else #define __NR___mq_timedsend_nocancel __NR_mq_timedsend +_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) #endif
-_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) CANCELLABLE_SYSCALL(int, mq_timedsend, (mqd_t mqdes, const char *msg_ptr, size_t msq_len, unsigned int msq_prio, const struct timespec *abs_timeout), (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) lt_libc_hidden(mq_timedsend) diff --git a/librt/timer_settime.c b/librt/timer_settime.c index 022880297..6bf5f8307 100644 --- a/librt/timer_settime.c +++ b/librt/timer_settime.c @@ -12,10 +12,14 @@ #if defined(__NR_timer_settime) || defined(__NR_timer_settime64)
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) -#define __NR___syscall_timer_settime __NR_timer_settime64 +int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue) +{ + struct timer *kt = (struct timer *)timerid; + + return INLINE_SYSCALL(timer_settime64, 4, kt->ktimerid, flags, value ? TO_ITS64_P(value) : 0, ovalue); +} #else #define __NR___syscall_timer_settime __NR_timer_settime -#endif
static __inline__ _syscall4(int, __syscall_timer_settime, kernel_timer_t, ktimerid, int, flags, const void *, value, void *, ovalue); @@ -31,3 +35,4 @@ int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, }
#endif +#endif
For BE architectures there is one significant difference in comparison with time64 support for little-endian architectures like ARMv7. The difference is that we strictly need to pass two 64bit values to system calls because Linux Kernel internally uses `struct __kernel_timespec` and similar, which consists of two 64bit fields. For this reason many files have been changed to convert pointers to timespec-family structures (mixed of 64bit and 32bit values) to the pointer of the similar but 64bit-only structures for using as system calls args. This is general prerequisite for any BE architecture.
Signed-off-by: Dmitry Chestnykh dm.chestnykh@gmail.com --- Moved __ts64_struct, __its64_struct and related macroses to the new private header, did some cleanups. include/internal/time64_helpers.h | 27 ++++++++++++++++ libc/inet/socketcalls.c | 6 +++- libc/misc/sysvipc/sem.c | 9 +++++- libc/signal/sigwait.c | 3 +- libc/sysdeps/linux/common/__rt_sigtimedwait.c | 10 ++++-- libc/sysdeps/linux/common/__rt_sigwaitinfo.c | 2 +- libc/sysdeps/linux/common/alarm.c | 2 +- libc/sysdeps/linux/common/clock_getres.c | 15 +++++++-- libc/sysdeps/linux/common/clock_gettime.c | 14 ++++++++- libc/sysdeps/linux/common/clock_settime.c | 7 ++++- libc/sysdeps/linux/common/ppoll.c | 6 +++- libc/sysdeps/linux/common/pselect.c | 6 +++- libc/sysdeps/linux/common/select.c | 16 +++++++--- libc/sysdeps/linux/common/time.c | 2 +- libc/sysdeps/linux/common/timerfd.c | 9 +++++- libc/sysdeps/linux/common/utimensat.c | 20 +++++++++++- libpthread/nptl/pthread_mutex_timedlock.c | 6 +++- .../sysdeps/unix/sysv/linux/lowlevellock.h | 31 +++++++++++++++++-- .../sysdeps/unix/sysv/linux/timer_settime.c | 5 ++- librt/clock_gettime.c | 17 ++++++++-- librt/clock_nanosleep.c | 7 +++-- librt/mq_timedreceive.c | 10 ++++-- librt/mq_timedsend.c | 9 ++++-- librt/timer_settime.c | 11 +++++-- 24 files changed, 213 insertions(+), 37 deletions(-) create mode 100644 include/internal/time64_helpers.h
diff --git a/include/internal/time64_helpers.h b/include/internal/time64_helpers.h new file mode 100644 index 000000000..897874fb3 --- /dev/null +++ b/include/internal/time64_helpers.h @@ -0,0 +1,27 @@ +#ifndef _TIME64_HELPERS_H +#define _TIME64_HELPERS_H + +#include <bits/types.h> +#include <stddef.h> + +struct __ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; + +#define TO_TS64_P(__ts) ((__ts) ? (&(struct __ts64_struct) {.tv_sec = (__ts)->tv_sec, .tv_nsec = (__ts)->tv_nsec}) : NULL) + +struct __its64_struct { + __S64_TYPE interval_tv_sec; + __S64_TYPE interval_tv_nsec; + __S64_TYPE value_tv_sec; + __S64_TYPE value_tv_nsec; +}; + +#define TO_ITS64_P(__its) ((__its) ? (&(struct __its64_struct) {.interval_tv_sec = (__its)->it_interval.tv_sec, \ + .interval_tv_nsec = (__its)->it_interval.tv_nsec, \ + .value_tv_sec = (__its)->it_value.tv_sec, \ + .value_tv_nsec = (__its)->it_value.tv_nsec}) : NULL) + + +#endif /* _TIME64_HELPERS_H */ \ No newline at end of file diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c index eb0983698..774ed6091 100644 --- a/libc/inet/socketcalls.c +++ b/libc/inet/socketcalls.c @@ -10,6 +10,10 @@ #include <cancel.h> #include <bits/kernel-features.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + #ifdef __NR_socketcall /* Various socketcall numbers */ #define SYS_SOCKET 1 @@ -273,7 +277,7 @@ static ssize_t __NC(recvmmsg)(int sockfd, struct mmsghdr *msg, size_t vlen, int flags, struct timespec *tmo) { # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_recvmmsg_time64) - return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo); + return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, TO_TS64_P(tmo)); # elif defined(__NR_recvmmsg) return (ssize_t)INLINE_SYSCALL(recvmmsg, 5, sockfd, msg, vlen, flags, tmo); # elif __NR_socketcall diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c index cd541761c..07076eff7 100644 --- a/libc/misc/sysvipc/sem.c +++ b/libc/misc/sysvipc/sem.c @@ -23,6 +23,9 @@
#include "ipc.h"
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif
#ifdef L_semctl /* Return identifier for array of NSEMS semaphores associated with @@ -96,7 +99,11 @@ int semop (int semid, struct sembuf *sops, size_t nsops) #ifdef L_semtimedop
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_semtimedop_time64) -_syscall4_time64(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout) +int semtimedop(int semid, struct sembuf *sops, size_t nsops, const struct timespec *timeout) +{ + return INLINE_SYSCALL(semtimedop_time64, 4, semid, sops, nsops, TO_TS64_P(timeout)); +} + #elif defined(__NR_semtimedop) _syscall4(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout)
diff --git a/libc/signal/sigwait.c b/libc/signal/sigwait.c index 3557a039e..b237534cd 100644 --- a/libc/signal/sigwait.c +++ b/libc/signal/sigwait.c @@ -24,7 +24,8 @@ #include <signal.h> #include <cancel.h>
-#if defined __NR_rt_sigtimedwait && defined __UCLIBC_HAS_REALTIME__ +#if (defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64))) && \ + defined(__UCLIBC_HAS_REALTIME__)
#include <string.h>
diff --git a/libc/sysdeps/linux/common/__rt_sigtimedwait.c b/libc/sysdeps/linux/common/__rt_sigtimedwait.c index bd82ca6d5..aff5299a1 100644 --- a/libc/sysdeps/linux/common/__rt_sigtimedwait.c +++ b/libc/sysdeps/linux/common/__rt_sigtimedwait.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__NR_rt_sigtimedwait_time64) && defined(__UCLIBC_USE_TIME64__)) # include <signal.h> # include <cancel.h> # ifdef __UCLIBC_HAS_THREADS_NATIVE__ @@ -21,6 +21,10 @@ # include <string.h> # endif
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, const struct timespec *timeout) { @@ -54,7 +58,7 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64) result = INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info, - timeout, __SYSCALL_SIGSET_T_SIZE); + TO_TS64_P(timeout), __SYSCALL_SIGSET_T_SIZE); # else result = INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); @@ -72,7 +76,7 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64) return INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info, - timeout, __SYSCALL_SIGSET_T_SIZE); + TO_TS64_P(timeout), __SYSCALL_SIGSET_T_SIZE); # else return INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); diff --git a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c index d2d176a64..7830b2e2c 100644 --- a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c +++ b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)) # define __need_NULL # include <stddef.h> # include <signal.h> diff --git a/libc/sysdeps/linux/common/alarm.c b/libc/sysdeps/linux/common/alarm.c index 4e6e2215b..861f6ad8e 100644 --- a/libc/sysdeps/linux/common/alarm.c +++ b/libc/sysdeps/linux/common/alarm.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <unistd.h>
-#ifdef __NR_alarm && !defined(__UCLIBC_USE_TIME64__) +#if defined(__NR_alarm) && !defined(__UCLIBC_USE_TIME64__) _syscall1(unsigned int, alarm, unsigned int, seconds) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/clock_getres.c b/libc/sysdeps/linux/common/clock_getres.c index d4b989958..fd0f8c14c 100644 --- a/libc/sysdeps/linux/common/clock_getres.c +++ b/libc/sysdeps/linux/common/clock_getres.c @@ -10,9 +10,20 @@ #include <sys/syscall.h> #include <time.h>
- #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64) -_syscall2_time64(int, clock_getres, clockid_t, clock_id, struct timespec*, res) +#include "internal/time64_helpers.h" + +int clock_getres(clockid_t clock_id, struct timespec *res) +{ + struct __ts64_struct __ts64; + int __ret = INLINE_SYSCALL(clock_getres_time64, 2, clock_id, &__ts64); + if (__ret == 0 && res) { + res->tv_sec = __ts64.tv_sec; + res->tv_nsec = __ts64.tv_nsec; + }; + + return __ret; +} #elif defined(__NR_clock_getres) _syscall2(int, clock_getres, clockid_t, clock_id, struct timespec*, res) #else diff --git a/libc/sysdeps/linux/common/clock_gettime.c b/libc/sysdeps/linux/common/clock_gettime.c index a595bd691..4d787b9b7 100644 --- a/libc/sysdeps/linux/common/clock_gettime.c +++ b/libc/sysdeps/linux/common/clock_gettime.c @@ -12,7 +12,19 @@ #include <time.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) -_syscall2_64(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) +#include "internal/time64_helpers.h" + +int clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + struct __ts64_struct __ts64; + int __ret = INLINE_SYSCALL(clock_gettime64, 2, clock_id, &__ts64); + if (tp) { + tp->tv_sec = __ts64.tv_sec; + tp->tv_nsec = __ts64.tv_nsec; + } + + return __ret; +} #elif defined(__NR_clock_gettime) _syscall2(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/clock_settime.c b/libc/sysdeps/linux/common/clock_settime.c index 89550af5a..3abc5f49b 100644 --- a/libc/sysdeps/linux/common/clock_settime.c +++ b/libc/sysdeps/linux/common/clock_settime.c @@ -12,7 +12,12 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_settime64) -_syscall2_64(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) +#include "internal/time64_helpers.h" + +int clock_settime(clockid_t clock_id, const struct timespec *tp) +{ + return INLINE_SYSCALL(clock_settime64, 2, clock_id, TO_TS64_P(tp)); +} #elif defined(__NR_clock_settime) _syscall2(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/ppoll.c b/libc/sysdeps/linux/common/ppoll.c index cb36149c5..870717bd7 100644 --- a/libc/sysdeps/linux/common/ppoll.c +++ b/libc/sysdeps/linux/common/ppoll.c @@ -26,6 +26,10 @@ #include <sys/poll.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + static int __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, const sigset_t *sigmask) @@ -38,7 +42,7 @@ __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, timeout = &tval; } #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_ppoll_time64) - return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE); + return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, TO_TS64_P(timeout), sigmask, __SYSCALL_SIGSET_T_SIZE); #else return INLINE_SYSCALL(ppoll, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE); #endif diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c index 23bdab5cf..7a446a589 100644 --- a/libc/sysdeps/linux/common/pselect.c +++ b/libc/sysdeps/linux/common/pselect.c @@ -26,6 +26,10 @@ #include <signal.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask) @@ -57,7 +61,7 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, sigmask = (void *)&data; } #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64) - return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask); + return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, TO_TS64_P(timeout), sigmask); #else return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask); #endif diff --git a/libc/sysdeps/linux/common/select.c b/libc/sysdeps/linux/common/select.c index 3132a109c..84016dd0b 100644 --- a/libc/sysdeps/linux/common/select.c +++ b/libc/sysdeps/linux/common/select.c @@ -15,17 +15,19 @@ # define __NR_select __NR__newselect #endif
-#if !defined __NR_select && defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) # include <stdint.h> # define USEC_PER_SEC 1000000L #endif
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { -#ifdef __NR_select - return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, timeout); -#elif defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) struct timespec _ts, *ts = 0; if (timeout) { uint32_t usec; @@ -47,8 +49,14 @@ int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
ts = &_ts; } +#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64) + return INLINE_SYSCALL(pselect6_time64, 6, n, readfds, writefds, exceptfds, TO_TS64_P(ts), 0); +#else return INLINE_SYSCALL(pselect6, 6, n, readfds, writefds, exceptfds, ts, 0); #endif +#elif defined(__NR_select) + return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, ts); +#endif } /* we should guard it, but we need it in other files, so let it fail * if we miss any of the syscalls */ diff --git a/libc/sysdeps/linux/common/time.c b/libc/sysdeps/linux/common/time.c index 22403f174..d084ffaad 100644 --- a/libc/sysdeps/linux/common/time.c +++ b/libc/sysdeps/linux/common/time.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <time.h>
-#ifdef __NR_time +#if defined(__NR_time) && !defined(__UCLIBC_USE_TIME64__) _syscall_noerr1(time_t, time, time_t *, t) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/timerfd.c b/libc/sysdeps/linux/common/timerfd.c index 0f19b44ed..b4a9e1a93 100644 --- a/libc/sysdeps/linux/common/timerfd.c +++ b/libc/sysdeps/linux/common/timerfd.c @@ -9,6 +9,10 @@ #include <sys/syscall.h> #include <sys/timerfd.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + /* * timerfd_create() */ @@ -21,7 +25,10 @@ _syscall2(int, timerfd_create, int, clockid, int, flags) */ #if defined(__NR_timerfd_settime) || defined(__NR_timerfd_settime64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timerfd_settime64) -_syscall4_64(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) +int timerfd_settime(int ufd, int flags, const struct itimerspec *utmr, struct itimerspec *otmr) +{ + return INLINE_SYSCALL(timerfd_settime64, 4, ufd, flags, TO_ITS64_P(utmr), otmr); +} #else _syscall4(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) #endif diff --git a/libc/sysdeps/linux/common/utimensat.c b/libc/sysdeps/linux/common/utimensat.c index 6a78ebb4f..fa6f90e55 100644 --- a/libc/sysdeps/linux/common/utimensat.c +++ b/libc/sysdeps/linux/common/utimensat.c @@ -9,9 +9,27 @@ #include <sys/syscall.h> #include <sys/stat.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + #if defined(__NR_utimensat) || defined(__NR_utimensat_time64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_utimensat_time64) -_syscall4_time64(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) +int utimensat(int fd, const char *path, const struct timespec times[2], int flags) +{ + struct __ts64_struct __times64[2] = { + { + .tv_sec = times ? times[0].tv_sec : 0, + .tv_nsec = times ? times[0].tv_nsec : 0 + }, + { + .tv_sec = times ? times[1].tv_sec : 0, + .tv_nsec = times ? times[1].tv_nsec : 0 + } + }; + + return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ? &__times64 : 0, flags); +} #else _syscall4(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) #endif diff --git a/libpthread/nptl/pthread_mutex_timedlock.c b/libpthread/nptl/pthread_mutex_timedlock.c index 25f9ec3b2..446275e67 100644 --- a/libpthread/nptl/pthread_mutex_timedlock.c +++ b/libpthread/nptl/pthread_mutex_timedlock.c @@ -23,6 +23,10 @@ #include <lowlevellock.h> #include <not-cancel.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + /* We need to build this function with optimization to avoid * lll_timedlock erroring out with * error: can't find a register in class ‘GENERAL_REGS’ while reloading ‘asm’ @@ -268,7 +272,7 @@ pthread_mutex_timedlock ( int e = INTERNAL_SYSCALL (futex_time64, __err, 4, &mutex->__data.__lock, __lll_private_flag (FUTEX_LOCK_PI, private), 1, - abstime); + abstime ? TO_TS64_P(abstime) : 0); #else int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock, __lll_private_flag (FUTEX_LOCK_PI, diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h index e72fe5234..86941b1f2 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h @@ -24,6 +24,10 @@ #include <sysdep.h> #include <bits/kernel-features.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + #define FUTEX_WAIT 0 #define FUTEX_WAKE 1 #define FUTEX_REQUEUE 3 @@ -71,8 +75,31 @@ # endif #endif
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64) + #define lll_futex_wait(futexp, val, private) \ - lll_futex_timed_wait(futexp, val, NULL, private) + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAIT, private), \ + (val), NULL); \ + __ret; \ + }) + +#else + +#define lll_futex_wait(futexp, val, private) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAIT, private), \ + (val), NULL); \ + __ret; \ + }) + +#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
@@ -82,7 +109,7 @@ long int __ret; \ __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \ __lll_private_flag (FUTEX_WAIT, private), \ - (val), (timespec)); \ + (val), (TO_TS64_P(timespec))); \ __ret; \ })
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c index 80d242f21..1cccf57cb 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c @@ -23,6 +23,9 @@ #include <bits/kernel-features.h> #include "kernel-posix-timers.h"
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif
#ifdef __NR_timer_settime # ifndef __ASSUME_POSIX_TIMERS @@ -56,7 +59,7 @@ timer_settime ( /* Delete the kernel timer object. */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) int res = INLINE_SYSCALL (timer_settime64, 4, kt->ktimerid, flags, - value, ovalue); + TO_ITS64_P(value), ovalue); # else int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags, value, ovalue); diff --git a/librt/clock_gettime.c b/librt/clock_gettime.c index b66b60231..eab9a3343 100644 --- a/librt/clock_gettime.c +++ b/librt/clock_gettime.c @@ -22,10 +22,21 @@ #include <sys/time.h> #include "kernel-posix-cpu-timers.h"
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) -#define SYSCALL_GETTIME \ - retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, tp); \ - break +#define SYSCALL_GETTIME \ + { \ + struct __ts64_struct __ts64; \ + retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, &__ts64); \ + if (tp) { \ + tp->tv_sec = __ts64.tv_sec; \ + tp->tv_nsec = __ts64.tv_nsec; \ + } \ + break; \ + } #else #define SYSCALL_GETTIME \ retval = INLINE_SYSCALL (clock_gettime, 2, clock_id, tp); \ diff --git a/librt/clock_nanosleep.c b/librt/clock_nanosleep.c index eaae75720..ef59369df 100644 --- a/librt/clock_nanosleep.c +++ b/librt/clock_nanosleep.c @@ -21,6 +21,9 @@
#include "kernel-posix-cpu-timers.h"
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif
/* We can simply use the syscall. The CPU clocks are not supported with this function. */ @@ -38,7 +41,7 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
if (SINGLE_THREAD_P) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64) - r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem); + r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, TO_TS64_P(req), rem); #else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); #endif @@ -47,7 +50,7 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, #ifdef __NEW_THREADS int oldstate = LIBC_CANCEL_ASYNC (); #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64) - r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem); + r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, TO_TS64_P(req), rem); #else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); diff --git a/librt/mq_timedreceive.c b/librt/mq_timedreceive.c index db1ae1aa8..f89b4c36b 100644 --- a/librt/mq_timedreceive.c +++ b/librt/mq_timedreceive.c @@ -9,12 +9,16 @@ #include <cancel.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedreceive_time64) -#define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive_time64 +#include "internal/time64_helpers.h" + +int _NC(mq_timedreceive)(mqd_t mqdes, char *restrict msg_ptr, size_t msg_len, unsigned int *restrict msq_prio, const struct timespec *restrict abs_timeout) +{ + return INLINE_SYSCALL(mq_timedreceive_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, TO_TS64_P(abs_timeout)); +} #else #define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive -#endif - _syscall5(ssize_t, __NC(mq_timedreceive), mqd_t, mqdes, char *__restrict, msg_ptr, size_t, msg_len, unsigned int *__restrict, msq_prio, const struct timespec *__restrict, abs_timeout) +#endif
CANCELLABLE_SYSCALL(ssize_t, mq_timedreceive, (mqd_t mqdes, char *__restrict msg_ptr, size_t msq_len, unsigned int *__restrict msq_prio, const struct timespec *__restrict abs_timeout), (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) diff --git a/librt/mq_timedsend.c b/librt/mq_timedsend.c index 6afaf5157..b081ac0ce 100644 --- a/librt/mq_timedsend.c +++ b/librt/mq_timedsend.c @@ -9,12 +9,17 @@ #include <cancel.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedsend_time64) -#define __NR___mq_timedsend_nocancel __NR_mq_timedsend_time64 +#include "internal/time64_helpers.h" + +int _NC(mq_timedsend)(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msq_prio, const struct timespec *abs_timeout) +{ + return INLINE_SYSCALL(mq_timedsend_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, TO_TS64_P(abs_timeout)); +} #else #define __NR___mq_timedsend_nocancel __NR_mq_timedsend +_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) #endif
-_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) CANCELLABLE_SYSCALL(int, mq_timedsend, (mqd_t mqdes, const char *msg_ptr, size_t msq_len, unsigned int msq_prio, const struct timespec *abs_timeout), (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) lt_libc_hidden(mq_timedsend) diff --git a/librt/timer_settime.c b/librt/timer_settime.c index 022880297..425cd7ee9 100644 --- a/librt/timer_settime.c +++ b/librt/timer_settime.c @@ -12,10 +12,16 @@ #if defined(__NR_timer_settime) || defined(__NR_timer_settime64)
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) -#define __NR___syscall_timer_settime __NR_timer_settime64 +#include "internal/time64_helpers.h" + +int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue) +{ + struct timer *kt = (struct timer *)timerid; + + return INLINE_SYSCALL(timer_settime64, 4, kt->ktimerid, flags, TO_ITS64_P(value), ovalue); +} #else #define __NR___syscall_timer_settime __NR_timer_settime -#endif
static __inline__ _syscall4(int, __syscall_timer_settime, kernel_timer_t, ktimerid, int, flags, const void *, value, void *, ovalue); @@ -31,3 +37,4 @@ int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, }
#endif +#endif
On Sat, Feb 24, 2024 at 9:59 PM Dmitry Chestnykh dm.chestnykh@gmail.com wrote:
For BE architectures there is one significant difference in comparison with time64 support for little-endian architectures like ARMv7. The difference is that we strictly need to pass two 64bit values to system calls because Linux Kernel internally uses `struct __kernel_timespec` and similar, which consists of two 64bit fields. For this reason many files have been changed to convert pointers to timespec-family structures (mixed of 64bit and 32bit values) to the pointer of the similar but 64bit-only structures for using as system calls args. This is general prerequisite for any BE architecture.
Signed-off-by: Dmitry Chestnykh dm.chestnykh@gmail.com
Moved __ts64_struct, __its64_struct and related macroses to the new private header, did some cleanups. include/internal/time64_helpers.h | 27 ++++++++++++++++ libc/inet/socketcalls.c | 6 +++- libc/misc/sysvipc/sem.c | 9 +++++- libc/signal/sigwait.c | 3 +- libc/sysdeps/linux/common/__rt_sigtimedwait.c | 10 ++++-- libc/sysdeps/linux/common/__rt_sigwaitinfo.c | 2 +- libc/sysdeps/linux/common/alarm.c | 2 +- libc/sysdeps/linux/common/clock_getres.c | 15 +++++++-- libc/sysdeps/linux/common/clock_gettime.c | 14 ++++++++- libc/sysdeps/linux/common/clock_settime.c | 7 ++++- libc/sysdeps/linux/common/ppoll.c | 6 +++- libc/sysdeps/linux/common/pselect.c | 6 +++- libc/sysdeps/linux/common/select.c | 16 +++++++--- libc/sysdeps/linux/common/time.c | 2 +- libc/sysdeps/linux/common/timerfd.c | 9 +++++- libc/sysdeps/linux/common/utimensat.c | 20 +++++++++++- libpthread/nptl/pthread_mutex_timedlock.c | 6 +++- .../sysdeps/unix/sysv/linux/lowlevellock.h | 31 +++++++++++++++++-- .../sysdeps/unix/sysv/linux/timer_settime.c | 5 ++- librt/clock_gettime.c | 17 ++++++++-- librt/clock_nanosleep.c | 7 +++-- librt/mq_timedreceive.c | 10 ++++-- librt/mq_timedsend.c | 9 ++++-- librt/timer_settime.c | 11 +++++-- 24 files changed, 213 insertions(+), 37 deletions(-) create mode 100644 include/internal/time64_helpers.h
diff --git a/include/internal/time64_helpers.h b/include/internal/time64_helpers.h new file mode 100644 index 000000000..897874fb3 --- /dev/null +++ b/include/internal/time64_helpers.h @@ -0,0 +1,27 @@ +#ifndef _TIME64_HELPERS_H +#define _TIME64_HELPERS_H
+#include <bits/types.h> +#include <stddef.h>
+struct __ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#define TO_TS64_P(__ts) ((__ts) ? (&(struct __ts64_struct) {.tv_sec = (__ts)->tv_sec, .tv_nsec = (__ts)->tv_nsec}) : NULL)
+struct __its64_struct {
- __S64_TYPE interval_tv_sec;
- __S64_TYPE interval_tv_nsec;
- __S64_TYPE value_tv_sec;
- __S64_TYPE value_tv_nsec;
+};
+#define TO_ITS64_P(__its) ((__its) ? (&(struct __its64_struct) {.interval_tv_sec = (__its)->it_interval.tv_sec, \
.interval_tv_nsec = (__its)->it_interval.tv_nsec, \
.value_tv_sec = (__its)->it_value.tv_sec, \
.value_tv_nsec = (__its)->it_value.tv_nsec}) : NULL)
+#endif /* _TIME64_HELPERS_H */ \ No newline at end of file
Please add one.
diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c index eb0983698..774ed6091 100644 --- a/libc/inet/socketcalls.c +++ b/libc/inet/socketcalls.c @@ -10,6 +10,10 @@ #include <cancel.h> #include <bits/kernel-features.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif
#ifdef __NR_socketcall /* Various socketcall numbers */ #define SYS_SOCKET 1 @@ -273,7 +277,7 @@ static ssize_t __NC(recvmmsg)(int sockfd, struct mmsghdr *msg, size_t vlen, int flags, struct timespec *tmo) { # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_recvmmsg_time64)
return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo);
return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, TO_TS64_P(tmo));
# elif defined(__NR_recvmmsg) return (ssize_t)INLINE_SYSCALL(recvmmsg, 5, sockfd, msg, vlen, flags, tmo); # elif __NR_socketcall diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c index cd541761c..07076eff7 100644 --- a/libc/misc/sysvipc/sem.c +++ b/libc/misc/sysvipc/sem.c @@ -23,6 +23,9 @@
#include "ipc.h"
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif
#ifdef L_semctl /* Return identifier for array of NSEMS semaphores associated with @@ -96,7 +99,11 @@ int semop (int semid, struct sembuf *sops, size_t nsops) #ifdef L_semtimedop
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_semtimedop_time64) -_syscall4_time64(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout) +int semtimedop(int semid, struct sembuf *sops, size_t nsops, const struct timespec *timeout) +{
- return INLINE_SYSCALL(semtimedop_time64, 4, semid, sops, nsops, TO_TS64_P(timeout));
+}
#elif defined(__NR_semtimedop) _syscall4(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout)
diff --git a/libc/signal/sigwait.c b/libc/signal/sigwait.c index 3557a039e..b237534cd 100644 --- a/libc/signal/sigwait.c +++ b/libc/signal/sigwait.c @@ -24,7 +24,8 @@ #include <signal.h> #include <cancel.h>
-#if defined __NR_rt_sigtimedwait && defined __UCLIBC_HAS_REALTIME__ +#if (defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64))) && \
- defined(__UCLIBC_HAS_REALTIME__)
#include <string.h>
diff --git a/libc/sysdeps/linux/common/__rt_sigtimedwait.c b/libc/sysdeps/linux/common/__rt_sigtimedwait.c index bd82ca6d5..aff5299a1 100644 --- a/libc/sysdeps/linux/common/__rt_sigtimedwait.c +++ b/libc/sysdeps/linux/common/__rt_sigtimedwait.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__NR_rt_sigtimedwait_time64) && defined(__UCLIBC_USE_TIME64__)) # include <signal.h> # include <cancel.h> # ifdef __UCLIBC_HAS_THREADS_NATIVE__ @@ -21,6 +21,10 @@ # include <string.h> # endif
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif
int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, const struct timespec *timeout) { @@ -54,7 +58,7 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64) result = INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
timeout, __SYSCALL_SIGSET_T_SIZE);
TO_TS64_P(timeout), __SYSCALL_SIGSET_T_SIZE);
# else result = INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); @@ -72,7 +76,7 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64) return INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
timeout, __SYSCALL_SIGSET_T_SIZE);
TO_TS64_P(timeout), __SYSCALL_SIGSET_T_SIZE);
# else return INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); diff --git a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c index d2d176a64..7830b2e2c 100644 --- a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c +++ b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)) # define __need_NULL # include <stddef.h> # include <signal.h> diff --git a/libc/sysdeps/linux/common/alarm.c b/libc/sysdeps/linux/common/alarm.c index 4e6e2215b..861f6ad8e 100644 --- a/libc/sysdeps/linux/common/alarm.c +++ b/libc/sysdeps/linux/common/alarm.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <unistd.h>
-#ifdef __NR_alarm && !defined(__UCLIBC_USE_TIME64__) +#if defined(__NR_alarm) && !defined(__UCLIBC_USE_TIME64__) _syscall1(unsigned int, alarm, unsigned int, seconds) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/clock_getres.c b/libc/sysdeps/linux/common/clock_getres.c index d4b989958..fd0f8c14c 100644 --- a/libc/sysdeps/linux/common/clock_getres.c +++ b/libc/sysdeps/linux/common/clock_getres.c @@ -10,9 +10,20 @@ #include <sys/syscall.h> #include <time.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64) -_syscall2_time64(int, clock_getres, clockid_t, clock_id, struct timespec*, res) +#include "internal/time64_helpers.h"
+int clock_getres(clockid_t clock_id, struct timespec *res) +{
struct __ts64_struct __ts64;
int __ret = INLINE_SYSCALL(clock_getres_time64, 2, clock_id, &__ts64);
if (__ret == 0 && res) {
res->tv_sec = __ts64.tv_sec;
res->tv_nsec = __ts64.tv_nsec;
};
return __ret;
+} #elif defined(__NR_clock_getres) _syscall2(int, clock_getres, clockid_t, clock_id, struct timespec*, res) #else diff --git a/libc/sysdeps/linux/common/clock_gettime.c b/libc/sysdeps/linux/common/clock_gettime.c index a595bd691..4d787b9b7 100644 --- a/libc/sysdeps/linux/common/clock_gettime.c +++ b/libc/sysdeps/linux/common/clock_gettime.c @@ -12,7 +12,19 @@ #include <time.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) -_syscall2_64(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) +#include "internal/time64_helpers.h"
+int clock_gettime(clockid_t clock_id, struct timespec *tp) +{
struct __ts64_struct __ts64;
int __ret = INLINE_SYSCALL(clock_gettime64, 2, clock_id, &__ts64);
if (tp) {
tp->tv_sec = __ts64.tv_sec;
tp->tv_nsec = __ts64.tv_nsec;
}
return __ret;
+} #elif defined(__NR_clock_gettime) _syscall2(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/clock_settime.c b/libc/sysdeps/linux/common/clock_settime.c index 89550af5a..3abc5f49b 100644 --- a/libc/sysdeps/linux/common/clock_settime.c +++ b/libc/sysdeps/linux/common/clock_settime.c @@ -12,7 +12,12 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_settime64) -_syscall2_64(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) +#include "internal/time64_helpers.h"
+int clock_settime(clockid_t clock_id, const struct timespec *tp) +{
return INLINE_SYSCALL(clock_settime64, 2, clock_id, TO_TS64_P(tp));
+} #elif defined(__NR_clock_settime) _syscall2(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/ppoll.c b/libc/sysdeps/linux/common/ppoll.c index cb36149c5..870717bd7 100644 --- a/libc/sysdeps/linux/common/ppoll.c +++ b/libc/sysdeps/linux/common/ppoll.c @@ -26,6 +26,10 @@ #include <sys/poll.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif
static int __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, const sigset_t *sigmask) @@ -38,7 +42,7 @@ __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, timeout = &tval; } #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_ppoll_time64)
return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE);
return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, TO_TS64_P(timeout), sigmask, __SYSCALL_SIGSET_T_SIZE);
#else return INLINE_SYSCALL(ppoll, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE); #endif diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c index 23bdab5cf..7a446a589 100644 --- a/libc/sysdeps/linux/common/pselect.c +++ b/libc/sysdeps/linux/common/pselect.c @@ -26,6 +26,10 @@ #include <signal.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif
static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask) @@ -57,7 +61,7 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, sigmask = (void *)&data; } #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64)
return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask);
return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, TO_TS64_P(timeout), sigmask);
#else return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask); #endif diff --git a/libc/sysdeps/linux/common/select.c b/libc/sysdeps/linux/common/select.c index 3132a109c..84016dd0b 100644 --- a/libc/sysdeps/linux/common/select.c +++ b/libc/sysdeps/linux/common/select.c @@ -15,17 +15,19 @@ # define __NR_select __NR__newselect #endif
-#if !defined __NR_select && defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) # include <stdint.h> # define USEC_PER_SEC 1000000L #endif
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif
int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { -#ifdef __NR_select
return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, timeout);
-#elif defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) struct timespec _ts, *ts = 0; if (timeout) { uint32_t usec; @@ -47,8 +49,14 @@ int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
ts = &_ts; }
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64)
return INLINE_SYSCALL(pselect6_time64, 6, n, readfds, writefds, exceptfds, TO_TS64_P(ts), 0);
+#else return INLINE_SYSCALL(pselect6, 6, n, readfds, writefds, exceptfds, ts, 0); #endif +#elif defined(__NR_select)
return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, ts);
+#endif } /* we should guard it, but we need it in other files, so let it fail
- if we miss any of the syscalls */
diff --git a/libc/sysdeps/linux/common/time.c b/libc/sysdeps/linux/common/time.c index 22403f174..d084ffaad 100644 --- a/libc/sysdeps/linux/common/time.c +++ b/libc/sysdeps/linux/common/time.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <time.h>
-#ifdef __NR_time +#if defined(__NR_time) && !defined(__UCLIBC_USE_TIME64__) _syscall_noerr1(time_t, time, time_t *, t) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/timerfd.c b/libc/sysdeps/linux/common/timerfd.c index 0f19b44ed..b4a9e1a93 100644 --- a/libc/sysdeps/linux/common/timerfd.c +++ b/libc/sysdeps/linux/common/timerfd.c @@ -9,6 +9,10 @@ #include <sys/syscall.h> #include <sys/timerfd.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif
/*
- timerfd_create()
*/ @@ -21,7 +25,10 @@ _syscall2(int, timerfd_create, int, clockid, int, flags) */ #if defined(__NR_timerfd_settime) || defined(__NR_timerfd_settime64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timerfd_settime64) -_syscall4_64(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) +int timerfd_settime(int ufd, int flags, const struct itimerspec *utmr, struct itimerspec *otmr) +{
- return INLINE_SYSCALL(timerfd_settime64, 4, ufd, flags, TO_ITS64_P(utmr), otmr);
+} #else _syscall4(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) #endif diff --git a/libc/sysdeps/linux/common/utimensat.c b/libc/sysdeps/linux/common/utimensat.c index 6a78ebb4f..fa6f90e55 100644 --- a/libc/sysdeps/linux/common/utimensat.c +++ b/libc/sysdeps/linux/common/utimensat.c @@ -9,9 +9,27 @@ #include <sys/syscall.h> #include <sys/stat.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif
#if defined(__NR_utimensat) || defined(__NR_utimensat_time64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_utimensat_time64) -_syscall4_time64(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) +int utimensat(int fd, const char *path, const struct timespec times[2], int flags) +{
- struct __ts64_struct __times64[2] = {
{
.tv_sec = times ? times[0].tv_sec : 0,
.tv_nsec = times ? times[0].tv_nsec : 0
},
{
.tv_sec = times ? times[1].tv_sec : 0,
.tv_nsec = times ? times[1].tv_nsec : 0
}
- };
- return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ? &__times64 : 0, flags);
+} #else _syscall4(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) #endif diff --git a/libpthread/nptl/pthread_mutex_timedlock.c b/libpthread/nptl/pthread_mutex_timedlock.c index 25f9ec3b2..446275e67 100644 --- a/libpthread/nptl/pthread_mutex_timedlock.c +++ b/libpthread/nptl/pthread_mutex_timedlock.c @@ -23,6 +23,10 @@ #include <lowlevellock.h> #include <not-cancel.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif
/* We need to build this function with optimization to avoid
- lll_timedlock erroring out with
- error: can't find a register in class ‘GENERAL_REGS’ while reloading ‘asm’
@@ -268,7 +272,7 @@ pthread_mutex_timedlock ( int e = INTERNAL_SYSCALL (futex_time64, __err, 4, &mutex->__data.__lock, __lll_private_flag (FUTEX_LOCK_PI, private), 1,
abstime);
abstime ? TO_TS64_P(abstime) : 0);
Ternary operator is not needed.
#else int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock, __lll_private_flag (FUTEX_LOCK_PI, diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h index e72fe5234..86941b1f2 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h @@ -24,6 +24,10 @@ #include <sysdep.h> #include <bits/kernel-features.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif
#define FUTEX_WAIT 0 #define FUTEX_WAKE 1 #define FUTEX_REQUEUE 3 @@ -71,8 +75,31 @@ # endif #endif
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
#define lll_futex_wait(futexp, val, private) \
- lll_futex_timed_wait(futexp, val, NULL, private)
Why not just leave this definition? Aren't the compilers good enough to eliminate the ternary operator with a constant condition?
- ({ \
- INTERNAL_SYSCALL_DECL (__err); \
- long int __ret; \
- __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \
__lll_private_flag (FUTEX_WAIT, private), \
(val), NULL); \
- __ret; \
- })
+#else
+#define lll_futex_wait(futexp, val, private) \
- ({ \
- INTERNAL_SYSCALL_DECL (__err); \
- long int __ret; \
- __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \
__lll_private_flag (FUTEX_WAIT, private), \
(val), NULL); \
- __ret; \
- })
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
@@ -82,7 +109,7 @@ long int __ret; \ __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \ __lll_private_flag (FUTEX_WAIT, private), \
(val), (timespec)); \
__ret; \ })(val), (TO_TS64_P(timespec))); \
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c index 80d242f21..1cccf57cb 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c @@ -23,6 +23,9 @@ #include <bits/kernel-features.h> #include "kernel-posix-timers.h"
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif
#ifdef __NR_timer_settime # ifndef __ASSUME_POSIX_TIMERS @@ -56,7 +59,7 @@ timer_settime ( /* Delete the kernel timer object. */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) int res = INLINE_SYSCALL (timer_settime64, 4, kt->ktimerid, flags,
value, ovalue);
TO_ITS64_P(value), ovalue);
# else int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags, value, ovalue); diff --git a/librt/clock_gettime.c b/librt/clock_gettime.c index b66b60231..eab9a3343 100644 --- a/librt/clock_gettime.c +++ b/librt/clock_gettime.c @@ -22,10 +22,21 @@ #include <sys/time.h> #include "kernel-posix-cpu-timers.h"
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) -#define SYSCALL_GETTIME \
- retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, tp); \
- break
+#define SYSCALL_GETTIME \
- { \
- struct __ts64_struct __ts64; \
- retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, &__ts64); \
- if (tp) { \
- tp->tv_sec = __ts64.tv_sec; \
- tp->tv_nsec = __ts64.tv_nsec; \
- } \
- break; \
- }
#else #define SYSCALL_GETTIME \ retval = INLINE_SYSCALL (clock_gettime, 2, clock_id, tp); \ diff --git a/librt/clock_nanosleep.c b/librt/clock_nanosleep.c index eaae75720..ef59369df 100644 --- a/librt/clock_nanosleep.c +++ b/librt/clock_nanosleep.c @@ -21,6 +21,9 @@
#include "kernel-posix-cpu-timers.h"
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif
/* We can simply use the syscall. The CPU clocks are not supported with this function. */ @@ -38,7 +41,7 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
if (SINGLE_THREAD_P) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64)
- r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem);
- r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, TO_TS64_P(req), rem);
#else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); #endif @@ -47,7 +50,7 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, #ifdef __NEW_THREADS int oldstate = LIBC_CANCEL_ASYNC (); #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64)
r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem);
r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, TO_TS64_P(req), rem);
#else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); diff --git a/librt/mq_timedreceive.c b/librt/mq_timedreceive.c index db1ae1aa8..f89b4c36b 100644 --- a/librt/mq_timedreceive.c +++ b/librt/mq_timedreceive.c @@ -9,12 +9,16 @@ #include <cancel.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedreceive_time64) -#define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive_time64 +#include "internal/time64_helpers.h"
+int _NC(mq_timedreceive)(mqd_t mqdes, char *restrict msg_ptr, size_t msg_len, unsigned int *restrict msq_prio, const struct timespec *restrict abs_timeout) +{
return INLINE_SYSCALL(mq_timedreceive_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, TO_TS64_P(abs_timeout));
+} #else #define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive -#endif
_syscall5(ssize_t, __NC(mq_timedreceive), mqd_t, mqdes, char *__restrict, msg_ptr, size_t, msg_len, unsigned int *__restrict, msq_prio, const struct timespec *__restrict, abs_timeout) +#endif
CANCELLABLE_SYSCALL(ssize_t, mq_timedreceive, (mqd_t mqdes, char *__restrict msg_ptr, size_t msq_len, unsigned int *__restrict msq_prio, const struct timespec *__restrict abs_timeout), (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) diff --git a/librt/mq_timedsend.c b/librt/mq_timedsend.c index 6afaf5157..b081ac0ce 100644 --- a/librt/mq_timedsend.c +++ b/librt/mq_timedsend.c @@ -9,12 +9,17 @@ #include <cancel.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedsend_time64) -#define __NR___mq_timedsend_nocancel __NR_mq_timedsend_time64 +#include "internal/time64_helpers.h"
+int _NC(mq_timedsend)(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msq_prio, const struct timespec *abs_timeout) +{
return INLINE_SYSCALL(mq_timedsend_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, TO_TS64_P(abs_timeout));
+} #else #define __NR___mq_timedsend_nocancel __NR_mq_timedsend +_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) #endif
-_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) CANCELLABLE_SYSCALL(int, mq_timedsend, (mqd_t mqdes, const char *msg_ptr, size_t msq_len, unsigned int msq_prio, const struct timespec *abs_timeout), (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) lt_libc_hidden(mq_timedsend) diff --git a/librt/timer_settime.c b/librt/timer_settime.c index 022880297..425cd7ee9 100644 --- a/librt/timer_settime.c +++ b/librt/timer_settime.c @@ -12,10 +12,16 @@ #if defined(__NR_timer_settime) || defined(__NR_timer_settime64)
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) -#define __NR___syscall_timer_settime __NR_timer_settime64 +#include "internal/time64_helpers.h"
+int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue) +{
struct timer *kt = (struct timer *)timerid;
return INLINE_SYSCALL(timer_settime64, 4, kt->ktimerid, flags, TO_ITS64_P(value), ovalue);
+} #else #define __NR___syscall_timer_settime __NR_timer_settime -#endif
static __inline__ _syscall4(int, __syscall_timer_settime, kernel_timer_t, ktimerid, int, flags, const void *, value, void *, ovalue); @@ -31,3 +37,4 @@ int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, }
#endif
+#endif
2.43.2
devel mailing list -- devel@uclibc-ng.org To unsubscribe send an email to devel-leave@uclibc-ng.org
For BE architectures there is one significant difference in comparison with time64 support for little-endian architectures like ARMv7. The difference is that we strictly need to pass two 64bit values to system calls because Linux Kernel internally uses `struct __kernel_timespec` and similar, which consists of two 64bit fields. For this reason many files have been changed to convert pointers to timespec-family structures (mixed of 64bit and 32bit values) to the pointer of the similar but 64bit-only structures for using as system calls args. This is general prerequisite for any BE architecture.
Signed-off-by: Dmitry Chestnykh dm.chestnykh@gmail.com --- Added newline to the end of time64_helpers.h. Yes, we can use the old definition of lll_futex_wait() macro because i reworked a little TO_TS64_P(). include/internal/time64_helpers.h | 31 +++++++++++++++++++ libc/inet/socketcalls.c | 6 +++- libc/misc/sysvipc/sem.c | 9 +++++- libc/signal/sigwait.c | 3 +- libc/sysdeps/linux/common/__rt_sigtimedwait.c | 10 ++++-- libc/sysdeps/linux/common/__rt_sigwaitinfo.c | 2 +- libc/sysdeps/linux/common/alarm.c | 2 +- libc/sysdeps/linux/common/clock_getres.c | 15 +++++++-- libc/sysdeps/linux/common/clock_gettime.c | 14 ++++++++- libc/sysdeps/linux/common/clock_settime.c | 7 ++++- libc/sysdeps/linux/common/ppoll.c | 6 +++- libc/sysdeps/linux/common/pselect.c | 6 +++- libc/sysdeps/linux/common/select.c | 16 +++++++--- libc/sysdeps/linux/common/time.c | 2 +- libc/sysdeps/linux/common/timerfd.c | 9 +++++- libc/sysdeps/linux/common/utimensat.c | 20 +++++++++++- libpthread/nptl/pthread_mutex_timedlock.c | 6 +++- .../sysdeps/unix/sysv/linux/lowlevellock.h | 6 +++- .../sysdeps/unix/sysv/linux/timer_settime.c | 5 ++- librt/clock_gettime.c | 17 ++++++++-- librt/clock_nanosleep.c | 7 +++-- librt/mq_timedreceive.c | 10 ++++-- librt/mq_timedsend.c | 9 ++++-- librt/timer_settime.c | 11 +++++-- 24 files changed, 193 insertions(+), 36 deletions(-) create mode 100644 include/internal/time64_helpers.h
diff --git a/include/internal/time64_helpers.h b/include/internal/time64_helpers.h new file mode 100644 index 000000000..7a78e8388 --- /dev/null +++ b/include/internal/time64_helpers.h @@ -0,0 +1,31 @@ +#ifndef _TIME64_HELPERS_H +#define _TIME64_HELPERS_H + +#include <bits/types.h> +#include <time.h> +#include <stddef.h> + +struct __ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; + +#define TO_TS64_P(__ts) (((struct timespec *)(__ts)) ? \ + (&(struct __ts64_struct) {.tv_sec = ((struct timespec *)(__ts))->tv_sec, \ + .tv_nsec = ((struct timespec *)(__ts))->tv_nsec}) : NULL) + +struct __its64_struct { + __S64_TYPE interval_tv_sec; + __S64_TYPE interval_tv_nsec; + __S64_TYPE value_tv_sec; + __S64_TYPE value_tv_nsec; +}; + +#define TO_ITS64_P(__its) (((struct itimerspec *)(__its)) ? \ + (&(struct __its64_struct) {.interval_tv_sec = ((struct itimerspec *)(__its))->it_interval.tv_sec, \ + .interval_tv_nsec = ((struct itimerspec *)(__its))->it_interval.tv_nsec, \ + .value_tv_sec = ((struct itimerspec *)(__its))->it_value.tv_sec, \ + .value_tv_nsec = ((struct itimerspec *)(__its))->it_value.tv_nsec}) : NULL) + + +#endif /* _TIME64_HELPERS_H */ diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c index eb0983698..774ed6091 100644 --- a/libc/inet/socketcalls.c +++ b/libc/inet/socketcalls.c @@ -10,6 +10,10 @@ #include <cancel.h> #include <bits/kernel-features.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + #ifdef __NR_socketcall /* Various socketcall numbers */ #define SYS_SOCKET 1 @@ -273,7 +277,7 @@ static ssize_t __NC(recvmmsg)(int sockfd, struct mmsghdr *msg, size_t vlen, int flags, struct timespec *tmo) { # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_recvmmsg_time64) - return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo); + return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, TO_TS64_P(tmo)); # elif defined(__NR_recvmmsg) return (ssize_t)INLINE_SYSCALL(recvmmsg, 5, sockfd, msg, vlen, flags, tmo); # elif __NR_socketcall diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c index cd541761c..07076eff7 100644 --- a/libc/misc/sysvipc/sem.c +++ b/libc/misc/sysvipc/sem.c @@ -23,6 +23,9 @@
#include "ipc.h"
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif
#ifdef L_semctl /* Return identifier for array of NSEMS semaphores associated with @@ -96,7 +99,11 @@ int semop (int semid, struct sembuf *sops, size_t nsops) #ifdef L_semtimedop
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_semtimedop_time64) -_syscall4_time64(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout) +int semtimedop(int semid, struct sembuf *sops, size_t nsops, const struct timespec *timeout) +{ + return INLINE_SYSCALL(semtimedop_time64, 4, semid, sops, nsops, TO_TS64_P(timeout)); +} + #elif defined(__NR_semtimedop) _syscall4(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout)
diff --git a/libc/signal/sigwait.c b/libc/signal/sigwait.c index 3557a039e..b237534cd 100644 --- a/libc/signal/sigwait.c +++ b/libc/signal/sigwait.c @@ -24,7 +24,8 @@ #include <signal.h> #include <cancel.h>
-#if defined __NR_rt_sigtimedwait && defined __UCLIBC_HAS_REALTIME__ +#if (defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64))) && \ + defined(__UCLIBC_HAS_REALTIME__)
#include <string.h>
diff --git a/libc/sysdeps/linux/common/__rt_sigtimedwait.c b/libc/sysdeps/linux/common/__rt_sigtimedwait.c index bd82ca6d5..aff5299a1 100644 --- a/libc/sysdeps/linux/common/__rt_sigtimedwait.c +++ b/libc/sysdeps/linux/common/__rt_sigtimedwait.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__NR_rt_sigtimedwait_time64) && defined(__UCLIBC_USE_TIME64__)) # include <signal.h> # include <cancel.h> # ifdef __UCLIBC_HAS_THREADS_NATIVE__ @@ -21,6 +21,10 @@ # include <string.h> # endif
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, const struct timespec *timeout) { @@ -54,7 +58,7 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64) result = INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info, - timeout, __SYSCALL_SIGSET_T_SIZE); + TO_TS64_P(timeout), __SYSCALL_SIGSET_T_SIZE); # else result = INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); @@ -72,7 +76,7 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64) return INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info, - timeout, __SYSCALL_SIGSET_T_SIZE); + TO_TS64_P(timeout), __SYSCALL_SIGSET_T_SIZE); # else return INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); diff --git a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c index d2d176a64..7830b2e2c 100644 --- a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c +++ b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)) # define __need_NULL # include <stddef.h> # include <signal.h> diff --git a/libc/sysdeps/linux/common/alarm.c b/libc/sysdeps/linux/common/alarm.c index 4e6e2215b..861f6ad8e 100644 --- a/libc/sysdeps/linux/common/alarm.c +++ b/libc/sysdeps/linux/common/alarm.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <unistd.h>
-#ifdef __NR_alarm && !defined(__UCLIBC_USE_TIME64__) +#if defined(__NR_alarm) && !defined(__UCLIBC_USE_TIME64__) _syscall1(unsigned int, alarm, unsigned int, seconds) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/clock_getres.c b/libc/sysdeps/linux/common/clock_getres.c index d4b989958..fd0f8c14c 100644 --- a/libc/sysdeps/linux/common/clock_getres.c +++ b/libc/sysdeps/linux/common/clock_getres.c @@ -10,9 +10,20 @@ #include <sys/syscall.h> #include <time.h>
- #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64) -_syscall2_time64(int, clock_getres, clockid_t, clock_id, struct timespec*, res) +#include "internal/time64_helpers.h" + +int clock_getres(clockid_t clock_id, struct timespec *res) +{ + struct __ts64_struct __ts64; + int __ret = INLINE_SYSCALL(clock_getres_time64, 2, clock_id, &__ts64); + if (__ret == 0 && res) { + res->tv_sec = __ts64.tv_sec; + res->tv_nsec = __ts64.tv_nsec; + }; + + return __ret; +} #elif defined(__NR_clock_getres) _syscall2(int, clock_getres, clockid_t, clock_id, struct timespec*, res) #else diff --git a/libc/sysdeps/linux/common/clock_gettime.c b/libc/sysdeps/linux/common/clock_gettime.c index a595bd691..4d787b9b7 100644 --- a/libc/sysdeps/linux/common/clock_gettime.c +++ b/libc/sysdeps/linux/common/clock_gettime.c @@ -12,7 +12,19 @@ #include <time.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) -_syscall2_64(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) +#include "internal/time64_helpers.h" + +int clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + struct __ts64_struct __ts64; + int __ret = INLINE_SYSCALL(clock_gettime64, 2, clock_id, &__ts64); + if (tp) { + tp->tv_sec = __ts64.tv_sec; + tp->tv_nsec = __ts64.tv_nsec; + } + + return __ret; +} #elif defined(__NR_clock_gettime) _syscall2(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/clock_settime.c b/libc/sysdeps/linux/common/clock_settime.c index 89550af5a..3abc5f49b 100644 --- a/libc/sysdeps/linux/common/clock_settime.c +++ b/libc/sysdeps/linux/common/clock_settime.c @@ -12,7 +12,12 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_settime64) -_syscall2_64(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) +#include "internal/time64_helpers.h" + +int clock_settime(clockid_t clock_id, const struct timespec *tp) +{ + return INLINE_SYSCALL(clock_settime64, 2, clock_id, TO_TS64_P(tp)); +} #elif defined(__NR_clock_settime) _syscall2(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/ppoll.c b/libc/sysdeps/linux/common/ppoll.c index cb36149c5..870717bd7 100644 --- a/libc/sysdeps/linux/common/ppoll.c +++ b/libc/sysdeps/linux/common/ppoll.c @@ -26,6 +26,10 @@ #include <sys/poll.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + static int __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, const sigset_t *sigmask) @@ -38,7 +42,7 @@ __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, timeout = &tval; } #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_ppoll_time64) - return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE); + return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, TO_TS64_P(timeout), sigmask, __SYSCALL_SIGSET_T_SIZE); #else return INLINE_SYSCALL(ppoll, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE); #endif diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c index 23bdab5cf..7a446a589 100644 --- a/libc/sysdeps/linux/common/pselect.c +++ b/libc/sysdeps/linux/common/pselect.c @@ -26,6 +26,10 @@ #include <signal.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask) @@ -57,7 +61,7 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, sigmask = (void *)&data; } #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64) - return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask); + return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, TO_TS64_P(timeout), sigmask); #else return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask); #endif diff --git a/libc/sysdeps/linux/common/select.c b/libc/sysdeps/linux/common/select.c index 3132a109c..84016dd0b 100644 --- a/libc/sysdeps/linux/common/select.c +++ b/libc/sysdeps/linux/common/select.c @@ -15,17 +15,19 @@ # define __NR_select __NR__newselect #endif
-#if !defined __NR_select && defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) # include <stdint.h> # define USEC_PER_SEC 1000000L #endif
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { -#ifdef __NR_select - return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, timeout); -#elif defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) struct timespec _ts, *ts = 0; if (timeout) { uint32_t usec; @@ -47,8 +49,14 @@ int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
ts = &_ts; } +#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64) + return INLINE_SYSCALL(pselect6_time64, 6, n, readfds, writefds, exceptfds, TO_TS64_P(ts), 0); +#else return INLINE_SYSCALL(pselect6, 6, n, readfds, writefds, exceptfds, ts, 0); #endif +#elif defined(__NR_select) + return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, ts); +#endif } /* we should guard it, but we need it in other files, so let it fail * if we miss any of the syscalls */ diff --git a/libc/sysdeps/linux/common/time.c b/libc/sysdeps/linux/common/time.c index 22403f174..d084ffaad 100644 --- a/libc/sysdeps/linux/common/time.c +++ b/libc/sysdeps/linux/common/time.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <time.h>
-#ifdef __NR_time +#if defined(__NR_time) && !defined(__UCLIBC_USE_TIME64__) _syscall_noerr1(time_t, time, time_t *, t) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/timerfd.c b/libc/sysdeps/linux/common/timerfd.c index 0f19b44ed..b4a9e1a93 100644 --- a/libc/sysdeps/linux/common/timerfd.c +++ b/libc/sysdeps/linux/common/timerfd.c @@ -9,6 +9,10 @@ #include <sys/syscall.h> #include <sys/timerfd.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + /* * timerfd_create() */ @@ -21,7 +25,10 @@ _syscall2(int, timerfd_create, int, clockid, int, flags) */ #if defined(__NR_timerfd_settime) || defined(__NR_timerfd_settime64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timerfd_settime64) -_syscall4_64(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) +int timerfd_settime(int ufd, int flags, const struct itimerspec *utmr, struct itimerspec *otmr) +{ + return INLINE_SYSCALL(timerfd_settime64, 4, ufd, flags, TO_ITS64_P(utmr), otmr); +} #else _syscall4(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) #endif diff --git a/libc/sysdeps/linux/common/utimensat.c b/libc/sysdeps/linux/common/utimensat.c index 6a78ebb4f..fa6f90e55 100644 --- a/libc/sysdeps/linux/common/utimensat.c +++ b/libc/sysdeps/linux/common/utimensat.c @@ -9,9 +9,27 @@ #include <sys/syscall.h> #include <sys/stat.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + #if defined(__NR_utimensat) || defined(__NR_utimensat_time64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_utimensat_time64) -_syscall4_time64(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) +int utimensat(int fd, const char *path, const struct timespec times[2], int flags) +{ + struct __ts64_struct __times64[2] = { + { + .tv_sec = times ? times[0].tv_sec : 0, + .tv_nsec = times ? times[0].tv_nsec : 0 + }, + { + .tv_sec = times ? times[1].tv_sec : 0, + .tv_nsec = times ? times[1].tv_nsec : 0 + } + }; + + return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ? &__times64 : 0, flags); +} #else _syscall4(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) #endif diff --git a/libpthread/nptl/pthread_mutex_timedlock.c b/libpthread/nptl/pthread_mutex_timedlock.c index 25f9ec3b2..d54983315 100644 --- a/libpthread/nptl/pthread_mutex_timedlock.c +++ b/libpthread/nptl/pthread_mutex_timedlock.c @@ -23,6 +23,10 @@ #include <lowlevellock.h> #include <not-cancel.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + /* We need to build this function with optimization to avoid * lll_timedlock erroring out with * error: can't find a register in class ‘GENERAL_REGS’ while reloading ‘asm’ @@ -268,7 +272,7 @@ pthread_mutex_timedlock ( int e = INTERNAL_SYSCALL (futex_time64, __err, 4, &mutex->__data.__lock, __lll_private_flag (FUTEX_LOCK_PI, private), 1, - abstime); + TO_TS64_P(abstime)); #else int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock, __lll_private_flag (FUTEX_LOCK_PI, diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h index e72fe5234..6ecc23e25 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h @@ -24,6 +24,10 @@ #include <sysdep.h> #include <bits/kernel-features.h>
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + #define FUTEX_WAIT 0 #define FUTEX_WAKE 1 #define FUTEX_REQUEUE 3 @@ -82,7 +86,7 @@ long int __ret; \ __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \ __lll_private_flag (FUTEX_WAIT, private), \ - (val), (timespec)); \ + (val), (TO_TS64_P(timespec))); \ __ret; \ })
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c index 80d242f21..1cccf57cb 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c @@ -23,6 +23,9 @@ #include <bits/kernel-features.h> #include "kernel-posix-timers.h"
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif
#ifdef __NR_timer_settime # ifndef __ASSUME_POSIX_TIMERS @@ -56,7 +59,7 @@ timer_settime ( /* Delete the kernel timer object. */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) int res = INLINE_SYSCALL (timer_settime64, 4, kt->ktimerid, flags, - value, ovalue); + TO_ITS64_P(value), ovalue); # else int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags, value, ovalue); diff --git a/librt/clock_gettime.c b/librt/clock_gettime.c index b66b60231..eab9a3343 100644 --- a/librt/clock_gettime.c +++ b/librt/clock_gettime.c @@ -22,10 +22,21 @@ #include <sys/time.h> #include "kernel-posix-cpu-timers.h"
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) -#define SYSCALL_GETTIME \ - retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, tp); \ - break +#define SYSCALL_GETTIME \ + { \ + struct __ts64_struct __ts64; \ + retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, &__ts64); \ + if (tp) { \ + tp->tv_sec = __ts64.tv_sec; \ + tp->tv_nsec = __ts64.tv_nsec; \ + } \ + break; \ + } #else #define SYSCALL_GETTIME \ retval = INLINE_SYSCALL (clock_gettime, 2, clock_id, tp); \ diff --git a/librt/clock_nanosleep.c b/librt/clock_nanosleep.c index eaae75720..ef59369df 100644 --- a/librt/clock_nanosleep.c +++ b/librt/clock_nanosleep.c @@ -21,6 +21,9 @@
#include "kernel-posix-cpu-timers.h"
+#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif
/* We can simply use the syscall. The CPU clocks are not supported with this function. */ @@ -38,7 +41,7 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
if (SINGLE_THREAD_P) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64) - r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem); + r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, TO_TS64_P(req), rem); #else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); #endif @@ -47,7 +50,7 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, #ifdef __NEW_THREADS int oldstate = LIBC_CANCEL_ASYNC (); #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64) - r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem); + r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, TO_TS64_P(req), rem); #else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); diff --git a/librt/mq_timedreceive.c b/librt/mq_timedreceive.c index db1ae1aa8..f89b4c36b 100644 --- a/librt/mq_timedreceive.c +++ b/librt/mq_timedreceive.c @@ -9,12 +9,16 @@ #include <cancel.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedreceive_time64) -#define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive_time64 +#include "internal/time64_helpers.h" + +int _NC(mq_timedreceive)(mqd_t mqdes, char *restrict msg_ptr, size_t msg_len, unsigned int *restrict msq_prio, const struct timespec *restrict abs_timeout) +{ + return INLINE_SYSCALL(mq_timedreceive_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, TO_TS64_P(abs_timeout)); +} #else #define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive -#endif - _syscall5(ssize_t, __NC(mq_timedreceive), mqd_t, mqdes, char *__restrict, msg_ptr, size_t, msg_len, unsigned int *__restrict, msq_prio, const struct timespec *__restrict, abs_timeout) +#endif
CANCELLABLE_SYSCALL(ssize_t, mq_timedreceive, (mqd_t mqdes, char *__restrict msg_ptr, size_t msq_len, unsigned int *__restrict msq_prio, const struct timespec *__restrict abs_timeout), (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) diff --git a/librt/mq_timedsend.c b/librt/mq_timedsend.c index 6afaf5157..b081ac0ce 100644 --- a/librt/mq_timedsend.c +++ b/librt/mq_timedsend.c @@ -9,12 +9,17 @@ #include <cancel.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedsend_time64) -#define __NR___mq_timedsend_nocancel __NR_mq_timedsend_time64 +#include "internal/time64_helpers.h" + +int _NC(mq_timedsend)(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msq_prio, const struct timespec *abs_timeout) +{ + return INLINE_SYSCALL(mq_timedsend_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, TO_TS64_P(abs_timeout)); +} #else #define __NR___mq_timedsend_nocancel __NR_mq_timedsend +_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) #endif
-_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) CANCELLABLE_SYSCALL(int, mq_timedsend, (mqd_t mqdes, const char *msg_ptr, size_t msq_len, unsigned int msq_prio, const struct timespec *abs_timeout), (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) lt_libc_hidden(mq_timedsend) diff --git a/librt/timer_settime.c b/librt/timer_settime.c index 022880297..425cd7ee9 100644 --- a/librt/timer_settime.c +++ b/librt/timer_settime.c @@ -12,10 +12,16 @@ #if defined(__NR_timer_settime) || defined(__NR_timer_settime64)
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) -#define __NR___syscall_timer_settime __NR_timer_settime64 +#include "internal/time64_helpers.h" + +int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue) +{ + struct timer *kt = (struct timer *)timerid; + + return INLINE_SYSCALL(timer_settime64, 4, kt->ktimerid, flags, TO_ITS64_P(value), ovalue); +} #else #define __NR___syscall_timer_settime __NR_timer_settime -#endif
static __inline__ _syscall4(int, __syscall_timer_settime, kernel_timer_t, ktimerid, int, flags, const void *, value, void *, ovalue); @@ -31,3 +37,4 @@ int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, }
#endif +#endif
On Sun, Feb 25, 2024 at 3:52 AM Dmitry Chestnykh dm.chestnykh@gmail.com wrote:
For BE architectures there is one significant difference in comparison with time64 support for little-endian architectures like ARMv7. The difference is that we strictly need to pass two 64bit values to system calls because Linux Kernel internally uses `struct __kernel_timespec` and similar, which consists of two 64bit fields. For this reason many files have been changed to convert pointers to timespec-family structures (mixed of 64bit and 32bit values) to the pointer of the similar but 64bit-only structures for using as system calls args. This is general prerequisite for any BE architecture.
Signed-off-by: Dmitry Chestnykh dm.chestnykh@gmail.com
Added newline to the end of time64_helpers.h. Yes, we can use the old definition of lll_futex_wait() macro because i reworked a little TO_TS64_P(). include/internal/time64_helpers.h | 31 +++++++++++++++++++ libc/inet/socketcalls.c | 6 +++- libc/misc/sysvipc/sem.c | 9 +++++- libc/signal/sigwait.c | 3 +- libc/sysdeps/linux/common/__rt_sigtimedwait.c | 10 ++++-- libc/sysdeps/linux/common/__rt_sigwaitinfo.c | 2 +- libc/sysdeps/linux/common/alarm.c | 2 +- libc/sysdeps/linux/common/clock_getres.c | 15 +++++++-- libc/sysdeps/linux/common/clock_gettime.c | 14 ++++++++- libc/sysdeps/linux/common/clock_settime.c | 7 ++++- libc/sysdeps/linux/common/ppoll.c | 6 +++- libc/sysdeps/linux/common/pselect.c | 6 +++- libc/sysdeps/linux/common/select.c | 16 +++++++--- libc/sysdeps/linux/common/time.c | 2 +- libc/sysdeps/linux/common/timerfd.c | 9 +++++- libc/sysdeps/linux/common/utimensat.c | 20 +++++++++++- libpthread/nptl/pthread_mutex_timedlock.c | 6 +++- .../sysdeps/unix/sysv/linux/lowlevellock.h | 6 +++- .../sysdeps/unix/sysv/linux/timer_settime.c | 5 ++- librt/clock_gettime.c | 17 ++++++++-- librt/clock_nanosleep.c | 7 +++-- librt/mq_timedreceive.c | 10 ++++-- librt/mq_timedsend.c | 9 ++++-- librt/timer_settime.c | 11 +++++-- 24 files changed, 193 insertions(+), 36 deletions(-) create mode 100644 include/internal/time64_helpers.h
This version looks good to me. Reviewed-by: Max Filippov jcmvbkbc@gmail.com
-- Thanks. -- Max
Hi Dmitry, Dmitry Chestnykh wrote,
For BE architectures there is one significant difference in comparison with time64 support for little-endian architectures like ARMv7. The difference is that we strictly need to pass two 64bit values to system calls because Linux Kernel internally uses `struct __kernel_timespec` and similar, which consists of two 64bit fields. For this reason many files have been changed to convert pointers to timespec-family structures (mixed of 64bit and 32bit values) to the pointer of the similar but 64bit-only structures for using as system calls args. This is general prerequisite for any BE architecture.
Signed-off-by: Dmitry Chestnykh dm.chestnykh@gmail.com
Thanks! Applied and pushed. best regards Waldemar
For BE architectures there is one significant difference in comparison with time64 support for little-endian architectures like ARMv7. The difference is that we strictly need to pass two 64bit values to system calls because Linux Kernel internally uses `struct __kernel_timespec` and similar, which consists of two 64bit fields. For this reason many files have been changed to convert pointers to timespec-family structures (mixed of 64bit and 32bit values) to the pointer of the similar but 64bit-only structures for using as system calls args. This is general prerequisite for any BE architecture.
Signed-off-by: Dmitry Chestnykh dm.chestnykh@gmail.com --- include/time.h | 27 +++++++++++++++++++ libc/inet/socketcalls.c | 2 +- libc/misc/sysvipc/sem.c | 6 ++++- libc/signal/sigwait.c | 3 ++- libc/sysdeps/linux/common/__rt_sigtimedwait.c | 6 ++--- libc/sysdeps/linux/common/__rt_sigwaitinfo.c | 2 +- libc/sysdeps/linux/common/alarm.c | 2 +- libc/sysdeps/linux/common/clock_getres.c | 13 +++++++-- libc/sysdeps/linux/common/clock_gettime.c | 12 ++++++++- libc/sysdeps/linux/common/clock_settime.c | 5 +++- libc/sysdeps/linux/common/ppoll.c | 2 +- libc/sysdeps/linux/common/pselect.c | 2 +- libc/sysdeps/linux/common/select.c | 12 ++++++--- libc/sysdeps/linux/common/time.c | 2 +- libc/sysdeps/linux/common/timerfd.c | 5 +++- libc/sysdeps/linux/common/utimensat.c | 16 ++++++++++- libpthread/nptl/pthread_mutex_timedlock.c | 2 +- .../sysdeps/unix/sysv/linux/lowlevellock.c | 5 ++-- .../sysdeps/unix/sysv/linux/lowlevellock.h | 27 +++++++++++++++++-- .../unix/sysv/linux/lowlevelrobustlock.c | 1 - .../sysdeps/unix/sysv/linux/timer_settime.c | 2 +- librt/clock_gettime.c | 11 ++++++-- librt/clock_nanosleep.c | 5 ++-- librt/mq_timedreceive.c | 8 +++--- librt/mq_timedsend.c | 6 ++++- librt/timer_settime.c | 9 +++++-- 26 files changed, 154 insertions(+), 39 deletions(-)
diff --git a/include/time.h b/include/time.h index 1a1408990..880a80d85 100644 --- a/include/time.h +++ b/include/time.h @@ -122,6 +122,16 @@ struct timespec long int tv_nsec; /* Nanoseconds. */ };
+#if defined(__UCLIBC_USE_TIME64__) + +struct __ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; + +#define TO_TS64_P(__ts) (&(struct __ts64_struct) {.tv_sec = (__ts)->tv_sec, .tv_nsec = (__ts)->tv_nsec}) +#endif + #endif /* timespec not defined and <time.h> or need timespec. */ #undef __need_timespec
@@ -165,6 +175,23 @@ struct itimerspec struct timespec it_value; };
+#if defined(__UCLIBC_USE_TIME64__) + +struct __its64_struct { + __S64_TYPE interval_tv_sec; + __S64_TYPE interval_tv_nsec; + __S64_TYPE value_tv_sec; + __S64_TYPE value_tv_nsec; +}; + +#define TO_ITS64_P(__its) (&(struct __its64_struct) {.interval_tv_sec = (__its)->it_interval.tv_sec, \ + .interval_tv_nsec = (__its)->it_interval.tv_nsec, \ + .value_tv_sec = (__its)->it_value.tv_sec, \ + .value_tv_nsec = (__its)->it_value.tv_nsec}) + +#endif + + /* We can use a simple forward declaration. */ struct sigevent;
diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c index eb0983698..ea623878a 100644 --- a/libc/inet/socketcalls.c +++ b/libc/inet/socketcalls.c @@ -273,7 +273,7 @@ static ssize_t __NC(recvmmsg)(int sockfd, struct mmsghdr *msg, size_t vlen, int flags, struct timespec *tmo) { # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_recvmmsg_time64) - return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo); + return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo ? TO_TS64_P(tmo) : 0); # elif defined(__NR_recvmmsg) return (ssize_t)INLINE_SYSCALL(recvmmsg, 5, sockfd, msg, vlen, flags, tmo); # elif __NR_socketcall diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c index cd541761c..48d345984 100644 --- a/libc/misc/sysvipc/sem.c +++ b/libc/misc/sysvipc/sem.c @@ -96,7 +96,11 @@ int semop (int semid, struct sembuf *sops, size_t nsops) #ifdef L_semtimedop
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_semtimedop_time64) -_syscall4_time64(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout) +int semtimedop(int semid, struct sembuf *sops, size_t nsops, const struct timespec *timeout) +{ + return INLINE_SYSCALL(semtimedop_time64, 4, semid, sops, nsops, timeout ? TO_TS64_P(timeout) : 0); +} + #elif defined(__NR_semtimedop) _syscall4(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout)
diff --git a/libc/signal/sigwait.c b/libc/signal/sigwait.c index 3557a039e..b237534cd 100644 --- a/libc/signal/sigwait.c +++ b/libc/signal/sigwait.c @@ -24,7 +24,8 @@ #include <signal.h> #include <cancel.h>
-#if defined __NR_rt_sigtimedwait && defined __UCLIBC_HAS_REALTIME__ +#if (defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64))) && \ + defined(__UCLIBC_HAS_REALTIME__)
#include <string.h>
diff --git a/libc/sysdeps/linux/common/__rt_sigtimedwait.c b/libc/sysdeps/linux/common/__rt_sigtimedwait.c index bd82ca6d5..44e1ce928 100644 --- a/libc/sysdeps/linux/common/__rt_sigtimedwait.c +++ b/libc/sysdeps/linux/common/__rt_sigtimedwait.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__NR_rt_sigtimedwait_time64) && defined(__UCLIBC_USE_TIME64__)) # include <signal.h> # include <cancel.h> # ifdef __UCLIBC_HAS_THREADS_NATIVE__ @@ -54,7 +54,7 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64) result = INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info, - timeout, __SYSCALL_SIGSET_T_SIZE); + timeout ? TO_TS64_P(timeout) : 0, __SYSCALL_SIGSET_T_SIZE); # else result = INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); @@ -72,7 +72,7 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64) return INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info, - timeout, __SYSCALL_SIGSET_T_SIZE); + timeout ? TO_TS64_P(timeout) : 0, __SYSCALL_SIGSET_T_SIZE); # else return INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); diff --git a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c index d2d176a64..7830b2e2c 100644 --- a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c +++ b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)) # define __need_NULL # include <stddef.h> # include <signal.h> diff --git a/libc/sysdeps/linux/common/alarm.c b/libc/sysdeps/linux/common/alarm.c index 4e6e2215b..861f6ad8e 100644 --- a/libc/sysdeps/linux/common/alarm.c +++ b/libc/sysdeps/linux/common/alarm.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <unistd.h>
-#ifdef __NR_alarm && !defined(__UCLIBC_USE_TIME64__) +#if defined(__NR_alarm) && !defined(__UCLIBC_USE_TIME64__) _syscall1(unsigned int, alarm, unsigned int, seconds) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/clock_getres.c b/libc/sysdeps/linux/common/clock_getres.c index d4b989958..c1818f9ce 100644 --- a/libc/sysdeps/linux/common/clock_getres.c +++ b/libc/sysdeps/linux/common/clock_getres.c @@ -10,9 +10,18 @@ #include <sys/syscall.h> #include <time.h>
- #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64) -_syscall2_time64(int, clock_getres, clockid_t, clock_id, struct timespec*, res) +int clock_getres(clockid_t clock_id, struct timespec *res) +{ + struct __ts64_struct __ts64; + int __ret = INLINE_SYSCALL(clock_getres_time64, 2, clock_id, &__ts64); + if (__ret == 0 && res) { + res->tv_sec = __ts64.tv_sec; + res->tv_nsec = __ts64.tv_nsec; + }; + + return __ret; +} #elif defined(__NR_clock_getres) _syscall2(int, clock_getres, clockid_t, clock_id, struct timespec*, res) #else diff --git a/libc/sysdeps/linux/common/clock_gettime.c b/libc/sysdeps/linux/common/clock_gettime.c index a595bd691..00212a9ef 100644 --- a/libc/sysdeps/linux/common/clock_gettime.c +++ b/libc/sysdeps/linux/common/clock_gettime.c @@ -12,7 +12,17 @@ #include <time.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) -_syscall2_64(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) +int clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + struct __ts64_struct __ts64; + int __ret = INLINE_SYSCALL(clock_gettime64, 2, clock_id, &__ts64); + if (tp) { + tp->tv_sec = __ts64.tv_sec; + tp->tv_nsec = __ts64.tv_nsec; + } + + return __ret; +} #elif defined(__NR_clock_gettime) _syscall2(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/clock_settime.c b/libc/sysdeps/linux/common/clock_settime.c index 89550af5a..666ae4075 100644 --- a/libc/sysdeps/linux/common/clock_settime.c +++ b/libc/sysdeps/linux/common/clock_settime.c @@ -12,7 +12,10 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_settime64) -_syscall2_64(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) +int clock_settime(clockid_t clock_id, const struct timespec *tp) +{ + return INLINE_SYSCALL(clock_settime64, 2, clock_id, tp ? TO_TS64_P(tp) : 0); +} #elif defined(__NR_clock_settime) _syscall2(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/ppoll.c b/libc/sysdeps/linux/common/ppoll.c index cb36149c5..3b98a2760 100644 --- a/libc/sysdeps/linux/common/ppoll.c +++ b/libc/sysdeps/linux/common/ppoll.c @@ -38,7 +38,7 @@ __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, timeout = &tval; } #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_ppoll_time64) - return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE); + return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout ? TO_TS64_P(timeout) : 0, sigmask, __SYSCALL_SIGSET_T_SIZE); #else return INLINE_SYSCALL(ppoll, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE); #endif diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c index 23bdab5cf..3ceb51012 100644 --- a/libc/sysdeps/linux/common/pselect.c +++ b/libc/sysdeps/linux/common/pselect.c @@ -57,7 +57,7 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, sigmask = (void *)&data; } #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64) - return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask); + return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout ? TO_TS64_P(timeout) : 0, sigmask); #else return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask); #endif diff --git a/libc/sysdeps/linux/common/select.c b/libc/sysdeps/linux/common/select.c index 3132a109c..05d2b55b2 100644 --- a/libc/sysdeps/linux/common/select.c +++ b/libc/sysdeps/linux/common/select.c @@ -15,7 +15,7 @@ # define __NR_select __NR__newselect #endif
-#if !defined __NR_select && defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) # include <stdint.h> # define USEC_PER_SEC 1000000L #endif @@ -23,9 +23,7 @@ int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { -#ifdef __NR_select - return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, timeout); -#elif defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) struct timespec _ts, *ts = 0; if (timeout) { uint32_t usec; @@ -47,8 +45,14 @@ int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
ts = &_ts; } +#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64) + return INLINE_SYSCALL(pselect6_time64, 6, n, readfds, writefds, exceptfds, ts ? TO_TS64_P(ts) : 0, 0); +#else return INLINE_SYSCALL(pselect6, 6, n, readfds, writefds, exceptfds, ts, 0); #endif +#elif defined(__NR_select) + return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, ts); +#endif } /* we should guard it, but we need it in other files, so let it fail * if we miss any of the syscalls */ diff --git a/libc/sysdeps/linux/common/time.c b/libc/sysdeps/linux/common/time.c index 22403f174..d084ffaad 100644 --- a/libc/sysdeps/linux/common/time.c +++ b/libc/sysdeps/linux/common/time.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <time.h>
-#ifdef __NR_time +#if defined(__NR_time) && !defined(__UCLIBC_USE_TIME64__) _syscall_noerr1(time_t, time, time_t *, t) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/timerfd.c b/libc/sysdeps/linux/common/timerfd.c index 0f19b44ed..07bfb09b7 100644 --- a/libc/sysdeps/linux/common/timerfd.c +++ b/libc/sysdeps/linux/common/timerfd.c @@ -21,7 +21,10 @@ _syscall2(int, timerfd_create, int, clockid, int, flags) */ #if defined(__NR_timerfd_settime) || defined(__NR_timerfd_settime64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timerfd_settime64) -_syscall4_64(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) +int timerfd_settime(int ufd, int flags, const struct itimerspec *utmr, struct itimerspec *otmr) +{ + return INLINE_SYSCALL(timerfd_settime64, 4, ufd, flags, utmr ? TO_ITS64_P(utmr) : 0, otmr); +} #else _syscall4(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) #endif diff --git a/libc/sysdeps/linux/common/utimensat.c b/libc/sysdeps/linux/common/utimensat.c index 6a78ebb4f..339a35559 100644 --- a/libc/sysdeps/linux/common/utimensat.c +++ b/libc/sysdeps/linux/common/utimensat.c @@ -11,7 +11,21 @@
#if defined(__NR_utimensat) || defined(__NR_utimensat_time64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_utimensat_time64) -_syscall4_time64(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) +int utimensat(int fd, const char *path, const struct timespec times[2], int flags) +{ + struct __ts64_struct __times64[2] = { + { + .tv_sec = times ? times[0].tv_sec : 0, + .tv_nsec = times ? times[0].tv_nsec : 0 + }, + { + .tv_sec = times ? times[1].tv_sec : 0, + .tv_nsec = times ? times[1].tv_nsec : 0 + } + }; + + return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ? &__times64 : 0, flags); +} #else _syscall4(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) #endif diff --git a/libpthread/nptl/pthread_mutex_timedlock.c b/libpthread/nptl/pthread_mutex_timedlock.c index 25f9ec3b2..7bb9a0aaf 100644 --- a/libpthread/nptl/pthread_mutex_timedlock.c +++ b/libpthread/nptl/pthread_mutex_timedlock.c @@ -268,7 +268,7 @@ pthread_mutex_timedlock ( int e = INTERNAL_SYSCALL (futex_time64, __err, 4, &mutex->__data.__lock, __lll_private_flag (FUTEX_LOCK_PI, private), 1, - abstime); + abstime ? TO_TS64_P(abstime) : 0); #else int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock, __lll_private_flag (FUTEX_LOCK_PI, diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c index 4294a20b0..e168b3925 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c @@ -95,7 +95,7 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime) while ((tid = *tidp) != 0) { struct timeval tv; - struct timespec rt; + struct timespec rt, *rtp;
/* Get the current time. */ (void) __gettimeofday (&tv, NULL); @@ -115,7 +115,8 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime)
/* Wait until thread terminates. The kernel so far does not use the private futex operations for this. */ - if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) == -ETIMEDOUT) + rtp = &rt; + if (lll_futex_timed_wait (tidp, tid, rtp, LLL_SHARED) == -ETIMEDOUT) return ETIMEDOUT; }
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h index e72fe5234..909b0aad3 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h @@ -71,8 +71,31 @@ # endif #endif
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64) + #define lll_futex_wait(futexp, val, private) \ - lll_futex_timed_wait(futexp, val, NULL, private) + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAIT, private), \ + (val), NULL); \ + __ret; \ + }) + +#else + +#define lll_futex_wait(futexp, val, private) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAIT, private), \ + (val), NULL); \ + __ret; \ + }) + +#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
@@ -82,7 +105,7 @@ long int __ret; \ __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \ __lll_private_flag (FUTEX_WAIT, private), \ - (val), (timespec)); \ + (val), (TO_TS64_P(timespec))); \ __ret; \ })
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c index 7b4e84343..6403f7ea0 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c @@ -99,7 +99,6 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime, if (oldval != newval && atomic_compare_and_exchange_bool_acq (futex, newval, oldval)) continue; - lll_futex_timed_wait (futex, newval, &rt, private);
try: diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c index 80d242f21..4fa600cb6 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c @@ -56,7 +56,7 @@ timer_settime ( /* Delete the kernel timer object. */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) int res = INLINE_SYSCALL (timer_settime64, 4, kt->ktimerid, flags, - value, ovalue); + value ? TO_ITS64_P(value) : 0, ovalue); # else int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags, value, ovalue); diff --git a/librt/clock_gettime.c b/librt/clock_gettime.c index b66b60231..c514e1a54 100644 --- a/librt/clock_gettime.c +++ b/librt/clock_gettime.c @@ -24,8 +24,15 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) #define SYSCALL_GETTIME \ - retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, tp); \ - break + { \ + struct __ts64_struct __ts64; \ + retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, &__ts64); \ + if (tp) { \ + tp->tv_sec = __ts64.tv_sec; \ + tp->tv_nsec = __ts64.tv_nsec; \ + } \ + break; \ + } #else #define SYSCALL_GETTIME \ retval = INLINE_SYSCALL (clock_gettime, 2, clock_id, tp); \ diff --git a/librt/clock_nanosleep.c b/librt/clock_nanosleep.c index eaae75720..cb7b2afa3 100644 --- a/librt/clock_nanosleep.c +++ b/librt/clock_nanosleep.c @@ -21,7 +21,6 @@
#include "kernel-posix-cpu-timers.h"
- /* We can simply use the syscall. The CPU clocks are not supported with this function. */ int @@ -38,7 +37,7 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
if (SINGLE_THREAD_P) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64) - r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem); + r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req ? TO_TS64_P(req) : 0, rem); #else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); #endif @@ -47,7 +46,7 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, #ifdef __NEW_THREADS int oldstate = LIBC_CANCEL_ASYNC (); #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64) - r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem); + r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req ? TO_TS64_P(req): 0, rem); #else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); diff --git a/librt/mq_timedreceive.c b/librt/mq_timedreceive.c index db1ae1aa8..2570b6f9e 100644 --- a/librt/mq_timedreceive.c +++ b/librt/mq_timedreceive.c @@ -9,12 +9,14 @@ #include <cancel.h>
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedreceive_time64) -#define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive_time64 +int _NC(mq_timedreceive)(mqd_t mqdes, char *restrict msg_ptr, size_t msg_len, unsigned int *restrict msq_prio, const struct timespec *restrict abs_timeout) +{ + return INLINE_SYSCALL(mq_timedreceive_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, abs_timeout ? TO_TS64_P(abs_timeout) : 0); +} #else #define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive -#endif - _syscall5(ssize_t, __NC(mq_timedreceive), mqd_t, mqdes, char *__restrict, msg_ptr, size_t, msg_len, unsigned int *__restrict, msq_prio, const struct timespec *__restrict, abs_timeout) +#endif
CANCELLABLE_SYSCALL(ssize_t, mq_timedreceive, (mqd_t mqdes, char *__restrict msg_ptr, size_t msq_len, unsigned int *__restrict msq_prio, const struct timespec *__restrict abs_timeout), (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) diff --git a/librt/mq_timedsend.c b/librt/mq_timedsend.c index 6afaf5157..bcbc0685f 100644 --- a/librt/mq_timedsend.c +++ b/librt/mq_timedsend.c @@ -10,11 +10,15 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedsend_time64) #define __NR___mq_timedsend_nocancel __NR_mq_timedsend_time64 +int _NC(mq_timedsend)(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msq_prio, const struct timespec *abs_timeout) +{ + return INLINE_SYSCALL(mq_timedsend_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, abs_timeout ? TO_TS64_P(abs_timeout) : 0); +} #else #define __NR___mq_timedsend_nocancel __NR_mq_timedsend +_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) #endif
-_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) CANCELLABLE_SYSCALL(int, mq_timedsend, (mqd_t mqdes, const char *msg_ptr, size_t msq_len, unsigned int msq_prio, const struct timespec *abs_timeout), (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) lt_libc_hidden(mq_timedsend) diff --git a/librt/timer_settime.c b/librt/timer_settime.c index 022880297..6bf5f8307 100644 --- a/librt/timer_settime.c +++ b/librt/timer_settime.c @@ -12,10 +12,14 @@ #if defined(__NR_timer_settime) || defined(__NR_timer_settime64)
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) -#define __NR___syscall_timer_settime __NR_timer_settime64 +int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue) +{ + struct timer *kt = (struct timer *)timerid; + + return INLINE_SYSCALL(timer_settime64, 4, kt->ktimerid, flags, value ? TO_ITS64_P(value) : 0, ovalue); +} #else #define __NR___syscall_timer_settime __NR_timer_settime -#endif
static __inline__ _syscall4(int, __syscall_timer_settime, kernel_timer_t, ktimerid, int, flags, const void *, value, void *, ovalue); @@ -31,3 +35,4 @@ int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, }
#endif +#endif
Patch is splitted, intermediate pointers removed.
сб, 24 февр. 2024 г. в 19:09, Max Filippov jcmvbkbc@gmail.com:
On Sat, Feb 24, 2024 at 7:01 AM Dmitry Chestnykh dm.chestnykh@gmail.com wrote:
PowerPC is big-endian architecture, so there are some significant differences in comparison with time64 support for little-endian architectures like ARM and xtensa.
JFYI xtensa supports both little and big endianness. Which suggests that it needs similar treatment as a BE PPC.
The main difference is that we strictly need to pass two 64bit values to system calls because Linux Kernel internally uses `struct __ketnel_timespec` and similar, which consists of two 64bit fields. For this reason many files have been changed to convert timespec-family structures (mixed of 64bit and 32bit values) to the 64bit-only structures for using as system calls args. Now time64 syscalls works properly both for LE (ARM, xtensa) and BE (PPC) memory layouts.
I'd suggest splitting this change into two parts: generic arch-independent changes followed by PPC-specific changes.
Signed-off-by: Dmitry Chestnykh dm.chestnykh@gmail.com
extra/Configs/Config.in | 2 +- libc/inet/socketcalls.c | 16 ++++++++- libc/misc/sysvipc/sem.c | 16 ++++++++- libc/signal/sigwait.c | 3 +- libc/sysdeps/linux/common/__rt_sigtimedwait.c | 23 ++++++++++-- libc/sysdeps/linux/common/__rt_sigwaitinfo.c | 2 +- libc/sysdeps/linux/common/alarm.c | 2 +- libc/sysdeps/linux/common/clock_getres.c | 20 ++++++++++- libc/sysdeps/linux/common/clock_gettime.c | 21 ++++++++++- libc/sysdeps/linux/common/clock_settime.c | 17 ++++++++- libc/sysdeps/linux/common/ppoll.c | 15 +++++++- libc/sysdeps/linux/common/pselect.c | 15 +++++++- libc/sysdeps/linux/common/select.c | 23 +++++++++--- libc/sysdeps/linux/common/time.c | 2 +- libc/sysdeps/linux/common/timerfd.c | 23 +++++++++++- libc/sysdeps/linux/common/utimensat.c | 23 +++++++++++- libc/sysdeps/linux/powerpc/bits/kernel_stat.h | 28 +++++++++++++-- libc/sysdeps/linux/powerpc/bits/sem.h | 16 +++++++++ libpthread/nptl/pthread_mutex_timedlock.c | 20 +++++++++-- .../sysdeps/pthread/pthread_cond_timedwait.c | 5 +-- .../pthread/pthread_rwlock_timedrdlock.c | 5 +-- .../pthread/pthread_rwlock_timedwrlock.c | 5 +-- .../sysdeps/unix/sysv/linux/lowlevellock.c | 10 +++--- .../sysdeps/unix/sysv/linux/lowlevellock.h | 35 +++++++++++++++++-- .../unix/sysv/linux/lowlevelrobustlock.c | 6 ++-- .../sysdeps/unix/sysv/linux/sem_timedwait.c | 6 ++-- .../sysdeps/unix/sysv/linux/timer_settime.c | 19 +++++++++- librt/clock_gettime.c | 20 +++++++++-- librt/clock_nanosleep.c | 23 ++++++++++-- librt/mq_timedreceive.c | 22 ++++++++++-- librt/mq_timedsend.c | 20 ++++++++++- librt/timer_settime.c | 28 +++++++++++++-- 32 files changed, 435 insertions(+), 56 deletions(-)
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in index 9351dffc8..f11a63b79 100644 --- a/extra/Configs/Config.in +++ b/extra/Configs/Config.in @@ -1026,7 +1026,7 @@ config UCLIBC_FALLBACK_TO_ETC_LOCALTIME
config UCLIBC_USE_TIME64 bool "Use *time64 syscalls instead of 32bit ones (if possible)"
depends on TARGET_arm || TARGET_xtensa
depends on TARGET_arm || TARGET_powerpc || TARGET_xtensa # TODO: add support for other architectures default n
diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c index eb0983698..7ec439887 100644 --- a/libc/inet/socketcalls.c +++ b/libc/inet/socketcalls.c @@ -268,12 +268,26 @@ lt_libc_hidden(recvmsg) #endif
#ifdef L_recvmmsg
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#endif
This pattern and a similar pattern with struct its64_struct is repeated multiple times in this patch. It seems that this repetition can be easily avoided?
#ifdef __ASSUME_RECVMMSG_SYSCALL static ssize_t __NC(recvmmsg)(int sockfd, struct mmsghdr *msg, size_t
vlen,
int flags, struct timespec *tmo)
{ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_recvmmsg_time64)
return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg,
vlen, flags, tmo);
struct ts64_struct __ts64 = {
.tv_sec = tmo ? tmo->tv_sec : 0,
.tv_nsec = tmo ? tmo->tv_nsec : 0
};
return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg,
vlen, flags, tmo ? &__ts64 : 0);
# elif defined(__NR_recvmmsg) return (ssize_t)INLINE_SYSCALL(recvmmsg, 5, sockfd, msg, vlen,
flags, tmo);
# elif __NR_socketcall diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c index cd541761c..d0bd0ba28 100644 --- a/libc/misc/sysvipc/sem.c +++ b/libc/misc/sysvipc/sem.c @@ -96,7 +96,21 @@ int semop (int semid, struct sembuf *sops, size_t
nsops)
#ifdef L_semtimedop
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_semtimedop_time64) -_syscall4_time64(int, semtimedop, int, semid, struct sembuf *, sops,
size_t, nsops, const struct timespec *, timeout)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+int semtimedop(int semid, struct sembuf *sops, size_t nsops, const
struct timespec *timeout) {
- struct ts64_struct __ts64 = {
.tv_sec = timeout ? timeout->tv_sec : 0,
.tv_nsec = timeout ? timeout->tv_nsec : 0
- };
- return INLINE_SYSCALL(semtimedop_time64, 4, semid, sops, nsops,
timeout ? &__ts64 : 0);
+}
#elif defined(__NR_semtimedop) _syscall4(int, semtimedop, int, semid, struct sembuf *, sops, size_t,
nsops, const struct timespec *, timeout)
diff --git a/libc/signal/sigwait.c b/libc/signal/sigwait.c index 3557a039e..b237534cd 100644 --- a/libc/signal/sigwait.c +++ b/libc/signal/sigwait.c @@ -24,7 +24,8 @@ #include <signal.h> #include <cancel.h>
-#if defined __NR_rt_sigtimedwait && defined __UCLIBC_HAS_REALTIME__ +#if (defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__)
&& defined(__NR_rt_sigtimedwait_time64))) && \
- defined(__UCLIBC_HAS_REALTIME__)
#include <string.h>
diff --git a/libc/sysdeps/linux/common/__rt_sigtimedwait.c
b/libc/sysdeps/linux/common/__rt_sigtimedwait.c
index bd82ca6d5..cd25fe177 100644 --- a/libc/sysdeps/linux/common/__rt_sigtimedwait.c +++ b/libc/sysdeps/linux/common/__rt_sigtimedwait.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) ||
(defined(__NR_rt_sigtimedwait_time64) && defined(__UCLIBC_USE_TIME64__))
# include <signal.h> # include <cancel.h> # ifdef __UCLIBC_HAS_THREADS_NATIVE__ @@ -21,6 +21,15 @@ # include <string.h> # endif
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
__S64_TYPE tv_sec;
__S64_TYPE tv_nsec;
+};
+#endif
int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, const struct timespec *timeout) { @@ -53,8 +62,12 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t
*info,
real size of the user-level sigset_t. */ /* on uClibc we use the kernel sigset_t size */
# if defined(__UCLIBC_USE_TIME64__) &&
defined(__NR_rt_sigtimedwait_time64)
struct ts64_struct __ts64 = {
.tv_sec = timeout ? timeout->tv_sec : 0,
.tv_nsec = timeout ? timeout->tv_nsec : 0
}; result = INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
timeout, __SYSCALL_SIGSET_T_SIZE);
timeout ? &__ts64 : 0,
__SYSCALL_SIGSET_T_SIZE);
# else result = INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); @@ -71,8 +84,12 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t
*info,
# else /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) &&
defined(__NR_rt_sigtimedwait_time64)
struct ts64_struct __ts64 = {
.tv_sec = timeout ? timeout->tv_sec : 0,
.tv_nsec = timeout ? timeout->tv_nsec : 0
}; return INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
timeout, __SYSCALL_SIGSET_T_SIZE);
timeout ? &__ts64 : 0,
__SYSCALL_SIGSET_T_SIZE);
# else return INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); diff --git a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c
b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c
index d2d176a64..7830b2e2c 100644 --- a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c +++ b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c @@ -9,7 +9,7 @@
#include <sys/syscall.h>
-#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) &&
defined(__NR_rt_sigtimedwait_time64))
# define __need_NULL # include <stddef.h> # include <signal.h> diff --git a/libc/sysdeps/linux/common/alarm.c
b/libc/sysdeps/linux/common/alarm.c
index 4e6e2215b..861f6ad8e 100644 --- a/libc/sysdeps/linux/common/alarm.c +++ b/libc/sysdeps/linux/common/alarm.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <unistd.h>
-#ifdef __NR_alarm && !defined(__UCLIBC_USE_TIME64__) +#if defined(__NR_alarm) && !defined(__UCLIBC_USE_TIME64__) _syscall1(unsigned int, alarm, unsigned int, seconds) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/clock_getres.c
b/libc/sysdeps/linux/common/clock_getres.c
index d4b989958..c72b0a21c 100644 --- a/libc/sysdeps/linux/common/clock_getres.c +++ b/libc/sysdeps/linux/common/clock_getres.c @@ -10,9 +10,27 @@ #include <sys/syscall.h> #include <time.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
__S64_TYPE tv_sec;
__S64_TYPE tv_nsec;
+};
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64) -_syscall2_time64(int, clock_getres, clockid_t, clock_id, struct
timespec*, res)
+int clock_getres(clockid_t clock_id, struct timespec *res) +{
struct ts64_struct __ts64;
int __ret = INLINE_SYSCALL(clock_getres_time64, 2, clock_id,
&__ts64);
if (__ret == 0 && res) {
res->tv_sec = __ts64.tv_sec;
res->tv_nsec = __ts64.tv_nsec;
};
return __ret;
+} #elif defined(__NR_clock_getres) _syscall2(int, clock_getres, clockid_t, clock_id, struct timespec*, res) #else diff --git a/libc/sysdeps/linux/common/clock_gettime.c
b/libc/sysdeps/linux/common/clock_gettime.c
index a595bd691..dbb767c94 100644 --- a/libc/sysdeps/linux/common/clock_gettime.c +++ b/libc/sysdeps/linux/common/clock_gettime.c @@ -11,8 +11,27 @@ #include <sys/syscall.h> #include <time.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
__S64_TYPE tv_sec;
__S64_TYPE tv_nsec;
+};
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) -_syscall2_64(int, clock_gettime, clockid_t, clock_id, struct timespec*,
tp)
+int clock_gettime(clockid_t clock_id, struct timespec *tp) +{
struct ts64_struct __ts64;
int __ret = INLINE_SYSCALL(clock_gettime64, 2, clock_id,
&__ts64);
if (tp) {
tp->tv_sec = __ts64.tv_sec;
tp->tv_nsec = __ts64.tv_nsec;
}
return __ret;
+} #elif defined(__NR_clock_gettime) _syscall2(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/clock_settime.c
b/libc/sysdeps/linux/common/clock_settime.c
index 89550af5a..54bfa20e8 100644 --- a/libc/sysdeps/linux/common/clock_settime.c +++ b/libc/sysdeps/linux/common/clock_settime.c @@ -12,7 +12,22 @@
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_settime64) -_syscall2_64(int, clock_settime, clockid_t, clock_id, const struct
timespec*, tp)
+struct ts64_struct {
__S64_TYPE tv_sec;
__S64_TYPE tv_nsec;
+};
+int clock_settime(clockid_t clock_id, const struct timespec *tp) +{
struct ts64_struct __ts64 = {
.tv_sec = tp->tv_sec,
.tv_nsec = tp->tv_nsec
};
return INLINE_SYSCALL(clock_settime64, 2, clock_id, &__ts64);
+}
#elif defined(__NR_clock_settime) _syscall2(int, clock_settime, clockid_t, clock_id, const struct
timespec*, tp)
#else diff --git a/libc/sysdeps/linux/common/ppoll.c
b/libc/sysdeps/linux/common/ppoll.c
index cb36149c5..16d836b6f 100644 --- a/libc/sysdeps/linux/common/ppoll.c +++ b/libc/sysdeps/linux/common/ppoll.c @@ -26,6 +26,15 @@ #include <sys/poll.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#endif
static int __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec
*timeout,
const sigset_t *sigmask)
@@ -38,7 +47,11 @@ __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const
struct timespec *timeout,
timeout = &tval; }
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_ppoll_time64)
return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout,
sigmask, __SYSCALL_SIGSET_T_SIZE);
- struct ts64_struct __ts64 = {
.tv_sec = timeout ? timeout->tv_sec : 0,
.tv_nsec = timeout ? timeout->tv_nsec : 0
- };
return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout ?
&__ts64 : 0, sigmask, __SYSCALL_SIGSET_T_SIZE);
#else return INLINE_SYSCALL(ppoll, 5, fds, nfds, timeout, sigmask,
__SYSCALL_SIGSET_T_SIZE);
#endif diff --git a/libc/sysdeps/linux/common/pselect.c
b/libc/sysdeps/linux/common/pselect.c
index 23bdab5cf..a189624ec 100644 --- a/libc/sysdeps/linux/common/pselect.c +++ b/libc/sysdeps/linux/common/pselect.c @@ -26,6 +26,15 @@ #include <signal.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#endif
static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec
*timeout,
const sigset_t *sigmask)
@@ -57,7 +66,11 @@ static int __NC(pselect)(int nfds, fd_set *readfds,
fd_set *writefds,
sigmask = (void *)&data; }
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64)
return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds,
writefds, exceptfds, timeout, sigmask);
struct ts64_struct __ts64 = {
.tv_sec = timeout ? timeout->tv_sec : 0,
.tv_nsec = timeout ? timeout->tv_nsec : 0
};
return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds,
writefds, exceptfds, timeout ? &__ts64 : 0, sigmask);
#else return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds,
exceptfds, timeout, sigmask);
#endif diff --git a/libc/sysdeps/linux/common/select.c
b/libc/sysdeps/linux/common/select.c
index 3132a109c..a55a61df1 100644 --- a/libc/sysdeps/linux/common/select.c +++ b/libc/sysdeps/linux/common/select.c @@ -15,17 +15,22 @@ # define __NR_select __NR__newselect #endif
-#if !defined __NR_select && defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) # include <stdint.h> # define USEC_PER_SEC 1000000L #endif
+#if defined(__UCLIBC_USE_TIME64__) +struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+}; +#endif
int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set
*exceptfds,
struct timeval *timeout)
{ -#ifdef __NR_select
return INLINE_SYSCALL(select, 5, n, readfds, writefds,
exceptfds, timeout);
-#elif defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) struct timespec _ts, *ts = 0; if (timeout) { uint32_t usec; @@ -47,8 +52,18 @@ int __NC(select)(int n, fd_set *readfds, fd_set
*writefds, fd_set *exceptfds,
ts = &_ts; }
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64)
struct ts64_struct __ts64 = {
.tv_sec = ts ? ts->tv_sec : 0,
.tv_nsec = ts ? ts->tv_nsec : 0
};
return INLINE_SYSCALL(pselect6_time64, 6, n, readfds, writefds,
exceptfds, timeout ? &__ts64 : 0, 0);
+#else return INLINE_SYSCALL(pselect6, 6, n, readfds, writefds,
exceptfds, ts, 0);
#endif +#elif defined(__NR_select)
return INLINE_SYSCALL(select, 5, n, readfds, writefds,
exceptfds, timeout);
+#endif } /* we should guard it, but we need it in other files, so let it fail
- if we miss any of the syscalls */
diff --git a/libc/sysdeps/linux/common/time.c
b/libc/sysdeps/linux/common/time.c
index 22403f174..d084ffaad 100644 --- a/libc/sysdeps/linux/common/time.c +++ b/libc/sysdeps/linux/common/time.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <time.h>
-#ifdef __NR_time +#if defined(__NR_time) && !defined(__UCLIBC_USE_TIME64__) _syscall_noerr1(time_t, time, time_t *, t) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/timerfd.c
b/libc/sysdeps/linux/common/timerfd.c
index 0f19b44ed..04db6ed00 100644 --- a/libc/sysdeps/linux/common/timerfd.c +++ b/libc/sysdeps/linux/common/timerfd.c @@ -16,12 +16,33 @@ _syscall2(int, timerfd_create, int, clockid, int, flags) #endif
+#if defined(__UCLIBC_USE_TIME64__)
+struct its64_struct {
- __S64_TYPE interval_tv_sec;
- __S64_TYPE interval_tv_nsec;
- __S64_TYPE value_tv_sec;
- __S64_TYPE value_tv_nsec;
+};
+#endif
/*
- timerfd_settime()
*/ #if defined(__NR_timerfd_settime) || defined(__NR_timerfd_settime64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timerfd_settime64) -_syscall4_64(int, timerfd_settime, int, ufd, int, flags, const struct
itimerspec *, utmr, struct itimerspec *, otmr)
+int timerfd_settime(int ufd, int flags, const struct itimerspec *utmr,
struct itimerspec *otmr)
+{
- struct its64_struct __its64 = {
.interval_tv_sec = utmr->it_interval.tv_sec,
.interval_tv_nsec = utmr->it_interval.tv_nsec,
.value_tv_sec = utmr->it_value.tv_sec,
.value_tv_nsec = utmr->it_value.tv_nsec,
- };
- return INLINE_SYSCALL(timerfd_settime64, 4, ufd, flags, &__its64,
otmr);
+} #else _syscall4(int, timerfd_settime, int, ufd, int, flags, const struct
itimerspec *, utmr, struct itimerspec *, otmr)
#endif diff --git a/libc/sysdeps/linux/common/utimensat.c
b/libc/sysdeps/linux/common/utimensat.c
index 6a78ebb4f..0c87b5c45 100644 --- a/libc/sysdeps/linux/common/utimensat.c +++ b/libc/sysdeps/linux/common/utimensat.c @@ -9,9 +9,30 @@ #include <sys/syscall.h> #include <sys/stat.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct uts64_struct {
- __S64_TYPE tv_sec1;
- __S64_TYPE tv_nsec1;
- __S64_TYPE tv_sec2;
- __S64_TYPE tv_nsec2;
+};
+#endif
#if defined(__NR_utimensat) || defined(__NR_utimensat_time64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_utimensat_time64) -_syscall4_time64(int, utimensat, int, fd, const char *, path, const
struct timespec *, times, int, flags)
+int utimensat(int fd, const char *path, const struct timespec times[2],
int flags)
+{
- struct uts64_struct __uts64 = {
.tv_sec1 = times ? times[0].tv_sec : 0,
.tv_nsec1 = times ? times[0].tv_nsec : 0,
.tv_sec2 = times ? times[1].tv_sec : 0,
.tv_nsec2 = times ? times[1].tv_nsec : 0
- };
- return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ?
&__uts64 : 0, flags);
+} #else _syscall4(int, utimensat, int, fd, const char *, path, const struct
timespec *, times, int, flags)
#endif diff --git a/libc/sysdeps/linux/powerpc/bits/kernel_stat.h
b/libc/sysdeps/linux/powerpc/bits/kernel_stat.h
index ce62b2ba2..0e76120ab 100644 --- a/libc/sysdeps/linux/powerpc/bits/kernel_stat.h +++ b/libc/sysdeps/linux/powerpc/bits/kernel_stat.h @@ -5,6 +5,16 @@
- struct kernel_stat should look like... It turns out each arch has a
- different opinion on the subject... */
+#if defined(__UCLIBC_USE_TIME64__) +#include <bits/types.h>
+struct ts32_struct {
__S32_TYPE tv_sec;
__S32_TYPE tv_nsec;
+};
+#endif
#if __WORDSIZE == 64 #define kernel_stat kernel_stat64 #else @@ -19,9 +29,15 @@ struct kernel_stat { __kernel_off_t st_size; unsigned long st_blksize; unsigned long st_blocks; +#if defined(__UCLIBC_USE_TIME64__)
struct ts32_struct __st_atim32;
struct ts32_struct __st_mtim32;
struct ts32_struct __st_ctim32;
+#else struct timespec st_atim; struct timespec st_mtim; struct timespec st_ctim; +#endif unsigned long __unused4; unsigned long __unused5; }; @@ -39,9 +55,15 @@ struct kernel_stat64 { long long st_size; /* Size of file, in bytes. */ long st_blksize; /* Optimal block size for I/O.
*/
long long st_blocks; /* Number 512-byte blocks
allocated. */
struct timespec st_atim; /* Time of last access. */
struct timespec st_mtim; /* Time of last modification. */
struct timespec st_ctim; /* Time of last status change.
*/
+#if defined(__UCLIBC_USE_TIME64__)
struct ts32_struct __st_atim32;
struct ts32_struct __st_mtim32;
struct ts32_struct __st_ctim32;
+#else
struct timespec st_atim;
struct timespec st_mtim;
struct timespec st_ctim;
+#endif unsigned long int __uclibc_unused4; unsigned long int __uclibc_unused5; }; diff --git a/libc/sysdeps/linux/powerpc/bits/sem.h
b/libc/sysdeps/linux/powerpc/bits/sem.h
index a9d895374..8d338eac0 100644 --- a/libc/sysdeps/linux/powerpc/bits/sem.h +++ b/libc/sysdeps/linux/powerpc/bits/sem.h @@ -35,6 +35,7 @@ #define SETALL 17 /* set all semval's */
/* Data structure describing a set of semaphores. */ struct semid_ds { @@ -42,16 +43,31 @@ struct semid_ds #if __WORDSIZE == 32 unsigned int __uclibc_unused1; #endif +#if defined(__UCLIBC_USE_TIME64__)
- unsigned long int __sem_otime_internal_1; /* last semop() time */
- unsigned long int __sem_otime_internal_2;
+#else __time_t sem_otime; /* last semop() time */ +#endif #if __WORDSIZE == 32 unsigned int __uclibc_unused2; #endif +#if defined(__UCLIBC_USE_TIME64__)
- unsigned long int __sem_ctime_internal_1; /* last time changed by
semctl() */
- unsigned long int __sem_ctime_internal_2;
+#else __time_t sem_ctime; /* last time changed by semctl()
*/
+#endif unsigned long int sem_nsems; /* number of semaphores in set */ +#if defined(__UCLIBC_USE_TIME64__)
- __time_t sem_otime;
- __time_t sem_ctime;
+#endif unsigned long __uclibc_unused3; unsigned long __uclibc_unused4; };
/* The user should define a union like the following to use it for
arguments
for `semctl'.
diff --git a/libpthread/nptl/pthread_mutex_timedlock.c
b/libpthread/nptl/pthread_mutex_timedlock.c
index 25f9ec3b2..d55495683 100644 --- a/libpthread/nptl/pthread_mutex_timedlock.c +++ b/libpthread/nptl/pthread_mutex_timedlock.c @@ -23,6 +23,15 @@ #include <lowlevellock.h> #include <not-cancel.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#endif
/* We need to build this function with optimization to avoid
- lll_timedlock erroring out with
- error: can't find a register in class ‘GENERAL_REGS’ while reloading
‘asm’
@@ -265,10 +274,14 @@ pthread_mutex_timedlock ( INTERNAL_SYSCALL_DECL (__err);
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
struct ts64_struct __ts64 = {
.tv_sec = abstime ? abstime->tv_sec : 0,
.tv_nsec = abstime ? abstime->tv_nsec : 0
}; int e = INTERNAL_SYSCALL (futex_time64, __err, 4,
&mutex->__data.__lock,
__lll_private_flag (FUTEX_LOCK_PI, private), 1,
abstime);
&__ts64);
#else int e = INTERNAL_SYSCALL (futex, __err, 4,
&mutex->__data.__lock,
__lll_private_flag (FUTEX_LOCK_PI,
@@ -454,7 +467,7 @@ pthread_mutex_timedlock ( }
struct timeval tv;
struct timespec rt;
struct timespec rt, *rtp; /* Get the current time. */ (void) gettimeofday (&tv, NULL);
@@ -475,8 +488,9 @@ pthread_mutex_timedlock (
Starting from this hunk...
goto failpp; }
rtp = &rt; lll_futex_timed_wait (&mutex->__data.__lock,
ceilval | 2, &rt,
ceilval | 2, rtp, PTHREAD_MUTEX_PSHARED (mutex)); } }
diff --git a/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c
b/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c
index 49aab0293..1ea2a888a 100644 --- a/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c +++ b/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c @@ -95,7 +95,7 @@ __pthread_cond_timedwait (
while (1) {
struct timespec rt;
struct timespec rt, *rtp; {
#ifdef __NR_clock_gettime INTERNAL_SYSCALL_DECL (err); @@ -164,8 +164,9 @@ __pthread_cond_timedwait ( cbuffer.oldtype = __pthread_enable_asynccancel ();
/* Wait until woken by signal or broadcast. */
rtp = &rt; err = lll_futex_timed_wait (&cond->__data.__futex,
futex_val, &rt, pshared);
futex_val, rtp, pshared); /* Disable asynchronous cancellation. */ __pthread_disable_asynccancel (cbuffer.oldtype);
diff --git
a/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c b/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c
index 596f5df51..379e92b43 100644 --- a/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c +++ b/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedrdlock.c @@ -81,7 +81,7 @@ pthread_rwlock_timedrdlock ( (void) gettimeofday (&tv, NULL);
/* Convert the absolute timeout value to a relative timeout. */
struct timespec rt;
struct timespec rt, *rtp; rt.tv_sec = abstime->tv_sec - tv.tv_sec; rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000; if (rt.tv_nsec < 0)
@@ -112,8 +112,9 @@ pthread_rwlock_timedrdlock ( lll_unlock (rwlock->__data.__lock, rwlock->__data.__shared);
/* Wait for the writer to finish. */
rtp = &rt; err = lll_futex_timed_wait (&rwlock->__data.__readers_wakeup,
waitval, &rt, rwlock->__data.__shared);
waitval, rtp, rwlock->__data.__shared); /* Get the lock. */ lll_lock (rwlock->__data.__lock, rwlock->__data.__shared);
diff --git
a/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c b/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c
index 0b04b357a..3ce9f9b13 100644 --- a/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c +++ b/libpthread/nptl/sysdeps/pthread/pthread_rwlock_timedwrlock.c @@ -72,7 +72,7 @@ pthread_rwlock_timedwrlock ( (void) gettimeofday (&tv, NULL);
/* Convert the absolute timeout value to a relative timeout. */
struct timespec rt;
struct timespec rt, *rtp; rt.tv_sec = abstime->tv_sec - tv.tv_sec; rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000; if (rt.tv_nsec < 0)
@@ -102,8 +102,9 @@ pthread_rwlock_timedwrlock ( lll_unlock (rwlock->__data.__lock, rwlock->__data.__shared);
/* Wait for the writer or reader(s) to finish. */
rtp = &rt; err = lll_futex_timed_wait (&rwlock->__data.__writer_wakeup,
waitval, &rt, rwlock->__data.__shared);
waitval, rtp, rwlock->__data.__shared); /* Get the lock. */ lll_lock (rwlock->__data.__lock, rwlock->__data.__shared);
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c
b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c
index 4294a20b0..5f7301976 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c @@ -63,7 +63,7 @@ __lll_timedlock_wait (int *futex, const struct
timespec *abstime, int private)
(void) gettimeofday (&tv, NULL); /* Compute relative timeout. */
struct timespec rt;
struct timespec rt, *rtp; rt.tv_sec = abstime->tv_sec - tv.tv_sec; rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000; if (rt.tv_nsec < 0)
@@ -76,7 +76,8 @@ __lll_timedlock_wait (int *futex, const struct
timespec *abstime, int private)
return ETIMEDOUT; /* Wait. */
lll_futex_timed_wait (futex, 2, &rt, private);
rtp = &rt;
lll_futex_timed_wait (futex, 2, rtp, private);
}
return 0;
@@ -95,7 +96,7 @@ __lll_timedwait_tid (int *tidp, const struct timespec
*abstime)
while ((tid = *tidp) != 0) { struct timeval tv;
struct timespec rt;
struct timespec rt, *rtp; /* Get the current time. */ (void) __gettimeofday (&tv, NULL);
@@ -115,7 +116,8 @@ __lll_timedwait_tid (int *tidp, const struct
timespec *abstime)
/* Wait until thread terminates. The kernel so far does not use the private futex operations for this. */
if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) ==
-ETIMEDOUT)
rtp = &rt;
if (lll_futex_timed_wait (tidp, tid, rtp, LLL_SHARED) ==
-ETIMEDOUT)
return ETIMEDOUT; }
...and up to here: why are all these changes adding an intermediate pointer needed?
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h
b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h
index e72fe5234..4209a21d3 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h @@ -71,18 +71,49 @@ # endif #endif
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
#define lll_futex_wait(futexp, val, private) \
- lll_futex_timed_wait(futexp, val, NULL, private)
- ({
\
- INTERNAL_SYSCALL_DECL (__err);
\
- long int __ret;
\
- __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp),
\
__lll_private_flag (FUTEX_WAIT, private),
\
(val), NULL); \
- __ret;
\
- })
+#else
+#define lll_futex_wait(futexp, val, private) \
- ({
\
- INTERNAL_SYSCALL_DECL (__err);
\
- long int __ret;
\
- __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp),
\
__lll_private_flag (FUTEX_WAIT, private),
\
(val), NULL); \
- __ret;
\
- })
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+struct __ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#define ptr_timespec_to_ts64(ts) \
- (&(struct __ts64_struct) {.tv_sec = ts->tv_sec, .tv_nsec =
ts->tv_nsec})
#define lll_futex_timed_wait(futexp, val, timespec, private) \ ({
\
INTERNAL_SYSCALL_DECL (__err);
\
long int __ret;
\
__ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp),
\
__lll_private_flag (FUTEX_WAIT, private),
\
(val), (timespec));
\
(val), (ptr_timespec_to_ts64(timespec)));
\
__ret;
\
})
diff --git
a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
index 7b4e84343..5781359fb 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c @@ -73,7 +73,7 @@ __lll_robust_timedlock_wait (int *futex, const struct
timespec *abstime,
do { struct timeval tv;
struct timespec rt;
struct timespec rt, *rtp; /* Get the current time. */ (void) __gettimeofday (&tv, NULL);
@@ -99,8 +99,8 @@ __lll_robust_timedlock_wait (int *futex, const struct
timespec *abstime,
if (oldval != newval && atomic_compare_and_exchange_bool_acq (futex, newval,
oldval))
continue;
lll_futex_timed_wait (futex, newval, &rt, private);
rtp = &rt;
lll_futex_timed_wait (futex, newval, rtp, private);
try: ;
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
b/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c
index 8c3ef47c5..05ba5bc13 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c @@ -51,7 +51,7 @@ sem_timedwait (sem_t *sem, const struct timespec
*abstime)
while (1) { struct timeval tv;
struct timespec rt;
struct timespec rt, *rtp; int sec, nsec; /* Get the current time. */
@@ -79,10 +79,12 @@ sem_timedwait (sem_t *sem, const struct timespec
*abstime)
rt.tv_sec = sec; rt.tv_nsec = nsec;
rtp = &rt;
/* Enable asynchronous cancellation. Required by the standard.
*/
int oldtype = __pthread_enable_asynccancel ();
err = lll_futex_timed_wait (&isem->value, 0, &rt,
err = lll_futex_timed_wait (&isem->value, 0, rtp, isem->private ^ FUTEX_PRIVATE_FLAG); /* Disable asynchronous cancellation. */
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c
b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c
index 80d242f21..d7c2aa804 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c @@ -38,6 +38,17 @@ static int compat_timer_settime (timer_t timerid, int
flags,
# define timer_settime timer_settime_alias # endif
+#if defined(__UCLIBC_USE_TIME64__)
+struct its64_struct {
- __S64_TYPE interval_tv_sec;
- __S64_TYPE interval_tv_nsec;
- __S64_TYPE value_tv_sec;
- __S64_TYPE value_tv_nsec;
+};
+#endif
int timer_settime ( @@ -55,8 +66,14 @@ timer_settime (
/* Delete the kernel timer object. */
# if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64)
struct its64_struct __its64 = {
.interval_tv_sec = value->it_interval.tv_sec,
.interval_tv_nsec = value->it_interval.tv_nsec,
.value_tv_sec = value->it_value.tv_sec,
.value_tv_nsec = value->it_value.tv_nsec,
}; int res = INLINE_SYSCALL (timer_settime64, 4, kt->ktimerid, flags,
value, ovalue);
value ? &__its64 : 0, ovalue);
# else int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags, value, ovalue); diff --git a/librt/clock_gettime.c b/librt/clock_gettime.c index b66b60231..eff40d68f 100644 --- a/librt/clock_gettime.c +++ b/librt/clock_gettime.c @@ -22,10 +22,26 @@ #include <sys/time.h> #include "kernel-posix-cpu-timers.h"
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) #define SYSCALL_GETTIME \
- retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, tp); \
- break
- { \
- struct ts64_struct __ts64; \
- retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, &__ts64); \
- if (tp) { \
- tp->tv_sec = __ts64.tv_sec; \
- tp->tv_nsec = __ts64.tv_nsec; \
- } \
- break; \
- }
#else #define SYSCALL_GETTIME \ retval = INLINE_SYSCALL (clock_gettime, 2, clock_id, tp); \ diff --git a/librt/clock_nanosleep.c b/librt/clock_nanosleep.c index eaae75720..786f7eede 100644 --- a/librt/clock_nanosleep.c +++ b/librt/clock_nanosleep.c @@ -21,6 +21,14 @@
#include "kernel-posix-cpu-timers.h"
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
- __S64_TYPE tv_sec;
- __S64_TYPE tv_nsec;
+};
+#endif
/* We can simply use the syscall. The CPU clocks are not supported with this function. */ @@ -36,18 +44,27 @@ clock_nanosleep (clockid_t clock_id, int flags,
const struct timespec *req,
if (clock_id == CLOCK_PROCESS_CPUTIME_ID) clock_id = MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED);
- if (SINGLE_THREAD_P)
- if (SINGLE_THREAD_P) {
#if defined(__UCLIBC_USE_TIME64__) &&
defined(__NR_clock_nanosleep_time64)
- r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id,
flags, req, rem);
- struct ts64_struct __ts64 = {
.tv_sec = req ? req->tv_sec : 0,
.tv_nsec = req ? req->tv_nsec : 0
- };
- r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id,
flags, req ? &__ts64 : 0, rem);
#else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags,
req, rem);
#endif
- } else {
#ifdef __NEW_THREADS int oldstate = LIBC_CANCEL_ASYNC (); #if defined(__UCLIBC_USE_TIME64__) &&
defined(__NR_clock_nanosleep_time64)
r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id,
flags, req, rem);
struct ts64_struct __ts64_2 = {
.tv_sec = req ? req->tv_sec : 0,
.tv_nsec = req ? req->tv_nsec : 0
};
r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id,
flags, req ? &__ts64_2 : 0, rem);
#else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags,
req,
rem);
diff --git a/librt/mq_timedreceive.c b/librt/mq_timedreceive.c index db1ae1aa8..818f54faa 100644 --- a/librt/mq_timedreceive.c +++ b/librt/mq_timedreceive.c @@ -8,13 +8,29 @@ #include <unistd.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
__S64_TYPE tv_sec;
__S64_TYPE tv_nsec;
+};
+#endif
#if defined(__UCLIBC_USE_TIME64__) &&
defined(__NR_mq_timedreceive_time64)
-#define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive_time64 +int _NC(mq_timedreceive)(mqd_t mqdes, char *restrict msg_ptr, size_t
msg_len, unsigned int *restrict msq_prio, const struct timespec *restrict abs_timeout)
+{
struct ts64_struct __ts64 = {
.tv_sec = abs_timeout ? abs_timeout->tv_sec : 0,
.tv_nsec = abs_timeout ? abs_timeout->tv_nsec : 0,
};
return INLINE_SYSCALL(mq_timedreceive_time64, 5, mqdes, msg_ptr,
msg_len, msq_prio, abs_timeout ? &__ts64 : 0);
+} #else #define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive -#endif
_syscall5(ssize_t, __NC(mq_timedreceive), mqd_t, mqdes, char
*__restrict, msg_ptr, size_t, msg_len, unsigned int *__restrict, msq_prio, const struct timespec *__restrict, abs_timeout)
+#endif
CANCELLABLE_SYSCALL(ssize_t, mq_timedreceive, (mqd_t mqdes, char
*__restrict msg_ptr, size_t msq_len, unsigned int *__restrict msq_prio, const struct timespec *__restrict abs_timeout),
(mqdes, msg_ptr, msq_len, msq_prio, abs_timeout))
diff --git a/librt/mq_timedsend.c b/librt/mq_timedsend.c index 6afaf5157..e8deea9cb 100644 --- a/librt/mq_timedsend.c +++ b/librt/mq_timedsend.c @@ -8,13 +8,31 @@ #include <unistd.h> #include <cancel.h>
+#if defined(__UCLIBC_USE_TIME64__)
+struct ts64_struct {
__S64_TYPE tv_sec;
__S64_TYPE tv_nsec;
+};
+#endif
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedsend_time64) #define __NR___mq_timedsend_nocancel __NR_mq_timedsend_time64 +int _NC(mq_timedsend)(mqd_t mqdes, const char *msg_ptr, size_t msg_len,
unsigned int msq_prio, const struct timespec *abs_timeout)
+{
struct ts64_struct __ts64 = {
.tv_sec = abs_timeout ? abs_timeout->tv_sec : 0,
.tv_nsec = abs_timeout ? abs_timeout->tv_nsec : 0,
};
return INLINE_SYSCALL(mq_timedsend_time64, 5, mqdes, msg_ptr,
msg_len, msq_prio, abs_timeout ? &__ts64 : 0);
+} #else #define __NR___mq_timedsend_nocancel __NR_mq_timedsend +_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr,
size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout)
#endif
-_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr,
size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout)
CANCELLABLE_SYSCALL(int, mq_timedsend, (mqd_t mqdes, const char
*msg_ptr, size_t msq_len, unsigned int msq_prio, const struct timespec *abs_timeout),
(mqdes, msg_ptr, msq_len, msq_prio, abs_timeout))
lt_libc_hidden(mq_timedsend) diff --git a/librt/timer_settime.c b/librt/timer_settime.c index 022880297..31202b07a 100644 --- a/librt/timer_settime.c +++ b/librt/timer_settime.c @@ -9,13 +9,36 @@
#include "kernel-posix-timers.h"
+#if defined(__UCLIBC_USE_TIME64__)
+struct its64_struct {
- __S64_TYPE interval_tv_sec;
- __S64_TYPE interval_tv_nsec;
- __S64_TYPE value_tv_sec;
- __S64_TYPE value_tv_nsec;
+};
+#endif
#if defined(__NR_timer_settime) || defined(__NR_timer_settime64)
#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) -#define __NR___syscall_timer_settime __NR_timer_settime64 +int timer_settime(timer_t timerid, int flags, const struct itimerspec
*value, struct itimerspec *ovalue)
+{
struct timer *kt = (struct timer *)timerid;
- struct its64_struct __its64 = {
.interval_tv_sec = value->it_interval.tv_sec,
.interval_tv_nsec = value->it_interval.tv_nsec,
.value_tv_sec = value->it_value.tv_sec,
.value_tv_nsec = value->it_value.tv_nsec,
- };
return INLINE_SYSCALL(timer_settime64, 4, kt->ktimerid, flags,
value ? &__its64: 0, ovalue);
+} #else
#define __NR___syscall_timer_settime __NR_timer_settime -#endif
static __inline__ _syscall4(int, __syscall_timer_settime,
kernel_timer_t, ktimerid,
int, flags, const void *, value, void *, ovalue);
@@ -31,3 +54,4 @@ int timer_settime(timer_t timerid, int flags, const
struct itimerspec *value,
}
#endif
+#endif
2.43.2
devel mailing list -- devel@uclibc-ng.org To unsubscribe send an email to devel-leave@uclibc-ng.org
-- Thanks. -- Max
On Sat, Feb 24, 2024 at 10:29 AM Dmitriy Chestnykh dm.chestnykh@gmail.com wrote:
Patch is splitted, intermediate pointers removed.
Something isn't right with the submission, I can see multiple copies of the patch 1/2, but no 2/2. Also please add version tag to the subject line, i.e. 'PATCH v3' for the next submission round.