Patch is splitted, intermediate pointers removed.
сб, 24 февр. 2024 г. в 19:09, Max Filippov <jcmvbkbc(a)gmail.com>om>:
On Sat, Feb 24, 2024 at 7:01 AM Dmitry Chestnykh
<dm.chestnykh(a)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(a)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(a)uclibc-ng.org
To unsubscribe send an email to devel-leave(a)uclibc-ng.org
--
Thanks.
-- Max