Browse Source

Add time64 support for MIPS32.

Signed-off-by: Dmitry Chestnykh <dm.chestnykh@gmail.com>
Dmitry Chestnykh 2 months ago
parent
commit
73017bba9d

+ 4 - 1
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
 

+ 1 - 1
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,

+ 3 - 3
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;

+ 4 - 0
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

+ 12 - 1
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;
 };

+ 61 - 0
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)
 {