summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Chestnykh <dm.chestnykh@gmail.com>2024-02-26 13:21:26 +0300
committerWaldemar Brodkorb <wbx@openadk.org>2024-02-26 11:28:42 +0100
commit73017bba9d3bc0f8ada159319ff590117c9e5689 (patch)
tree05f6d950a0ef0702f9513085cd9d66cef7d7a1bb
parentfb800e73a9c81a299f55de7a3aba4a0c3ab074e0 (diff)
Add time64 support for MIPS32.
Signed-off-by: Dmitry Chestnykh <dm.chestnykh@gmail.com>
-rw-r--r--extra/Configs/Config.in5
-rw-r--r--libc/sysdeps/linux/common/fstatat.c2
-rw-r--r--libc/sysdeps/linux/common/xstatconv.c6
-rw-r--r--libc/sysdeps/linux/mips/bits/kernel_stat.h4
-rw-r--r--libc/sysdeps/linux/mips/bits/sem.h13
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/mips/lowlevellock.h61
6 files changed, 85 insertions, 6 deletions
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
index f11a63b79..c7c502040 100644
--- a/extra/Configs/Config.in
+++ b/extra/Configs/Config.in
@@ -1026,7 +1026,10 @@ 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_powerpc || TARGET_xtensa
+ depends on TARGET_arm || \
+ (TARGET_mips && !CONFIG_MIPS_N64_ABI) || \
+ TARGET_powerpc || \
+ TARGET_xtensa
# TODO: add support for other architectures
default n
diff --git a/libc/sysdeps/linux/common/fstatat.c b/libc/sysdeps/linux/common/fstatat.c
index 8064722d2..d4f566a62 100644
--- a/libc/sysdeps/linux/common/fstatat.c
+++ b/libc/sysdeps/linux/common/fstatat.c
@@ -62,7 +62,7 @@ int fstatat(int fd, const char *file, struct stat *buf, int flag)
.st_mtim.tv_nsec = tmp.stx_mtime.tv_nsec,
.st_ctim.tv_sec = tmp.stx_ctime.tv_sec,
.st_ctim.tv_nsec = tmp.stx_ctime.tv_nsec,
-#if defined(__UCLIBC_USE_TIME64__)
+#if defined(__UCLIBC_USE_TIME64__) && !defined(__mips__)
.__st_atim32.tv_sec = stx.stx_atime.tv_sec,
.__st_atim32.tv_nsec = stx.stx_atime.tv_nsec,
.__st_mtim32.tv_sec = stx.stx_mtime.tv_sec,
diff --git a/libc/sysdeps/linux/common/xstatconv.c b/libc/sysdeps/linux/common/xstatconv.c
index 4b0a7424e..391804e66 100644
--- a/libc/sysdeps/linux/common/xstatconv.c
+++ b/libc/sysdeps/linux/common/xstatconv.c
@@ -37,7 +37,7 @@ void __xstat_conv(struct kernel_stat *kbuf, struct stat *buf)
buf->st_size = kbuf->st_size;
buf->st_blksize = kbuf->st_blksize;
buf->st_blocks = kbuf->st_blocks;
-#if defined(__UCLIBC_USE_TIME64__)
+#if defined(__UCLIBC_USE_TIME64__) && !defined(__mips__)
buf->st_atim.tv_sec = kbuf->__st_atim32.tv_sec;
buf->st_atim.tv_nsec = kbuf->__st_atim32.tv_nsec;
buf->st_mtim.tv_sec = kbuf->__st_mtim32.tv_sec;
@@ -68,7 +68,7 @@ void __xstat32_conv(struct kernel_stat64 *kbuf, struct stat *buf)
buf->st_size = kbuf->st_size;
buf->st_blksize = kbuf->st_blksize;
buf->st_blocks = kbuf->st_blocks;
-#if defined(__UCLIBC_USE_TIME64__)
+#if defined(__UCLIBC_USE_TIME64__) && !defined(__mips__)
buf->st_atim.tv_sec = kbuf->__st_atim32.tv_sec;
buf->st_atim.tv_nsec = kbuf->__st_atim32.tv_nsec;
buf->st_mtim.tv_sec = kbuf->__st_mtim32.tv_sec;
@@ -102,7 +102,7 @@ void __xstat64_conv(struct kernel_stat64 *kbuf, struct stat64 *buf)
buf->st_size = kbuf->st_size;
buf->st_blksize = kbuf->st_blksize;
buf->st_blocks = kbuf->st_blocks;
-#if defined(__UCLIBC_USE_TIME64__)
+#if defined(__UCLIBC_USE_TIME64__) && !defined(__mips__)
buf->st_atim.tv_sec = kbuf->__st_atim32.tv_sec;
buf->st_atim.tv_nsec = kbuf->__st_atim32.tv_nsec;
buf->st_mtim.tv_sec = kbuf->__st_mtim32.tv_sec;
diff --git a/libc/sysdeps/linux/mips/bits/kernel_stat.h b/libc/sysdeps/linux/mips/bits/kernel_stat.h
index a2a6169a3..23a6ce61a 100644
--- a/libc/sysdeps/linux/mips/bits/kernel_stat.h
+++ b/libc/sysdeps/linux/mips/bits/kernel_stat.h
@@ -14,7 +14,11 @@ typedef struct {
} __ktimespec_t;
#else
typedef struct {
+#if defined(__UCLIBC_USE_TIME64__)
+ __S32_TYPE tv_sec;
+#else
time_t tv_sec;
+#endif
unsigned long tv_nsec;
} __ktimespec_t;
#endif
diff --git a/libc/sysdeps/linux/mips/bits/sem.h b/libc/sysdeps/linux/mips/bits/sem.h
index 3e4e9682b..35eaa05c3 100644
--- a/libc/sysdeps/linux/mips/bits/sem.h
+++ b/libc/sysdeps/linux/mips/bits/sem.h
@@ -38,9 +38,20 @@
struct semid_ds
{
struct ipc_perm sem_perm; /* operation permission struct */
- __time_t sem_otime; /* last semop() time */
+#if defined(__UCLIBC_USE_TIME64__)
+ unsigned long int __sem_otime_internal_1; /* last semop() time */
+ unsigned long int __sem_otime_internal_2;
+ unsigned long int __sem_ctime_internal_1; /* last time changed by semctl() */
+ unsigned long int __sem_ctime_internal_2;
+#else
+ __time_t sem_otime; /* last semop() time */
__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 int __uclibc_unused1;
unsigned long int __uclibc_unused2;
};
diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/lowlevellock.h b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/lowlevellock.h
index 450a286b4..9fc000a91 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/mips/lowlevellock.h
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/mips/lowlevellock.h
@@ -26,6 +26,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
@@ -77,6 +81,30 @@
#define lll_futex_wait(futexp, val, private) \
lll_futex_timed_wait(futexp, val, NULL, private)
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+
+#define lll_futex_timed_wait(futexp, val, timespec, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret attribute_unused; \
+ __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (long) (futexp), \
+ __lll_private_flag (FUTEX_WAIT, private), \
+ (val), (TO_TS64_P(timespec))); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
+ })
+
+#define lll_futex_wake(futexp, nr, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret attribute_unused; \
+ __ret = INTERNAL_SYSCALL (futex_time64, __err, 4, (long) (futexp), \
+ __lll_private_flag (FUTEX_WAKE, private), \
+ (nr), 0); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
+ })
+
+#else
+
#define lll_futex_timed_wait(futexp, val, timespec, private) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
@@ -97,6 +125,8 @@
INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \
})
+#endif
+
#define lll_robust_dead(futexv, private) \
do \
{ \
@@ -106,6 +136,35 @@
} \
while (0)
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
+
+/* Returns non-zero if error happened, zero if success. */
+#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret attribute_unused; \
+ __ret = INTERNAL_SYSCALL (futex_time64, __err, 6, (long) (futexp), \
+ __lll_private_flag (FUTEX_CMP_REQUEUE, private),\
+ (nr_wake), (nr_move), (mutex), (val)); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
+ })
+
+/* Returns non-zero if error happened, zero if success. */
+#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (__err); \
+ long int __ret attribute_unused; \
+ \
+ __ret = INTERNAL_SYSCALL (futex_time64, __err, 6, (futexp), \
+ __lll_private_flag (FUTEX_WAKE_OP, private), \
+ (nr_wake), (nr_wake2), (futexp2), \
+ FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \
+ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
+ })
+
+
+#else
+
/* Returns non-zero if error happened, zero if success. */
#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
({ \
@@ -130,6 +189,8 @@
INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
})
+#endif
+
static inline int __attribute__((always_inline))
__lll_trylock(int *futex)
{