diff mbox series

[uclibc-ng-devel,2/2] Add time64 support for MIPS32.

Message ID 20240226102126.2755658-2-dm.chestnykh@gmail.com
State Accepted
Headers show
Series [uclibc-ng-devel,1/2] Refactor `ts32_struct` and `TO_ITS64_P`. | expand

Commit Message

Dmitry Chestnykh Feb. 26, 2024, 10:21 a.m. UTC
Signed-off-by: Dmitry Chestnykh <dm.chestnykh@gmail.com>
---
 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 +++-
 .../unix/sysv/linux/mips/lowlevellock.h       | 61 +++++++++++++++++++
 6 files changed, 85 insertions(+), 6 deletions(-)
diff mbox series

Patch

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)
 {