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