From c6e359dbc7bd155b10e15616d11e15c48b8bbefa Mon Sep 17 00:00:00 2001 From: Dmitry Chestnykh Date: Wed, 28 Feb 2024 11:45:09 +0300 Subject: libc: Pass 64bit-only time structures to syscalls. With time64 enabled we need to pass structure which consists of two 64bit fields to clock_gettime64() and clock_nanosleep_time64() syscalls with proper conversion to regular timespec structure after syscall execution. Signed-off-by: Dmitry Chestnykh --- libpthread/nptl/pthread_mutex_timedlock.c | 14 +++++++++++--- .../nptl/sysdeps/pthread/pthread_cond_timedwait.c | 15 ++++++++++++--- librt/clock_nanosleep.c | 21 ++++++++++++++++++--- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/libpthread/nptl/pthread_mutex_timedlock.c b/libpthread/nptl/pthread_mutex_timedlock.c index d54983315..1191639b6 100644 --- a/libpthread/nptl/pthread_mutex_timedlock.c +++ b/libpthread/nptl/pthread_mutex_timedlock.c @@ -298,11 +298,19 @@ pthread_mutex_timedlock ( /* Delay the thread until the timeout is reached. Then return ETIMEDOUT. */ struct timespec reltime; - struct timespec now; +#if defined(__UCLIBC_USE_TIME64__) + struct __ts64_struct __now64; +#endif + struct timespec now = {.tv_sec = 0, .tv_nsec = 0}; #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) - INTERNAL_SYSCALL (clock_gettime64, __err, 2, CLOCK_REALTIME, - &now); + int __r = INTERNAL_SYSCALL (clock_gettime64, __err, 2, CLOCK_REALTIME, + &__now64); + + if (__r == 0) { + now.tv_sec = __now64.tv_sec; + now.tv_nsec = __now64.tv_nsec; + } #else INTERNAL_SYSCALL (clock_gettime, __err, 2, CLOCK_REALTIME, &now); diff --git a/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c b/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c index 49aab0293..ce738b1a1 100644 --- a/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c +++ b/libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c @@ -95,18 +95,27 @@ __pthread_cond_timedwait ( while (1) { - struct timespec rt; + struct timespec rt = {.tv_sec = 0, .tv_nsec = 0}; +#if defined(__UCLIBC_USE_TIME64__) + struct __ts64_struct __rt64; +#endif { #ifdef __NR_clock_gettime INTERNAL_SYSCALL_DECL (err); -# ifndef __ASSUME_POSIX_TIMERS +# if !defined(__ASSUME_POSIX_TIMERS) || defined(__UCLIBC_USE_TIME64__) int ret = # endif #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) INTERNAL_SYSCALL (clock_gettime64, err, 2, (cond->__data.__nwaiters & ((1 << COND_NWAITERS_SHIFT) - 1)), - &rt); + &__rt64); + + if (ret == 0) { + rt.tv_sec = __rt64.tv_sec; + rt.tv_nsec = __rt64.tv_nsec; + } + #else INTERNAL_SYSCALL (clock_gettime, err, 2, (cond->__data.__nwaiters diff --git a/librt/clock_nanosleep.c b/librt/clock_nanosleep.c index ef59369df..5537b0609 100644 --- a/librt/clock_nanosleep.c +++ b/librt/clock_nanosleep.c @@ -39,18 +39,33 @@ 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, TO_TS64_P(req), rem); + struct __ts64_struct __req, __rem; + __req.tv_sec = req->tv_sec; + __req.tv_nsec = req->tv_nsec; + r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, &__req, &__rem); + if (rem) { + rem->tv_sec = (time_t) __rem.tv_sec; + rem->tv_nsec = __rem.tv_nsec; + } #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, TO_TS64_P(req), rem); + struct __ts64_struct __req, __rem; + __req.tv_sec = req->tv_sec; + __req.tv_nsec = req->tv_nsec; + r = INTERNAL_SYSCALL (clock_nanosleep_time64, err, 4, clock_id, flags, &__req, &__rem); + if (rem) { + rem->tv_sec = (time_t) __rem.tv_sec; + rem->tv_nsec = __rem.tv_nsec; + } #else r = INTERNAL_SYSCALL (clock_nanosleep, err, 4, clock_id, flags, req, rem); -- cgit v1.2.3