From 73017bba9d3bc0f8ada159319ff590117c9e5689 Mon Sep 17 00:00:00 2001 From: Dmitry Chestnykh Date: Mon, 26 Feb 2024 13:21:26 +0300 Subject: Add time64 support for MIPS32. Signed-off-by: Dmitry Chestnykh --- extra/Configs/Config.in | 5 +- libc/sysdeps/linux/common/fstatat.c | 2 +- libc/sysdeps/linux/common/xstatconv.c | 6 +-- libc/sysdeps/linux/mips/bits/kernel_stat.h | 4 ++ libc/sysdeps/linux/mips/bits/sem.h | 13 ++++- .../sysdeps/unix/sysv/linux/mips/lowlevellock.h | 61 ++++++++++++++++++++++ 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 #include +#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) { -- cgit v1.2.3