Message ID | 20240224150047.1039669-1-dm.chestnykh@gmail.com |
---|---|
State | Superseded |
Headers | show |
Series | [uclibc-ng-devel] Add time64 support for PowerPC. | expand |
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 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 >
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.
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
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(-)