summaryrefslogtreecommitdiff
path: root/librt
diff options
context:
space:
mode:
authorDmitry Chestnykh <dm.chestnykh@gmail.com>2024-02-25 14:43:28 +0300
committerWaldemar Brodkorb <wbx@openadk.org>2024-02-25 19:27:48 +0100
commit81ed334f67e0c56ff0a89ade0fc156c0ba23f190 (patch)
tree09829cc5cd0d03a4f91887864f6a3c28213549af /librt
parent086a5f165096af104b01bb6d5639bd769bd17620 (diff)
Add support for using time64 on big-endian machines.
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>
Diffstat (limited to 'librt')
-rw-r--r--librt/clock_gettime.c17
-rw-r--r--librt/clock_nanosleep.c7
-rw-r--r--librt/mq_timedreceive.c10
-rw-r--r--librt/mq_timedsend.c9
-rw-r--r--librt/timer_settime.c11
5 files changed, 42 insertions, 12 deletions
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