Message ID | 20240225055533.2918452-1-dm.chestnykh@gmail.com |
---|---|
State | Superseded |
Headers | show |
Series | [uclibc-ng-devel,v3,1/2] Add support for using time64 on big-endian machines. | expand |
On Sat, Feb 24, 2024 at 9:59 PM Dmitry Chestnykh <dm.chestnykh@gmail.com> wrote: > > For BE architectures there is one significant difference > in comparison with time64 support for little-endian > architectures like ARMv7. > The difference is that we strictly need to pass two 64bit > values to system calls because Linux Kernel internally uses > `struct __kernel_timespec` and similar, which consists of two > 64bit fields. > For this reason many files have been changed to convert > pointers to timespec-family structures (mixed of 64bit and 32bit values) > to the pointer of the similar but 64bit-only structures > for using as system calls args. > This is general prerequisite for any BE architecture. > > Signed-off-by: Dmitry Chestnykh <dm.chestnykh@gmail.com> > --- > Moved __ts64_struct, __its64_struct and related macroses > to the new private header, did some cleanups. > include/internal/time64_helpers.h | 27 ++++++++++++++++ > libc/inet/socketcalls.c | 6 +++- > libc/misc/sysvipc/sem.c | 9 +++++- > libc/signal/sigwait.c | 3 +- > libc/sysdeps/linux/common/__rt_sigtimedwait.c | 10 ++++-- > libc/sysdeps/linux/common/__rt_sigwaitinfo.c | 2 +- > libc/sysdeps/linux/common/alarm.c | 2 +- > libc/sysdeps/linux/common/clock_getres.c | 15 +++++++-- > libc/sysdeps/linux/common/clock_gettime.c | 14 ++++++++- > libc/sysdeps/linux/common/clock_settime.c | 7 ++++- > libc/sysdeps/linux/common/ppoll.c | 6 +++- > libc/sysdeps/linux/common/pselect.c | 6 +++- > libc/sysdeps/linux/common/select.c | 16 +++++++--- > libc/sysdeps/linux/common/time.c | 2 +- > libc/sysdeps/linux/common/timerfd.c | 9 +++++- > libc/sysdeps/linux/common/utimensat.c | 20 +++++++++++- > libpthread/nptl/pthread_mutex_timedlock.c | 6 +++- > .../sysdeps/unix/sysv/linux/lowlevellock.h | 31 +++++++++++++++++-- > .../sysdeps/unix/sysv/linux/timer_settime.c | 5 ++- > librt/clock_gettime.c | 17 ++++++++-- > librt/clock_nanosleep.c | 7 +++-- > librt/mq_timedreceive.c | 10 ++++-- > librt/mq_timedsend.c | 9 ++++-- > librt/timer_settime.c | 11 +++++-- > 24 files changed, 213 insertions(+), 37 deletions(-) > create mode 100644 include/internal/time64_helpers.h > > diff --git a/include/internal/time64_helpers.h b/include/internal/time64_helpers.h > new file mode 100644 > index 000000000..897874fb3 > --- /dev/null > +++ b/include/internal/time64_helpers.h > @@ -0,0 +1,27 @@ > +#ifndef _TIME64_HELPERS_H > +#define _TIME64_HELPERS_H > + > +#include <bits/types.h> > +#include <stddef.h> > + > +struct __ts64_struct { > + __S64_TYPE tv_sec; > + __S64_TYPE tv_nsec; > +}; > + > +#define TO_TS64_P(__ts) ((__ts) ? (&(struct __ts64_struct) {.tv_sec = (__ts)->tv_sec, .tv_nsec = (__ts)->tv_nsec}) : NULL) > + > +struct __its64_struct { > + __S64_TYPE interval_tv_sec; > + __S64_TYPE interval_tv_nsec; > + __S64_TYPE value_tv_sec; > + __S64_TYPE value_tv_nsec; > +}; > + > +#define TO_ITS64_P(__its) ((__its) ? (&(struct __its64_struct) {.interval_tv_sec = (__its)->it_interval.tv_sec, \ > + .interval_tv_nsec = (__its)->it_interval.tv_nsec, \ > + .value_tv_sec = (__its)->it_value.tv_sec, \ > + .value_tv_nsec = (__its)->it_value.tv_nsec}) : NULL) > + > + > +#endif /* _TIME64_HELPERS_H */ > \ No newline at end of file Please add one. > diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c > index eb0983698..774ed6091 100644 > --- a/libc/inet/socketcalls.c > +++ b/libc/inet/socketcalls.c > @@ -10,6 +10,10 @@ > #include <cancel.h> > #include <bits/kernel-features.h> > > +#if defined(__UCLIBC_USE_TIME64__) > +#include "internal/time64_helpers.h" > +#endif > + > #ifdef __NR_socketcall > /* Various socketcall numbers */ > #define SYS_SOCKET 1 > @@ -273,7 +277,7 @@ static ssize_t __NC(recvmmsg)(int sockfd, struct mmsghdr *msg, size_t vlen, > int flags, struct timespec *tmo) > { > # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_recvmmsg_time64) > - return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo); > + return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, TO_TS64_P(tmo)); > # elif defined(__NR_recvmmsg) > return (ssize_t)INLINE_SYSCALL(recvmmsg, 5, sockfd, msg, vlen, flags, tmo); > # elif __NR_socketcall > diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c > index cd541761c..07076eff7 100644 > --- a/libc/misc/sysvipc/sem.c > +++ b/libc/misc/sysvipc/sem.c > @@ -23,6 +23,9 @@ > > #include "ipc.h" > > +#if defined(__UCLIBC_USE_TIME64__) > +#include "internal/time64_helpers.h" > +#endif > > #ifdef L_semctl > /* Return identifier for array of NSEMS semaphores associated with > @@ -96,7 +99,11 @@ int semop (int semid, struct sembuf *sops, size_t nsops) > #ifdef L_semtimedop > > #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_semtimedop_time64) > -_syscall4_time64(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout) > +int semtimedop(int semid, struct sembuf *sops, size_t nsops, const struct timespec *timeout) > +{ > + return INLINE_SYSCALL(semtimedop_time64, 4, semid, sops, nsops, TO_TS64_P(timeout)); > +} > + > #elif defined(__NR_semtimedop) > _syscall4(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout) > > diff --git a/libc/signal/sigwait.c b/libc/signal/sigwait.c > index 3557a039e..b237534cd 100644 > --- a/libc/signal/sigwait.c > +++ b/libc/signal/sigwait.c > @@ -24,7 +24,8 @@ > #include <signal.h> > #include <cancel.h> > > -#if defined __NR_rt_sigtimedwait && defined __UCLIBC_HAS_REALTIME__ > +#if (defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64))) && \ > + defined(__UCLIBC_HAS_REALTIME__) > > #include <string.h> > > diff --git a/libc/sysdeps/linux/common/__rt_sigtimedwait.c b/libc/sysdeps/linux/common/__rt_sigtimedwait.c > index bd82ca6d5..aff5299a1 100644 > --- a/libc/sysdeps/linux/common/__rt_sigtimedwait.c > +++ b/libc/sysdeps/linux/common/__rt_sigtimedwait.c > @@ -9,7 +9,7 @@ > > #include <sys/syscall.h> > > -#ifdef __NR_rt_sigtimedwait > +#if defined(__NR_rt_sigtimedwait) || (defined(__NR_rt_sigtimedwait_time64) && defined(__UCLIBC_USE_TIME64__)) > # include <signal.h> > # include <cancel.h> > # ifdef __UCLIBC_HAS_THREADS_NATIVE__ > @@ -21,6 +21,10 @@ > # include <string.h> > # endif > > +#if defined(__UCLIBC_USE_TIME64__) > +#include "internal/time64_helpers.h" > +#endif > + > int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, > const struct timespec *timeout) > { > @@ -54,7 +58,7 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, > /* on uClibc we use the kernel sigset_t size */ > # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64) > result = INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info, > - timeout, __SYSCALL_SIGSET_T_SIZE); > + TO_TS64_P(timeout), __SYSCALL_SIGSET_T_SIZE); > # else > result = INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, > timeout, __SYSCALL_SIGSET_T_SIZE); > @@ -72,7 +76,7 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, > /* on uClibc we use the kernel sigset_t size */ > # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64) > return INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info, > - timeout, __SYSCALL_SIGSET_T_SIZE); > + TO_TS64_P(timeout), __SYSCALL_SIGSET_T_SIZE); > # else > return INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, > timeout, __SYSCALL_SIGSET_T_SIZE); > diff --git a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c > index d2d176a64..7830b2e2c 100644 > --- a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c > +++ b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c > @@ -9,7 +9,7 @@ > > #include <sys/syscall.h> > > -#ifdef __NR_rt_sigtimedwait > +#if defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)) > # define __need_NULL > # include <stddef.h> > # include <signal.h> > diff --git a/libc/sysdeps/linux/common/alarm.c b/libc/sysdeps/linux/common/alarm.c > index 4e6e2215b..861f6ad8e 100644 > --- a/libc/sysdeps/linux/common/alarm.c > +++ b/libc/sysdeps/linux/common/alarm.c > @@ -9,7 +9,7 @@ > #include <sys/syscall.h> > #include <unistd.h> > > -#ifdef __NR_alarm && !defined(__UCLIBC_USE_TIME64__) > +#if defined(__NR_alarm) && !defined(__UCLIBC_USE_TIME64__) > _syscall1(unsigned int, alarm, unsigned int, seconds) > #else > # include <sys/time.h> > diff --git a/libc/sysdeps/linux/common/clock_getres.c b/libc/sysdeps/linux/common/clock_getres.c > index d4b989958..fd0f8c14c 100644 > --- a/libc/sysdeps/linux/common/clock_getres.c > +++ b/libc/sysdeps/linux/common/clock_getres.c > @@ -10,9 +10,20 @@ > #include <sys/syscall.h> > #include <time.h> > > - > #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64) > -_syscall2_time64(int, clock_getres, clockid_t, clock_id, struct timespec*, res) > +#include "internal/time64_helpers.h" > + > +int clock_getres(clockid_t clock_id, struct timespec *res) > +{ > + struct __ts64_struct __ts64; > + int __ret = INLINE_SYSCALL(clock_getres_time64, 2, clock_id, &__ts64); > + if (__ret == 0 && res) { > + res->tv_sec = __ts64.tv_sec; > + res->tv_nsec = __ts64.tv_nsec; > + }; > + > + return __ret; > +} > #elif defined(__NR_clock_getres) > _syscall2(int, clock_getres, clockid_t, clock_id, struct timespec*, res) > #else > diff --git a/libc/sysdeps/linux/common/clock_gettime.c b/libc/sysdeps/linux/common/clock_gettime.c > index a595bd691..4d787b9b7 100644 > --- a/libc/sysdeps/linux/common/clock_gettime.c > +++ b/libc/sysdeps/linux/common/clock_gettime.c > @@ -12,7 +12,19 @@ > #include <time.h> > > #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) > -_syscall2_64(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) > +#include "internal/time64_helpers.h" > + > +int clock_gettime(clockid_t clock_id, struct timespec *tp) > +{ > + struct __ts64_struct __ts64; > + int __ret = INLINE_SYSCALL(clock_gettime64, 2, clock_id, &__ts64); > + if (tp) { > + tp->tv_sec = __ts64.tv_sec; > + tp->tv_nsec = __ts64.tv_nsec; > + } > + > + return __ret; > +} > #elif defined(__NR_clock_gettime) > _syscall2(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) > #else > diff --git a/libc/sysdeps/linux/common/clock_settime.c b/libc/sysdeps/linux/common/clock_settime.c > index 89550af5a..3abc5f49b 100644 > --- a/libc/sysdeps/linux/common/clock_settime.c > +++ b/libc/sysdeps/linux/common/clock_settime.c > @@ -12,7 +12,12 @@ > > > #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_settime64) > -_syscall2_64(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) > +#include "internal/time64_helpers.h" > + > +int clock_settime(clockid_t clock_id, const struct timespec *tp) > +{ > + return INLINE_SYSCALL(clock_settime64, 2, clock_id, TO_TS64_P(tp)); > +} > #elif defined(__NR_clock_settime) > _syscall2(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) > #else > diff --git a/libc/sysdeps/linux/common/ppoll.c b/libc/sysdeps/linux/common/ppoll.c > index cb36149c5..870717bd7 100644 > --- a/libc/sysdeps/linux/common/ppoll.c > +++ b/libc/sysdeps/linux/common/ppoll.c > @@ -26,6 +26,10 @@ > #include <sys/poll.h> > #include <cancel.h> > > +#if defined(__UCLIBC_USE_TIME64__) > +#include "internal/time64_helpers.h" > +#endif > + > static int > __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, > const sigset_t *sigmask) > @@ -38,7 +42,7 @@ __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, > timeout = &tval; > } > #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_ppoll_time64) > - return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE); > + return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, TO_TS64_P(timeout), sigmask, __SYSCALL_SIGSET_T_SIZE); > #else > return INLINE_SYSCALL(ppoll, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE); > #endif > diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c > index 23bdab5cf..7a446a589 100644 > --- a/libc/sysdeps/linux/common/pselect.c > +++ b/libc/sysdeps/linux/common/pselect.c > @@ -26,6 +26,10 @@ > #include <signal.h> > #include <cancel.h> > > +#if defined(__UCLIBC_USE_TIME64__) > +#include "internal/time64_helpers.h" > +#endif > + > static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, > fd_set *exceptfds, const struct timespec *timeout, > const sigset_t *sigmask) > @@ -57,7 +61,7 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, > sigmask = (void *)&data; > } > #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64) > - return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask); > + return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, TO_TS64_P(timeout), sigmask); > #else > return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask); > #endif > diff --git a/libc/sysdeps/linux/common/select.c b/libc/sysdeps/linux/common/select.c > index 3132a109c..84016dd0b 100644 > --- a/libc/sysdeps/linux/common/select.c > +++ b/libc/sysdeps/linux/common/select.c > @@ -15,17 +15,19 @@ > # define __NR_select __NR__newselect > #endif > > -#if !defined __NR_select && defined __NR_pselect6 > +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) > # include <stdint.h> > # define USEC_PER_SEC 1000000L > #endif > > +#if defined(__UCLIBC_USE_TIME64__) > +#include "internal/time64_helpers.h" > +#endif > + > int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, > struct timeval *timeout) > { > -#ifdef __NR_select > - return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, timeout); > -#elif defined __NR_pselect6 > +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) > struct timespec _ts, *ts = 0; > if (timeout) { > uint32_t usec; > @@ -47,8 +49,14 @@ int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, > > ts = &_ts; > } > +#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64) > + return INLINE_SYSCALL(pselect6_time64, 6, n, readfds, writefds, exceptfds, TO_TS64_P(ts), 0); > +#else > return INLINE_SYSCALL(pselect6, 6, n, readfds, writefds, exceptfds, ts, 0); > #endif > +#elif defined(__NR_select) > + return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, ts); > +#endif > } > /* we should guard it, but we need it in other files, so let it fail > * if we miss any of the syscalls */ > diff --git a/libc/sysdeps/linux/common/time.c b/libc/sysdeps/linux/common/time.c > index 22403f174..d084ffaad 100644 > --- a/libc/sysdeps/linux/common/time.c > +++ b/libc/sysdeps/linux/common/time.c > @@ -9,7 +9,7 @@ > #include <sys/syscall.h> > #include <time.h> > > -#ifdef __NR_time > +#if defined(__NR_time) && !defined(__UCLIBC_USE_TIME64__) > _syscall_noerr1(time_t, time, time_t *, t) > #else > # include <sys/time.h> > diff --git a/libc/sysdeps/linux/common/timerfd.c b/libc/sysdeps/linux/common/timerfd.c > index 0f19b44ed..b4a9e1a93 100644 > --- a/libc/sysdeps/linux/common/timerfd.c > +++ b/libc/sysdeps/linux/common/timerfd.c > @@ -9,6 +9,10 @@ > #include <sys/syscall.h> > #include <sys/timerfd.h> > > +#if defined(__UCLIBC_USE_TIME64__) > +#include "internal/time64_helpers.h" > +#endif > + > /* > * timerfd_create() > */ > @@ -21,7 +25,10 @@ _syscall2(int, timerfd_create, int, clockid, int, flags) > */ > #if defined(__NR_timerfd_settime) || defined(__NR_timerfd_settime64) > #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timerfd_settime64) > -_syscall4_64(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) > +int timerfd_settime(int ufd, int flags, const struct itimerspec *utmr, struct itimerspec *otmr) > +{ > + return INLINE_SYSCALL(timerfd_settime64, 4, ufd, flags, TO_ITS64_P(utmr), otmr); > +} > #else > _syscall4(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) > #endif > diff --git a/libc/sysdeps/linux/common/utimensat.c b/libc/sysdeps/linux/common/utimensat.c > index 6a78ebb4f..fa6f90e55 100644 > --- a/libc/sysdeps/linux/common/utimensat.c > +++ b/libc/sysdeps/linux/common/utimensat.c > @@ -9,9 +9,27 @@ > #include <sys/syscall.h> > #include <sys/stat.h> > > +#if defined(__UCLIBC_USE_TIME64__) > +#include "internal/time64_helpers.h" > +#endif > + > #if defined(__NR_utimensat) || defined(__NR_utimensat_time64) > #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_utimensat_time64) > -_syscall4_time64(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) > +int utimensat(int fd, const char *path, const struct timespec times[2], int flags) > +{ > + struct __ts64_struct __times64[2] = { > + { > + .tv_sec = times ? times[0].tv_sec : 0, > + .tv_nsec = times ? times[0].tv_nsec : 0 > + }, > + { > + .tv_sec = times ? times[1].tv_sec : 0, > + .tv_nsec = times ? times[1].tv_nsec : 0 > + } > + }; > + > + return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ? &__times64 : 0, flags); > +} > #else > _syscall4(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) > #endif > diff --git a/libpthread/nptl/pthread_mutex_timedlock.c b/libpthread/nptl/pthread_mutex_timedlock.c > index 25f9ec3b2..446275e67 100644 > --- a/libpthread/nptl/pthread_mutex_timedlock.c > +++ b/libpthread/nptl/pthread_mutex_timedlock.c > @@ -23,6 +23,10 @@ > #include <lowlevellock.h> > #include <not-cancel.h> > > +#if defined(__UCLIBC_USE_TIME64__) > +#include "internal/time64_helpers.h" > +#endif > + > /* We need to build this function with optimization to avoid > * lll_timedlock erroring out with > * error: can't find a register in class ‘GENERAL_REGS’ while reloading ‘asm’ > @@ -268,7 +272,7 @@ pthread_mutex_timedlock ( > int e = INTERNAL_SYSCALL (futex_time64, __err, 4, &mutex->__data.__lock, > __lll_private_flag (FUTEX_LOCK_PI, > private), 1, > - abstime); > + abstime ? TO_TS64_P(abstime) : 0); Ternary operator is not needed. > #else > int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock, > __lll_private_flag (FUTEX_LOCK_PI, > diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h > index e72fe5234..86941b1f2 100644 > --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h > +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h > @@ -24,6 +24,10 @@ > #include <sysdep.h> > #include <bits/kernel-features.h> > > +#if defined(__UCLIBC_USE_TIME64__) > +#include "internal/time64_helpers.h" > +#endif > + > #define FUTEX_WAIT 0 > #define FUTEX_WAKE 1 > #define FUTEX_REQUEUE 3 > @@ -71,8 +75,31 @@ > # endif > #endif > > +#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64) > + > #define lll_futex_wait(futexp, val, private) \ > - lll_futex_timed_wait(futexp, val, NULL, private) Why not just leave this definition? Aren't the compilers good enough to eliminate the ternary operator with a constant condition? > + ({ \ > + INTERNAL_SYSCALL_DECL (__err); \ > + long int __ret; \ > + __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \ > + __lll_private_flag (FUTEX_WAIT, private), \ > + (val), NULL); \ > + __ret; \ > + }) > + > +#else > + > +#define lll_futex_wait(futexp, val, private) \ > + ({ \ > + INTERNAL_SYSCALL_DECL (__err); \ > + long int __ret; \ > + __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ > + __lll_private_flag (FUTEX_WAIT, private), \ > + (val), NULL); \ > + __ret; \ > + }) > + > +#endif > > #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64) > > @@ -82,7 +109,7 @@ > long int __ret; \ > __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \ > __lll_private_flag (FUTEX_WAIT, private), \ > - (val), (timespec)); \ > + (val), (TO_TS64_P(timespec))); \ > __ret; \ > }) > > diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c > index 80d242f21..1cccf57cb 100644 > --- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c > +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c > @@ -23,6 +23,9 @@ > #include <bits/kernel-features.h> > #include "kernel-posix-timers.h" > > +#if defined(__UCLIBC_USE_TIME64__) > +#include "internal/time64_helpers.h" > +#endif > > #ifdef __NR_timer_settime > # ifndef __ASSUME_POSIX_TIMERS > @@ -56,7 +59,7 @@ timer_settime ( > /* Delete the kernel timer object. */ > # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) > int res = INLINE_SYSCALL (timer_settime64, 4, kt->ktimerid, flags, > - value, ovalue); > + TO_ITS64_P(value), ovalue); > # else > int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags, > value, ovalue); > diff --git a/librt/clock_gettime.c b/librt/clock_gettime.c > index b66b60231..eab9a3343 100644 > --- a/librt/clock_gettime.c > +++ b/librt/clock_gettime.c > @@ -22,10 +22,21 @@ > #include <sys/time.h> > #include "kernel-posix-cpu-timers.h" > > +#if defined(__UCLIBC_USE_TIME64__) > +#include "internal/time64_helpers.h" > +#endif > + > #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) > -#define SYSCALL_GETTIME \ > - retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, tp); \ > - break > +#define SYSCALL_GETTIME \ > + { \ > + struct __ts64_struct __ts64; \ > + retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, &__ts64); \ > + if (tp) { \ > + tp->tv_sec = __ts64.tv_sec; \ > + tp->tv_nsec = __ts64.tv_nsec; \ > + } \ > + break; \ > + } > #else > #define SYSCALL_GETTIME \ > retval = INLINE_SYSCALL (clock_gettime, 2, clock_id, tp); \ > diff --git a/librt/clock_nanosleep.c b/librt/clock_nanosleep.c > index eaae75720..ef59369df 100644 > --- a/librt/clock_nanosleep.c > +++ b/librt/clock_nanosleep.c > @@ -21,6 +21,9 @@ > > #include "kernel-posix-cpu-timers.h" > > +#if defined(__UCLIBC_USE_TIME64__) > +#include "internal/time64_helpers.h" > +#endif > > /* We can simply use the syscall. The CPU clocks are not supported > with this function. */ > @@ -38,7 +41,7 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, > > if (SINGLE_THREAD_P) > #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64) > - r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem); > + r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, TO_TS64_P(req), rem); > #else > r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); > #endif > @@ -47,7 +50,7 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, > #ifdef __NEW_THREADS > int oldstate = LIBC_CANCEL_ASYNC (); > #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64) > - r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem); > + r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, TO_TS64_P(req), rem); > #else > r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, > rem); > diff --git a/librt/mq_timedreceive.c b/librt/mq_timedreceive.c > index db1ae1aa8..f89b4c36b 100644 > --- a/librt/mq_timedreceive.c > +++ b/librt/mq_timedreceive.c > @@ -9,12 +9,16 @@ > #include <cancel.h> > > #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedreceive_time64) > -#define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive_time64 > +#include "internal/time64_helpers.h" > + > +int _NC(mq_timedreceive)(mqd_t mqdes, char *restrict msg_ptr, size_t msg_len, unsigned int *restrict msq_prio, const struct timespec *restrict abs_timeout) > +{ > + return INLINE_SYSCALL(mq_timedreceive_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, TO_TS64_P(abs_timeout)); > +} > #else > #define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive > -#endif > - > _syscall5(ssize_t, __NC(mq_timedreceive), mqd_t, mqdes, char *__restrict, msg_ptr, size_t, msg_len, unsigned int *__restrict, msq_prio, const struct timespec *__restrict, abs_timeout) > +#endif > > CANCELLABLE_SYSCALL(ssize_t, mq_timedreceive, (mqd_t mqdes, char *__restrict msg_ptr, size_t msq_len, unsigned int *__restrict msq_prio, const struct timespec *__restrict abs_timeout), > (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) > diff --git a/librt/mq_timedsend.c b/librt/mq_timedsend.c > index 6afaf5157..b081ac0ce 100644 > --- a/librt/mq_timedsend.c > +++ b/librt/mq_timedsend.c > @@ -9,12 +9,17 @@ > #include <cancel.h> > > #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedsend_time64) > -#define __NR___mq_timedsend_nocancel __NR_mq_timedsend_time64 > +#include "internal/time64_helpers.h" > + > +int _NC(mq_timedsend)(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msq_prio, const struct timespec *abs_timeout) > +{ > + return INLINE_SYSCALL(mq_timedsend_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, TO_TS64_P(abs_timeout)); > +} > #else > #define __NR___mq_timedsend_nocancel __NR_mq_timedsend > +_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) > #endif > > -_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) > CANCELLABLE_SYSCALL(int, mq_timedsend, (mqd_t mqdes, const char *msg_ptr, size_t msq_len, unsigned int msq_prio, const struct timespec *abs_timeout), > (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) > lt_libc_hidden(mq_timedsend) > diff --git a/librt/timer_settime.c b/librt/timer_settime.c > index 022880297..425cd7ee9 100644 > --- a/librt/timer_settime.c > +++ b/librt/timer_settime.c > @@ -12,10 +12,16 @@ > #if defined(__NR_timer_settime) || defined(__NR_timer_settime64) > > #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) > -#define __NR___syscall_timer_settime __NR_timer_settime64 > +#include "internal/time64_helpers.h" > + > +int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue) > +{ > + struct timer *kt = (struct timer *)timerid; > + > + return INLINE_SYSCALL(timer_settime64, 4, kt->ktimerid, flags, TO_ITS64_P(value), ovalue); > +} > #else > #define __NR___syscall_timer_settime __NR_timer_settime > -#endif > > static __inline__ _syscall4(int, __syscall_timer_settime, kernel_timer_t, ktimerid, > int, flags, const void *, value, void *, ovalue); > @@ -31,3 +37,4 @@ int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, > } > > #endif > +#endif > -- > 2.43.2 > > _______________________________________________ > devel mailing list -- devel@uclibc-ng.org > To unsubscribe send an email to devel-leave@uclibc-ng.org
diff --git a/include/internal/time64_helpers.h b/include/internal/time64_helpers.h new file mode 100644 index 000000000..897874fb3 --- /dev/null +++ b/include/internal/time64_helpers.h @@ -0,0 +1,27 @@ +#ifndef _TIME64_HELPERS_H +#define _TIME64_HELPERS_H + +#include <bits/types.h> +#include <stddef.h> + +struct __ts64_struct { + __S64_TYPE tv_sec; + __S64_TYPE tv_nsec; +}; + +#define TO_TS64_P(__ts) ((__ts) ? (&(struct __ts64_struct) {.tv_sec = (__ts)->tv_sec, .tv_nsec = (__ts)->tv_nsec}) : NULL) + +struct __its64_struct { + __S64_TYPE interval_tv_sec; + __S64_TYPE interval_tv_nsec; + __S64_TYPE value_tv_sec; + __S64_TYPE value_tv_nsec; +}; + +#define TO_ITS64_P(__its) ((__its) ? (&(struct __its64_struct) {.interval_tv_sec = (__its)->it_interval.tv_sec, \ + .interval_tv_nsec = (__its)->it_interval.tv_nsec, \ + .value_tv_sec = (__its)->it_value.tv_sec, \ + .value_tv_nsec = (__its)->it_value.tv_nsec}) : NULL) + + +#endif /* _TIME64_HELPERS_H */ \ No newline at end of file diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c index eb0983698..774ed6091 100644 --- a/libc/inet/socketcalls.c +++ b/libc/inet/socketcalls.c @@ -10,6 +10,10 @@ #include <cancel.h> #include <bits/kernel-features.h> +#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + #ifdef __NR_socketcall /* Various socketcall numbers */ #define SYS_SOCKET 1 @@ -273,7 +277,7 @@ static ssize_t __NC(recvmmsg)(int sockfd, struct mmsghdr *msg, size_t vlen, int flags, struct timespec *tmo) { # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_recvmmsg_time64) - return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo); + return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, TO_TS64_P(tmo)); # elif defined(__NR_recvmmsg) return (ssize_t)INLINE_SYSCALL(recvmmsg, 5, sockfd, msg, vlen, flags, tmo); # elif __NR_socketcall diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c index cd541761c..07076eff7 100644 --- a/libc/misc/sysvipc/sem.c +++ b/libc/misc/sysvipc/sem.c @@ -23,6 +23,9 @@ #include "ipc.h" +#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif #ifdef L_semctl /* Return identifier for array of NSEMS semaphores associated with @@ -96,7 +99,11 @@ int semop (int semid, struct sembuf *sops, size_t nsops) #ifdef L_semtimedop #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_semtimedop_time64) -_syscall4_time64(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout) +int semtimedop(int semid, struct sembuf *sops, size_t nsops, const struct timespec *timeout) +{ + return INLINE_SYSCALL(semtimedop_time64, 4, semid, sops, nsops, TO_TS64_P(timeout)); +} + #elif defined(__NR_semtimedop) _syscall4(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout) diff --git a/libc/signal/sigwait.c b/libc/signal/sigwait.c index 3557a039e..b237534cd 100644 --- a/libc/signal/sigwait.c +++ b/libc/signal/sigwait.c @@ -24,7 +24,8 @@ #include <signal.h> #include <cancel.h> -#if defined __NR_rt_sigtimedwait && defined __UCLIBC_HAS_REALTIME__ +#if (defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64))) && \ + defined(__UCLIBC_HAS_REALTIME__) #include <string.h> diff --git a/libc/sysdeps/linux/common/__rt_sigtimedwait.c b/libc/sysdeps/linux/common/__rt_sigtimedwait.c index bd82ca6d5..aff5299a1 100644 --- a/libc/sysdeps/linux/common/__rt_sigtimedwait.c +++ b/libc/sysdeps/linux/common/__rt_sigtimedwait.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> -#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__NR_rt_sigtimedwait_time64) && defined(__UCLIBC_USE_TIME64__)) # include <signal.h> # include <cancel.h> # ifdef __UCLIBC_HAS_THREADS_NATIVE__ @@ -21,6 +21,10 @@ # include <string.h> # endif +#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, const struct timespec *timeout) { @@ -54,7 +58,7 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64) result = INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info, - timeout, __SYSCALL_SIGSET_T_SIZE); + TO_TS64_P(timeout), __SYSCALL_SIGSET_T_SIZE); # else result = INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); @@ -72,7 +76,7 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info, /* on uClibc we use the kernel sigset_t size */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64) return INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info, - timeout, __SYSCALL_SIGSET_T_SIZE); + TO_TS64_P(timeout), __SYSCALL_SIGSET_T_SIZE); # else return INLINE_SYSCALL(rt_sigtimedwait, 4, set, info, timeout, __SYSCALL_SIGSET_T_SIZE); diff --git a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c index d2d176a64..7830b2e2c 100644 --- a/libc/sysdeps/linux/common/__rt_sigwaitinfo.c +++ b/libc/sysdeps/linux/common/__rt_sigwaitinfo.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> -#ifdef __NR_rt_sigtimedwait +#if defined(__NR_rt_sigtimedwait) || (defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)) # define __need_NULL # include <stddef.h> # include <signal.h> diff --git a/libc/sysdeps/linux/common/alarm.c b/libc/sysdeps/linux/common/alarm.c index 4e6e2215b..861f6ad8e 100644 --- a/libc/sysdeps/linux/common/alarm.c +++ b/libc/sysdeps/linux/common/alarm.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <unistd.h> -#ifdef __NR_alarm && !defined(__UCLIBC_USE_TIME64__) +#if defined(__NR_alarm) && !defined(__UCLIBC_USE_TIME64__) _syscall1(unsigned int, alarm, unsigned int, seconds) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/clock_getres.c b/libc/sysdeps/linux/common/clock_getres.c index d4b989958..fd0f8c14c 100644 --- a/libc/sysdeps/linux/common/clock_getres.c +++ b/libc/sysdeps/linux/common/clock_getres.c @@ -10,9 +10,20 @@ #include <sys/syscall.h> #include <time.h> - #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64) -_syscall2_time64(int, clock_getres, clockid_t, clock_id, struct timespec*, res) +#include "internal/time64_helpers.h" + +int clock_getres(clockid_t clock_id, struct timespec *res) +{ + struct __ts64_struct __ts64; + int __ret = INLINE_SYSCALL(clock_getres_time64, 2, clock_id, &__ts64); + if (__ret == 0 && res) { + res->tv_sec = __ts64.tv_sec; + res->tv_nsec = __ts64.tv_nsec; + }; + + return __ret; +} #elif defined(__NR_clock_getres) _syscall2(int, clock_getres, clockid_t, clock_id, struct timespec*, res) #else diff --git a/libc/sysdeps/linux/common/clock_gettime.c b/libc/sysdeps/linux/common/clock_gettime.c index a595bd691..4d787b9b7 100644 --- a/libc/sysdeps/linux/common/clock_gettime.c +++ b/libc/sysdeps/linux/common/clock_gettime.c @@ -12,7 +12,19 @@ #include <time.h> #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) -_syscall2_64(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) +#include "internal/time64_helpers.h" + +int clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + struct __ts64_struct __ts64; + int __ret = INLINE_SYSCALL(clock_gettime64, 2, clock_id, &__ts64); + if (tp) { + tp->tv_sec = __ts64.tv_sec; + tp->tv_nsec = __ts64.tv_nsec; + } + + return __ret; +} #elif defined(__NR_clock_gettime) _syscall2(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/clock_settime.c b/libc/sysdeps/linux/common/clock_settime.c index 89550af5a..3abc5f49b 100644 --- a/libc/sysdeps/linux/common/clock_settime.c +++ b/libc/sysdeps/linux/common/clock_settime.c @@ -12,7 +12,12 @@ #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_settime64) -_syscall2_64(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) +#include "internal/time64_helpers.h" + +int clock_settime(clockid_t clock_id, const struct timespec *tp) +{ + return INLINE_SYSCALL(clock_settime64, 2, clock_id, TO_TS64_P(tp)); +} #elif defined(__NR_clock_settime) _syscall2(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp) #else diff --git a/libc/sysdeps/linux/common/ppoll.c b/libc/sysdeps/linux/common/ppoll.c index cb36149c5..870717bd7 100644 --- a/libc/sysdeps/linux/common/ppoll.c +++ b/libc/sysdeps/linux/common/ppoll.c @@ -26,6 +26,10 @@ #include <sys/poll.h> #include <cancel.h> +#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + static int __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, const sigset_t *sigmask) @@ -38,7 +42,7 @@ __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, timeout = &tval; } #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_ppoll_time64) - return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE); + return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, TO_TS64_P(timeout), sigmask, __SYSCALL_SIGSET_T_SIZE); #else return INLINE_SYSCALL(ppoll, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE); #endif diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c index 23bdab5cf..7a446a589 100644 --- a/libc/sysdeps/linux/common/pselect.c +++ b/libc/sysdeps/linux/common/pselect.c @@ -26,6 +26,10 @@ #include <signal.h> #include <cancel.h> +#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask) @@ -57,7 +61,7 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, sigmask = (void *)&data; } #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64) - return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask); + return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, TO_TS64_P(timeout), sigmask); #else return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask); #endif diff --git a/libc/sysdeps/linux/common/select.c b/libc/sysdeps/linux/common/select.c index 3132a109c..84016dd0b 100644 --- a/libc/sysdeps/linux/common/select.c +++ b/libc/sysdeps/linux/common/select.c @@ -15,17 +15,19 @@ # define __NR_select __NR__newselect #endif -#if !defined __NR_select && defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) # include <stdint.h> # define USEC_PER_SEC 1000000L #endif +#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { -#ifdef __NR_select - return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, timeout); -#elif defined __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) struct timespec _ts, *ts = 0; if (timeout) { uint32_t usec; @@ -47,8 +49,14 @@ int __NC(select)(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, ts = &_ts; } +#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64) + return INLINE_SYSCALL(pselect6_time64, 6, n, readfds, writefds, exceptfds, TO_TS64_P(ts), 0); +#else return INLINE_SYSCALL(pselect6, 6, n, readfds, writefds, exceptfds, ts, 0); #endif +#elif defined(__NR_select) + return INLINE_SYSCALL(select, 5, n, readfds, writefds, exceptfds, ts); +#endif } /* we should guard it, but we need it in other files, so let it fail * if we miss any of the syscalls */ diff --git a/libc/sysdeps/linux/common/time.c b/libc/sysdeps/linux/common/time.c index 22403f174..d084ffaad 100644 --- a/libc/sysdeps/linux/common/time.c +++ b/libc/sysdeps/linux/common/time.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <time.h> -#ifdef __NR_time +#if defined(__NR_time) && !defined(__UCLIBC_USE_TIME64__) _syscall_noerr1(time_t, time, time_t *, t) #else # include <sys/time.h> diff --git a/libc/sysdeps/linux/common/timerfd.c b/libc/sysdeps/linux/common/timerfd.c index 0f19b44ed..b4a9e1a93 100644 --- a/libc/sysdeps/linux/common/timerfd.c +++ b/libc/sysdeps/linux/common/timerfd.c @@ -9,6 +9,10 @@ #include <sys/syscall.h> #include <sys/timerfd.h> +#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + /* * timerfd_create() */ @@ -21,7 +25,10 @@ _syscall2(int, timerfd_create, int, clockid, int, flags) */ #if defined(__NR_timerfd_settime) || defined(__NR_timerfd_settime64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timerfd_settime64) -_syscall4_64(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) +int timerfd_settime(int ufd, int flags, const struct itimerspec *utmr, struct itimerspec *otmr) +{ + return INLINE_SYSCALL(timerfd_settime64, 4, ufd, flags, TO_ITS64_P(utmr), otmr); +} #else _syscall4(int, timerfd_settime, int, ufd, int, flags, const struct itimerspec *, utmr, struct itimerspec *, otmr) #endif diff --git a/libc/sysdeps/linux/common/utimensat.c b/libc/sysdeps/linux/common/utimensat.c index 6a78ebb4f..fa6f90e55 100644 --- a/libc/sysdeps/linux/common/utimensat.c +++ b/libc/sysdeps/linux/common/utimensat.c @@ -9,9 +9,27 @@ #include <sys/syscall.h> #include <sys/stat.h> +#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + #if defined(__NR_utimensat) || defined(__NR_utimensat_time64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_utimensat_time64) -_syscall4_time64(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) +int utimensat(int fd, const char *path, const struct timespec times[2], int flags) +{ + struct __ts64_struct __times64[2] = { + { + .tv_sec = times ? times[0].tv_sec : 0, + .tv_nsec = times ? times[0].tv_nsec : 0 + }, + { + .tv_sec = times ? times[1].tv_sec : 0, + .tv_nsec = times ? times[1].tv_nsec : 0 + } + }; + + return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ? &__times64 : 0, flags); +} #else _syscall4(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) #endif diff --git a/libpthread/nptl/pthread_mutex_timedlock.c b/libpthread/nptl/pthread_mutex_timedlock.c index 25f9ec3b2..446275e67 100644 --- a/libpthread/nptl/pthread_mutex_timedlock.c +++ b/libpthread/nptl/pthread_mutex_timedlock.c @@ -23,6 +23,10 @@ #include <lowlevellock.h> #include <not-cancel.h> +#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + /* We need to build this function with optimization to avoid * lll_timedlock erroring out with * error: can't find a register in class ‘GENERAL_REGS’ while reloading ‘asm’ @@ -268,7 +272,7 @@ pthread_mutex_timedlock ( int e = INTERNAL_SYSCALL (futex_time64, __err, 4, &mutex->__data.__lock, __lll_private_flag (FUTEX_LOCK_PI, private), 1, - abstime); + abstime ? TO_TS64_P(abstime) : 0); #else int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock, __lll_private_flag (FUTEX_LOCK_PI, diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h index e72fe5234..86941b1f2 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h @@ -24,6 +24,10 @@ #include <sysdep.h> #include <bits/kernel-features.h> +#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + #define FUTEX_WAIT 0 #define FUTEX_WAKE 1 #define FUTEX_REQUEUE 3 @@ -71,8 +75,31 @@ # endif #endif +#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64) + #define lll_futex_wait(futexp, val, private) \ - lll_futex_timed_wait(futexp, val, NULL, private) + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAIT, private), \ + (val), NULL); \ + __ret; \ + }) + +#else + +#define lll_futex_wait(futexp, val, private) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAIT, private), \ + (val), NULL); \ + __ret; \ + }) + +#endif #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64) @@ -82,7 +109,7 @@ long int __ret; \ __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (futexp), \ __lll_private_flag (FUTEX_WAIT, private), \ - (val), (timespec)); \ + (val), (TO_TS64_P(timespec))); \ __ret; \ }) diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c index 80d242f21..1cccf57cb 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c @@ -23,6 +23,9 @@ #include <bits/kernel-features.h> #include "kernel-posix-timers.h" +#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif #ifdef __NR_timer_settime # ifndef __ASSUME_POSIX_TIMERS @@ -56,7 +59,7 @@ timer_settime ( /* Delete the kernel timer object. */ # if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) int res = INLINE_SYSCALL (timer_settime64, 4, kt->ktimerid, flags, - value, ovalue); + TO_ITS64_P(value), ovalue); # else int res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags, value, ovalue); diff --git a/librt/clock_gettime.c b/librt/clock_gettime.c index b66b60231..eab9a3343 100644 --- a/librt/clock_gettime.c +++ b/librt/clock_gettime.c @@ -22,10 +22,21 @@ #include <sys/time.h> #include "kernel-posix-cpu-timers.h" +#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif + #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) -#define SYSCALL_GETTIME \ - retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, tp); \ - break +#define SYSCALL_GETTIME \ + { \ + struct __ts64_struct __ts64; \ + retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, &__ts64); \ + if (tp) { \ + tp->tv_sec = __ts64.tv_sec; \ + tp->tv_nsec = __ts64.tv_nsec; \ + } \ + break; \ + } #else #define SYSCALL_GETTIME \ retval = INLINE_SYSCALL (clock_gettime, 2, clock_id, tp); \ diff --git a/librt/clock_nanosleep.c b/librt/clock_nanosleep.c index eaae75720..ef59369df 100644 --- a/librt/clock_nanosleep.c +++ b/librt/clock_nanosleep.c @@ -21,6 +21,9 @@ #include "kernel-posix-cpu-timers.h" +#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif /* We can simply use the syscall. The CPU clocks are not supported with this function. */ @@ -38,7 +41,7 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, if (SINGLE_THREAD_P) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64) - r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem); + r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, TO_TS64_P(req), rem); #else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); #endif @@ -47,7 +50,7 @@ clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, #ifdef __NEW_THREADS int oldstate = LIBC_CANCEL_ASYNC (); #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_nanosleep_time64) - r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, req, rem); + r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, TO_TS64_P(req), rem); #else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); diff --git a/librt/mq_timedreceive.c b/librt/mq_timedreceive.c index db1ae1aa8..f89b4c36b 100644 --- a/librt/mq_timedreceive.c +++ b/librt/mq_timedreceive.c @@ -9,12 +9,16 @@ #include <cancel.h> #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedreceive_time64) -#define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive_time64 +#include "internal/time64_helpers.h" + +int _NC(mq_timedreceive)(mqd_t mqdes, char *restrict msg_ptr, size_t msg_len, unsigned int *restrict msq_prio, const struct timespec *restrict abs_timeout) +{ + return INLINE_SYSCALL(mq_timedreceive_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, TO_TS64_P(abs_timeout)); +} #else #define __NR___mq_timedreceive_nocancel __NR_mq_timedreceive -#endif - _syscall5(ssize_t, __NC(mq_timedreceive), mqd_t, mqdes, char *__restrict, msg_ptr, size_t, msg_len, unsigned int *__restrict, msq_prio, const struct timespec *__restrict, abs_timeout) +#endif CANCELLABLE_SYSCALL(ssize_t, mq_timedreceive, (mqd_t mqdes, char *__restrict msg_ptr, size_t msq_len, unsigned int *__restrict msq_prio, const struct timespec *__restrict abs_timeout), (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) diff --git a/librt/mq_timedsend.c b/librt/mq_timedsend.c index 6afaf5157..b081ac0ce 100644 --- a/librt/mq_timedsend.c +++ b/librt/mq_timedsend.c @@ -9,12 +9,17 @@ #include <cancel.h> #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_mq_timedsend_time64) -#define __NR___mq_timedsend_nocancel __NR_mq_timedsend_time64 +#include "internal/time64_helpers.h" + +int _NC(mq_timedsend)(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msq_prio, const struct timespec *abs_timeout) +{ + return INLINE_SYSCALL(mq_timedsend_time64, 5, mqdes, msg_ptr, msg_len, msq_prio, TO_TS64_P(abs_timeout)); +} #else #define __NR___mq_timedsend_nocancel __NR_mq_timedsend +_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) #endif -_syscall5(int, __NC(mq_timedsend), mqd_t, mqdes, const char *, msg_ptr, size_t, msg_len, unsigned int, msq_prio, const struct timespec *, abs_timeout) CANCELLABLE_SYSCALL(int, mq_timedsend, (mqd_t mqdes, const char *msg_ptr, size_t msq_len, unsigned int msq_prio, const struct timespec *abs_timeout), (mqdes, msg_ptr, msq_len, msq_prio, abs_timeout)) lt_libc_hidden(mq_timedsend) diff --git a/librt/timer_settime.c b/librt/timer_settime.c index 022880297..425cd7ee9 100644 --- a/librt/timer_settime.c +++ b/librt/timer_settime.c @@ -12,10 +12,16 @@ #if defined(__NR_timer_settime) || defined(__NR_timer_settime64) #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_timer_settime64) -#define __NR___syscall_timer_settime __NR_timer_settime64 +#include "internal/time64_helpers.h" + +int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue) +{ + struct timer *kt = (struct timer *)timerid; + + return INLINE_SYSCALL(timer_settime64, 4, kt->ktimerid, flags, TO_ITS64_P(value), ovalue); +} #else #define __NR___syscall_timer_settime __NR_timer_settime -#endif static __inline__ _syscall4(int, __syscall_timer_settime, kernel_timer_t, ktimerid, int, flags, const void *, value, void *, ovalue); @@ -31,3 +37,4 @@ int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, } #endif +#endif
For BE architectures there is one significant difference in comparison with time64 support for little-endian architectures like ARMv7. The difference is that we strictly need to pass two 64bit values to system calls because Linux Kernel internally uses `struct __kernel_timespec` and similar, which consists of two 64bit fields. For this reason many files have been changed to convert pointers to timespec-family structures (mixed of 64bit and 32bit values) to the pointer of the similar but 64bit-only structures for using as system calls args. This is general prerequisite for any BE architecture. Signed-off-by: Dmitry Chestnykh <dm.chestnykh@gmail.com> --- Moved __ts64_struct, __its64_struct and related macroses to the new private header, did some cleanups. include/internal/time64_helpers.h | 27 ++++++++++++++++ libc/inet/socketcalls.c | 6 +++- libc/misc/sysvipc/sem.c | 9 +++++- libc/signal/sigwait.c | 3 +- libc/sysdeps/linux/common/__rt_sigtimedwait.c | 10 ++++-- libc/sysdeps/linux/common/__rt_sigwaitinfo.c | 2 +- libc/sysdeps/linux/common/alarm.c | 2 +- libc/sysdeps/linux/common/clock_getres.c | 15 +++++++-- libc/sysdeps/linux/common/clock_gettime.c | 14 ++++++++- libc/sysdeps/linux/common/clock_settime.c | 7 ++++- libc/sysdeps/linux/common/ppoll.c | 6 +++- libc/sysdeps/linux/common/pselect.c | 6 +++- libc/sysdeps/linux/common/select.c | 16 +++++++--- libc/sysdeps/linux/common/time.c | 2 +- libc/sysdeps/linux/common/timerfd.c | 9 +++++- libc/sysdeps/linux/common/utimensat.c | 20 +++++++++++- libpthread/nptl/pthread_mutex_timedlock.c | 6 +++- .../sysdeps/unix/sysv/linux/lowlevellock.h | 31 +++++++++++++++++-- .../sysdeps/unix/sysv/linux/timer_settime.c | 5 ++- librt/clock_gettime.c | 17 ++++++++-- librt/clock_nanosleep.c | 7 +++-- librt/mq_timedreceive.c | 10 ++++-- librt/mq_timedsend.c | 9 ++++-- librt/timer_settime.c | 11 +++++-- 24 files changed, 213 insertions(+), 37 deletions(-) create mode 100644 include/internal/time64_helpers.h