[PATCH 01/23] linux: Simplify clock_adjtime

classic Classic list List threaded Threaded
40 messages Options
12
Reply | Threaded
Open this post in threaded view
|

[PATCH 01/23] linux: Simplify clock_adjtime

Sourceware - libc-alpha mailing list
With arch-syscall.h it can now assumes the existance of either
__NR_clock_adjtime or __NR_clock_adjtime_time64.  The 32-bit time_t
support is now only build for !__ASSUME_TIME64_SYSCALLS.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 sysdeps/unix/sysv/linux/clock_adjtime.c | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/clock_adjtime.c b/sysdeps/unix/sysv/linux/clock_adjtime.c
index 764a60b9bf..4caff2ad05 100644
--- a/sysdeps/unix/sysv/linux/clock_adjtime.c
+++ b/sysdeps/unix/sysv/linux/clock_adjtime.c
@@ -26,15 +26,13 @@
 int
 __clock_adjtime64 (const clockid_t clock_id, struct __timex64 *tx64)
 {
-#ifdef __ASSUME_TIME64_SYSCALLS
-# ifndef __NR_clock_adjtime64
-#  define __NR_clock_adjtime64 __NR_clock_adjtime
-# endif
- return INLINE_SYSCALL_CALL (clock_adjtime64, clock_id, tx64);
-#else
-  int ret = INLINE_SYSCALL_CALL (clock_adjtime64, clock_id, tx64);
-  if (errno != ENOSYS)
-    return ret;
+#ifndef __NR_clock_adjtime64
+# define __NR_clock_adjtime64 __NR_clock_adjtime
+#endif
+  int r = INLINE_SYSCALL_CALL (clock_adjtime64, clock_id, tx64);
+#ifndef __ASSUME_TIME64_SYSCALLS
+  if (r >= 0 || errno != ENOSYS)
+    return r;
 
   if (tx64->modes & ADJ_SETOFFSET
       && ! in_time_t_range (tx64->time.tv_sec))
@@ -44,12 +42,11 @@ __clock_adjtime64 (const clockid_t clock_id, struct __timex64 *tx64)
     }
 
   struct timex tx32 = valid_timex64_to_timex (*tx64);
-  int retval = INLINE_SYSCALL_CALL (clock_adjtime, clock_id, &tx32);
-  if (retval >= 0)
+  r = INLINE_SYSCALL_CALL (clock_adjtime, clock_id, &tx32);
+  if (r >= 0)
     *tx64 = valid_timex_to_timex64 (tx32);
-
-  return retval;
 #endif
+  return r;
 }
 
 #if __TIMESIZE != 64
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 02/23] linux: Simplify clock_gettime

Sourceware - libc-alpha mailing list
With arch-syscall.h it can now assumes the existance of either
__NR_clock_gettime or __NR_clock_gettime_time64.  The 32-bit time_t
support is now only build for !__ASSUME_TIME64_SYSCALLS.

It also uses the time64-support functions to simplify it further.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 sysdeps/unix/sysv/linux/clock_gettime.c | 42 ++++++++++---------------
 1 file changed, 17 insertions(+), 25 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c
index bfe3823b68..5a65113a1d 100644
--- a/sysdeps/unix/sysv/linux/clock_gettime.c
+++ b/sysdeps/unix/sysv/linux/clock_gettime.c
@@ -22,43 +22,34 @@
 #include <time.h>
 #include "kernel-posix-cpu-timers.h"
 #include <sysdep-vdso.h>
-
+#include <time64-support.h>
 #include <shlib-compat.h>
 
 /* Get current value of CLOCK and store it in TP.  */
 int
 __clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp)
 {
-#ifdef __ASSUME_TIME64_SYSCALLS
-  /* 64 bit ABIs or newer 32-bit ABIs that only support 64-bit time_t.  */
-# ifndef __NR_clock_gettime64
-#  define __NR_clock_gettime64 __NR_clock_gettime
-# endif
-# ifdef HAVE_CLOCK_GETTIME64_VSYSCALL
-  return INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp);
-# else
-  return INLINE_SYSCALL_CALL (clock_gettime64, clock_id, tp);
-# endif
-#else
   int r;
-  /* Old 32-bit ABI with possible 64-bit time_t support.  */
-# ifdef __NR_clock_gettime64
-  /* Avoid issue a __NR_clock_gettime64 syscall on kernels that do not
-     support 64-bit time_t.  */
-  static int time64_support = 1;
-  if (atomic_load_relaxed (&time64_support) != 0)
+
+#ifndef __NR_clock_gettime64
+# define __NR_clock_gettime64 __NR_clock_gettime
+#endif
+
+  if (supports_time64 ())
     {
-#  ifdef HAVE_CLOCK_GETTIME64_VSYSCALL
+#ifdef HAVE_CLOCK_GETTIME64_VSYSCALL
       r = INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp);
-#  else
+#else
       r = INLINE_SYSCALL_CALL (clock_gettime64, clock_id, tp);
-#  endif
+#endif
+
       if (r == 0 || errno != ENOSYS)
  return r;
 
-      atomic_store_relaxed (&time64_support, 0);
-    }
-# endif
+      mark_time64_unsupported ();
+   }
+
+#ifndef __ASSUME_TIME64_SYSCALLS
   /* Fallback code that uses 32-bit support.  */
   struct timespec tp32;
 # ifdef HAVE_CLOCK_GETTIME_VSYSCALL
@@ -68,8 +59,9 @@ __clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp)
 # endif
   if (r == 0)
     *tp = valid_timespec_to_timespec64 (tp32);
-  return r;
 #endif
+
+  return r;
 }
 
 #if __TIMESIZE != 64
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 03/23] linux: Simplify clock_nanosleep

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
With arch-syscall.h it can now assumes the existance of either
__NR_clock_nanosleep or __NR_clock_nanosleep_time64.  The 32-bit
time_t support is now only build for !__ASSUME_TIME64_SYSCALLS.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 sysdeps/unix/sysv/linux/clock_nanosleep.c | 33 ++++++++---------------
 1 file changed, 11 insertions(+), 22 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c b/sysdeps/unix/sysv/linux/clock_nanosleep.c
index cc7a09569d..6ad3321435 100644
--- a/sysdeps/unix/sysv/linux/clock_nanosleep.c
+++ b/sysdeps/unix/sysv/linux/clock_nanosleep.c
@@ -30,8 +30,6 @@ int
 __clock_nanosleep_time64 (clockid_t clock_id, int flags, const struct __timespec64 *req,
                           struct __timespec64 *rem)
 {
-  int r;
-
   if (clock_id == CLOCK_THREAD_CPUTIME_ID)
     return EINVAL;
   if (clock_id == CLOCK_PROCESS_CPUTIME_ID)
@@ -39,22 +37,15 @@ __clock_nanosleep_time64 (clockid_t clock_id, int flags, const struct __timespec
 
   /* If the call is interrupted by a signal handler or encounters an error,
      it returns a positive value similar to errno.  */
-#ifdef __ASSUME_TIME64_SYSCALLS
-# ifndef __NR_clock_nanosleep_time64
-#  define __NR_clock_nanosleep_time64 __NR_clock_nanosleep
-# endif
-  r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, clock_id,
-                               flags, req, rem);
-#else
-# ifdef __NR_clock_nanosleep_time64
-  r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, clock_id,
-                               flags, req, rem);
-
-  if (! INTERNAL_SYSCALL_ERROR_P (r))
-    return 0;
-  if (INTERNAL_SYSCALL_ERRNO (r) != ENOSYS)
-    return INTERNAL_SYSCALL_ERRNO (r);
-# endif /* __NR_clock_nanosleep_time64 */
+#ifndef __NR_clock_nanosleep_time64
+# define __NR_clock_nanosleep_time64 __NR_clock_nanosleep
+#endif
+  int r = INTERNAL_SYSCALL_CANCEL (clock_nanosleep_time64, clock_id,
+   flags, req, rem);
+
+#ifndef __ASSUME_TIME64_SYSCALLS
+  if (r == 0 || r != -ENOSYS)
+    return -r;
 
   if (! in_time_t_range (req->tv_sec))
     {
@@ -68,14 +59,12 @@ __clock_nanosleep_time64 (clockid_t clock_id, int flags, const struct __timespec
                                &ts32, &tr32);
   if (INTERNAL_SYSCALL_ERROR_P (r))
     {
-      if (INTERNAL_SYSCALL_ERRNO (r) == EINTR && rem != NULL
-  && (flags & TIMER_ABSTIME) == 0)
+      if (r == -EINTR && rem != NULL && (flags & TIMER_ABSTIME) == 0)
  *rem = valid_timespec_to_timespec64 (tr32);
     }
 #endif /* __ASSUME_TIME64_SYSCALLS */
 
-  return (INTERNAL_SYSCALL_ERROR_P (r)
-  ? INTERNAL_SYSCALL_ERRNO (r) : 0);
+  return -r;
 }
 
 #if __TIMESIZE != 64
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 04/23] linux: Simplify clock_settime

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
With arch-syscall.h it can now assumes the existance of either
__NR_clock_settime or __NR_clock_settime_time64.  The 32-bit
time_t support is now only build for !__ASSUME_TIME64_SYSCALLS.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 sysdeps/unix/sysv/linux/clock_settime.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/clock_settime.c b/sysdeps/unix/sysv/linux/clock_settime.c
index ebda871f4c..ce0bf622c0 100644
--- a/sysdeps/unix/sysv/linux/clock_settime.c
+++ b/sysdeps/unix/sysv/linux/clock_settime.c
@@ -32,17 +32,15 @@ __clock_settime64 (clockid_t clock_id, const struct __timespec64 *tp)
       return -1;
     }
 
-#ifdef __ASSUME_TIME64_SYSCALLS
-# ifndef __NR_clock_settime64
-#  define __NR_clock_settime64 __NR_clock_settime
-# endif
-  return INLINE_SYSCALL_CALL (clock_settime64, clock_id, tp);
-#else
-# ifdef __NR_clock_settime64
+#ifndef __NR_clock_settime64
+# define __NR_clock_settime64 __NR_clock_settime
+#endif
   int ret = INLINE_SYSCALL_CALL (clock_settime64, clock_id, tp);
+
+#ifndef __ASSUME_TIME64_SYSCALLS
   if (ret == 0 || errno != ENOSYS)
     return ret;
-# endif
+
   if (! in_time_t_range (tp->tv_sec))
     {
       __set_errno (EOVERFLOW);
@@ -50,8 +48,10 @@ __clock_settime64 (clockid_t clock_id, const struct __timespec64 *tp)
     }
 
   struct timespec ts32 = valid_timespec64_to_timespec (*tp);
-  return INLINE_SYSCALL_CALL (clock_settime, clock_id, &ts32);
+  ret = INLINE_SYSCALL_CALL (clock_settime, clock_id, &ts32);
 #endif
+
+  return ret;
 }
 
 #if __TIMESIZE != 64
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 05/23] linux: Simplify mq_timedreceive

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
With arch-syscall.h it can now assumes the existance of either
__NR_mq_timedreceive or __NR_mq_timedreceive_time64.  The 32-bit
time_t support is now only build for !__ASSUME_TIME64_SYSCALLS.

The internal 64-bit time_t names is also adjusted to use the
other y2038 symbol names.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 include/mqueue.h                          | 16 ++++++------
 sysdeps/unix/sysv/linux/mq_timedreceive.c | 32 +++++++++++------------
 2 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/include/mqueue.h b/include/mqueue.h
index 98e4596c22..b3ee8b7462 100644
--- a/include/mqueue.h
+++ b/include/mqueue.h
@@ -13,18 +13,18 @@ hidden_proto (mq_setattr)
 #include <struct___timespec64.h>
 #if __TIMESIZE == 64
 # define __mq_timedsend_time64 __mq_timedsend
-# define __mq_timedreceive_time64 __mq_timedreceive
+# define __mq_timedreceive64 __mq_timedreceive
 #else
 extern int __mq_timedsend_time64 (mqd_t mqdes, const char *msg_ptr,
                                   size_t msg_len, unsigned int msg_prio,
                                   const struct __timespec64 *abs_timeout);
 librt_hidden_proto (__mq_timedsend_time64)
-extern ssize_t __mq_timedreceive_time64 (mqd_t mqdes,
-                                         char *__restrict msg_ptr,
-                                         size_t msg_len,
-                                         unsigned int *__restrict msg_prio,
-                                         const struct __timespec64 *__restrict
-                                         abs_timeout);
-librt_hidden_proto (__mq_timedreceive_time64)
+extern ssize_t __mq_timedreceive64 (mqd_t mqdes,
+                                    char *__restrict msg_ptr,
+                                    size_t msg_len,
+                                    unsigned int *__restrict msg_prio,
+                                    const struct __timespec64 *__restrict
+                                    abs_timeout);
+librt_hidden_proto (__mq_timedreceive64)
 #endif
 #endif
diff --git a/sysdeps/unix/sysv/linux/mq_timedreceive.c b/sysdeps/unix/sysv/linux/mq_timedreceive.c
index 728a63d1ec..61c27fd8f7 100644
--- a/sysdeps/unix/sysv/linux/mq_timedreceive.c
+++ b/sysdeps/unix/sysv/linux/mq_timedreceive.c
@@ -22,19 +22,17 @@
 /* Receive the oldest from highest priority messages in message queue
    MQDES, stop waiting if ABS_TIMEOUT expires.  */
 ssize_t
-__mq_timedreceive_time64 (mqd_t mqdes, char *__restrict msg_ptr, size_t msg_len,
-                          unsigned int *__restrict msg_prio,
-                          const struct __timespec64 *__restrict abs_timeout)
+__mq_timedreceive64 (mqd_t mqdes, char *__restrict msg_ptr, size_t msg_len,
+                     unsigned int *__restrict msg_prio,
+                     const struct __timespec64 *__restrict abs_timeout)
 {
-#ifdef __ASSUME_TIME64_SYSCALLS
-# ifndef __NR_mq_timedreceive_time64
-#  define __NR_mq_timedreceive_time64 __NR_mq_timedreceive
-# endif
-  return SYSCALL_CANCEL (mq_timedreceive_time64, mqdes, msg_ptr, msg_len,
-                         msg_prio, abs_timeout);
-#else
+#ifndef __NR_mq_timedreceive_time64
+# define __NR_mq_timedreceive_time64 __NR_mq_timedreceive
+#endif
   int ret = SYSCALL_CANCEL (mq_timedreceive_time64, mqdes, msg_ptr, msg_len,
-                            msg_prio, abs_timeout);
+    msg_prio, abs_timeout);
+
+#ifndef __ASSUME_TIME64_SYSCALLS
   if (ret == 0 || errno != ENOSYS)
     return ret;
 
@@ -50,13 +48,15 @@ __mq_timedreceive_time64 (mqd_t mqdes, char *__restrict msg_ptr, size_t msg_len,
       ts32 = valid_timespec64_to_timespec (*abs_timeout);
     }
 
-  return SYSCALL_CANCEL (mq_timedreceive, mqdes, msg_ptr, msg_len, msg_prio,
-                         abs_timeout != NULL ? &ts32 : NULL);
+  ret = SYSCALL_CANCEL (mq_timedreceive, mqdes, msg_ptr, msg_len, msg_prio,
+ abs_timeout != NULL ? &ts32 : NULL);
 #endif
+
+  return ret;
 }
 
 #if __TIMESIZE != 64
-librt_hidden_def (__mq_timedreceive_time64)
+librt_hidden_def (__mq_timedreceive64)
 
 ssize_t
 __mq_timedreceive (mqd_t mqdes, char *__restrict msg_ptr, size_t msg_len,
@@ -67,8 +67,8 @@ __mq_timedreceive (mqd_t mqdes, char *__restrict msg_ptr, size_t msg_len,
   if (abs_timeout != NULL)
     ts64 = valid_timespec_to_timespec64 (*abs_timeout);
 
-  return __mq_timedreceive_time64 (mqdes, msg_ptr, msg_len, msg_prio,
-                                   abs_timeout != NULL ? &ts64 : NULL);
+  return __mq_timedreceive64 (mqdes, msg_ptr, msg_len, msg_prio,
+      abs_timeout != NULL ? &ts64 : NULL);
 }
 #endif
 
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 06/23] linux: Simplify mq_timedsend

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
 With arch-syscall.h it can now assumes the existance of either
__NR_mq_timedsend or __NR_mq_timedsend_time64.  The 32-bit
time_t support is now only build for !__ASSUME_TIME64_SYSCALLS.

The internal 64-bit time_t names is also adjusted to use the
other y2038 symbol names.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 include/mqueue.h                       | 10 +++++-----
 sysdeps/unix/sysv/linux/mq_timedsend.c | 26 +++++++++++++-------------
 2 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/include/mqueue.h b/include/mqueue.h
index b3ee8b7462..e0e30dc890 100644
--- a/include/mqueue.h
+++ b/include/mqueue.h
@@ -12,13 +12,13 @@ hidden_proto (mq_setattr)
 # endif
 #include <struct___timespec64.h>
 #if __TIMESIZE == 64
-# define __mq_timedsend_time64 __mq_timedsend
+# define __mq_timedsend64 __mq_timedsend
 # define __mq_timedreceive64 __mq_timedreceive
 #else
-extern int __mq_timedsend_time64 (mqd_t mqdes, const char *msg_ptr,
-                                  size_t msg_len, unsigned int msg_prio,
-                                  const struct __timespec64 *abs_timeout);
-librt_hidden_proto (__mq_timedsend_time64)
+extern int __mq_timedsend64 (mqd_t mqdes, const char *msg_ptr,
+     size_t msg_len, unsigned int msg_prio,
+     const struct __timespec64 *abs_timeout);
+librt_hidden_proto (__mq_timedsend64)
 extern ssize_t __mq_timedreceive64 (mqd_t mqdes,
                                     char *__restrict msg_ptr,
                                     size_t msg_len,
diff --git a/sysdeps/unix/sysv/linux/mq_timedsend.c b/sysdeps/unix/sysv/linux/mq_timedsend.c
index f2a43df300..6011db7112 100644
--- a/sysdeps/unix/sysv/linux/mq_timedsend.c
+++ b/sysdeps/unix/sysv/linux/mq_timedsend.c
@@ -22,19 +22,17 @@
 /* Add message pointed by MSG_PTR to message queue MQDES, stop blocking
    on full message queue if ABS_TIMEOUT expires.  */
 int
-__mq_timedsend_time64 (mqd_t mqdes, const char *msg_ptr, size_t msg_len,
-                       unsigned int msg_prio,
-                       const struct __timespec64 *abs_timeout)
+__mq_timedsend64 (mqd_t mqdes, const char *msg_ptr, size_t msg_len,
+  unsigned int msg_prio,
+  const struct __timespec64 *abs_timeout)
 {
-#ifdef __ASSUME_TIME64_SYSCALLS
 # ifndef __NR_mq_timedsend_time64
 #  define __NR_mq_timedsend_time64 __NR_mq_timedsend
 # endif
-  return SYSCALL_CANCEL (mq_timedsend_time64, mqdes, msg_ptr, msg_len,
-                         msg_prio, abs_timeout);
-#else
   int ret = SYSCALL_CANCEL (mq_timedsend_time64, mqdes, msg_ptr, msg_len,
-                            msg_prio, abs_timeout);
+    msg_prio, abs_timeout);
+
+#ifndef __ASSUME_TIME64_SYSCALLS
   if (ret == 0 || errno != ENOSYS)
     return ret;
 
@@ -50,13 +48,15 @@ __mq_timedsend_time64 (mqd_t mqdes, const char *msg_ptr, size_t msg_len,
       ts32 = valid_timespec64_to_timespec (*abs_timeout);
     }
 
-  return SYSCALL_CANCEL (mq_timedsend, mqdes, msg_ptr, msg_len, msg_prio,
-                         abs_timeout != NULL ? &ts32 : NULL);
+  ret = SYSCALL_CANCEL (mq_timedsend, mqdes, msg_ptr, msg_len, msg_prio,
+ abs_timeout != NULL ? &ts32 : NULL);
 #endif
+
+  return ret;
 }
 
 #if __TIMESIZE != 64
-librt_hidden_def (__mq_timedsend_time64)
+librt_hidden_def (__mq_timedsend64)
 
 int
 __mq_timedsend (mqd_t mqdes, const char *msg_ptr, size_t msg_len,
@@ -66,8 +66,8 @@ __mq_timedsend (mqd_t mqdes, const char *msg_ptr, size_t msg_len,
   if (abs_timeout != NULL)
     ts64 = valid_timespec_to_timespec64 (*abs_timeout);
 
-  return __mq_timedsend_time64 (mqdes, msg_ptr, msg_len, msg_prio,
-                                abs_timeout != NULL ? &ts64 : NULL);
+  return __mq_timedsend64 (mqdes, msg_ptr, msg_len, msg_prio,
+   abs_timeout != NULL ? &ts64 : NULL);
 }
 #endif
 
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 07/23] linux: Simplify ppoll

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
With arch-syscall.h it can now assumes the existance of either
__NR_ppoll or __NR_ppoll_time64.  The 32-bit time_t support is now
only build for !__ASSUME_TIME64_SYSCALLS.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 sysdeps/unix/sysv/linux/ppoll.c | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/ppoll.c b/sysdeps/unix/sysv/linux/ppoll.c
index 0f15636cce..079d56b5eb 100644
--- a/sysdeps/unix/sysv/linux/ppoll.c
+++ b/sysdeps/unix/sysv/linux/ppoll.c
@@ -37,19 +37,16 @@ __ppoll64 (struct pollfd *fds, nfds_t nfds, const struct __timespec64 *timeout,
       timeout = &tval;
     }
 
-#ifdef __ASSUME_TIME64_SYSCALLS
-# ifndef __NR_ppoll_time64
-#  define __NR_ppoll_time64 __NR_ppoll
-# endif
-  return SYSCALL_CANCEL (ppoll_time64, fds, nfds, timeout, sigmask,
- __NSIG_BYTES);
-#else
-# ifdef __NR_ppoll_time64
+#ifndef __NR_ppoll_time64
+# define __NR_ppoll_time64 __NR_ppoll
+#endif
   int ret = SYSCALL_CANCEL (ppoll_time64, fds, nfds, timeout, sigmask,
-                            __NSIG_BYTES);
+    __NSIG_BYTES);
+
+#ifdef __ASSUME_TIME64_SYSCALLS
   if (ret >= 0 || errno != ENOSYS)
     return ret;
-# endif
+
   struct timespec ts32;
   if (timeout)
     {
@@ -62,9 +59,11 @@ __ppoll64 (struct pollfd *fds, nfds_t nfds, const struct __timespec64 *timeout,
       ts32 = valid_timespec64_to_timespec (*timeout);
     }
 
-  return SYSCALL_CANCEL (ppoll, fds, nfds, timeout ? &ts32 : NULL, sigmask,
-                         __NSIG_BYTES);
+  ret = SYSCALL_CANCEL (ppoll, fds, nfds, timeout ? &ts32 : NULL, sigmask,
+ __NSIG_BYTES);
 #endif
+
+  return ret;
 }
 
 #if __TIMESIZE != 64
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 08/23] linux: Simplify sched_rr_get_interval

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
With arch-syscall.h it can now assumes the existance of either
__NR_sched_rr_get_interval or __NR_sched_rr_get_interval_time64.
The 32-bit time_t support is now only build for
!__ASSUME_TIME64_SYSCALLS.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 sysdeps/unix/sysv/linux/sched_rr_gi.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/sched_rr_gi.c b/sysdeps/unix/sysv/linux/sched_rr_gi.c
index 3d7b484591..997562159f 100644
--- a/sysdeps/unix/sysv/linux/sched_rr_gi.c
+++ b/sysdeps/unix/sysv/linux/sched_rr_gi.c
@@ -25,24 +25,20 @@
 int
 __sched_rr_get_interval64 (pid_t pid, struct __timespec64 *tp)
 {
-#ifdef __ASSUME_TIME64_SYSCALLS
-# ifndef __NR_sched_rr_get_interval_time64
-#  define __NR_sched_rr_get_interval_time64 __NR_sched_rr_get_interval
-# endif
-  return INLINE_SYSCALL_CALL (sched_rr_get_interval_time64, pid, tp);
-#else
-# ifdef __NR_sched_rr_get_interval_time64
+#ifndef __NR_sched_rr_get_interval_time64
+# define __NR_sched_rr_get_interval_time64 __NR_sched_rr_get_interval
+#endif
   int ret = INLINE_SYSCALL_CALL (sched_rr_get_interval_time64, pid, tp);
+#ifndef __ASSUME_TIME64_SYSCALLS
   if (ret == 0 || errno != ENOSYS)
     return ret;
-# endif
+
   struct timespec tp32;
-  int retval = INLINE_SYSCALL_CALL (sched_rr_get_interval, pid, &tp32);
-  if (retval == 0)
+  ret = INLINE_SYSCALL_CALL (sched_rr_get_interval, pid, &tp32);
+  if (ret == 0)
     *tp = valid_timespec_to_timespec64 (tp32);
-
-  return retval;
 #endif
+  return ret;
 }
 
 #if __TIMESIZE != 64
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 09/23] linux: Simplify timer_gettime

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
With arch-syscall.h it can now assumes the existance of either
__NR_timer_gettime or __NR_time_gettime_time64.  The 32-bit time_t
support is now only build for !__ASSUME_TIME64_SYSCALLS.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 sysdeps/unix/sysv/linux/timer_gettime.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/timer_gettime.c b/sysdeps/unix/sysv/linux/timer_gettime.c
index 1e07d4845b..5d31c7c864 100644
--- a/sysdeps/unix/sysv/linux/timer_gettime.c
+++ b/sysdeps/unix/sysv/linux/timer_gettime.c
@@ -28,27 +28,23 @@ __timer_gettime64 (timer_t timerid, struct __itimerspec64 *value)
 {
   struct timer *kt = (struct timer *) timerid;
 
-#ifdef __ASSUME_TIME64_SYSCALLS
-# ifndef __NR_timer_gettime64
-#  define __NR_timer_gettime64 __NR_timer_gettime
-# endif
-  return INLINE_SYSCALL_CALL (timer_gettime64, kt->ktimerid, value);
-#else
-# ifdef __NR_timer_gettime64
+#ifndef __NR_timer_gettime64
+# define __NR_timer_gettime64 __NR_timer_gettime
+#endif
   int ret = INLINE_SYSCALL_CALL (timer_gettime64, kt->ktimerid, value);
+#ifndef __ASSUME_TIME64_SYSCALLS
   if (ret == 0 || errno != ENOSYS)
     return ret;
-# endif
+
   struct itimerspec its32;
-  int retval = INLINE_SYSCALL_CALL (timer_gettime, kt->ktimerid, &its32);
-  if (retval == 0)
+  ret = INLINE_SYSCALL_CALL (timer_gettime, kt->ktimerid, &its32);
+  if (ret == 0)
     {
       value->it_interval = valid_timespec_to_timespec64 (its32.it_interval);
       value->it_value = valid_timespec_to_timespec64 (its32.it_value);
     }
-
-  return retval;
 #endif
+  return ret;
 }
 
 #if __TIMESIZE != 64
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 10/23] linux: Simplify timerfd_settime

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
 With arch-syscall.h it can now assumes the existance of either
__NR_timer_settime or __NR_time_settime_time64.  The 32-bit time_t
support is now only build for !__ASSUME_TIME64_SYSCALLS.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 sysdeps/unix/sysv/linux/timerfd_settime.c | 23 +++++++++--------------
 1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/timerfd_settime.c b/sysdeps/unix/sysv/linux/timerfd_settime.c
index 164b4e860a..7c55e7e8d6 100644
--- a/sysdeps/unix/sysv/linux/timerfd_settime.c
+++ b/sysdeps/unix/sysv/linux/timerfd_settime.c
@@ -26,18 +26,13 @@ int
 __timerfd_settime64 (int fd, int flags, const struct __itimerspec64 *value,
                      struct __itimerspec64 *ovalue)
 {
-#ifdef __ASSUME_TIME64_SYSCALLS
-# ifndef __NR_timerfd_settime64
-#  define __NR_timerfd_settime64 __NR_timerfd_settime
-# endif
-  return INLINE_SYSCALL_CALL (timerfd_settime64, fd, flags, value, ovalue);
-#else
-# ifdef __NR_timerfd_settime64
+#ifndef __NR_timerfd_settime64
+# define __NR_timerfd_settime64 __NR_timerfd_settime
+#endif
   int ret = INLINE_SYSCALL_CALL (timerfd_settime64, fd, flags, value, ovalue);
+#ifndef __ASSUME_TIME64_SYSCALLS
   if (ret == 0 || errno != ENOSYS)
     return ret;
-# endif
-  struct itimerspec its32, oits32;
 
   if (! in_time_t_range ((value->it_value).tv_sec)
       || ! in_time_t_range ((value->it_interval).tv_sec))
@@ -46,19 +41,19 @@ __timerfd_settime64 (int fd, int flags, const struct __itimerspec64 *value,
       return -1;
     }
 
+  struct itimerspec its32, oits32;
   its32.it_interval = valid_timespec64_to_timespec (value->it_interval);
   its32.it_value = valid_timespec64_to_timespec (value->it_value);
 
-  int retval = INLINE_SYSCALL_CALL (timerfd_settime, fd, flags,
-                                    &its32, ovalue ? &oits32 : NULL);
-  if (retval == 0 && ovalue)
+  ret = INLINE_SYSCALL_CALL (timerfd_settime, fd, flags,
+     &its32, ovalue ? &oits32 : NULL);
+  if (ret == 0 && ovalue != NULL)
     {
       ovalue->it_interval = valid_timespec_to_timespec64 (oits32.it_interval);
       ovalue->it_value = valid_timespec_to_timespec64 (oits32.it_value);
     }
-
-  return retval;
 #endif
+  return ret;
 }
 
 #if __TIMESIZE != 64
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 11/23] linux: Simplify utimensat

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
With arch-syscall.h it can now assumes the existance of either
__NR_utimensat or __NR_utimensat_time64.  The 32-bit time_t
support is now only build for !__ASSUME_TIME64_SYSCALLS.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 sysdeps/unix/sysv/linux/utimensat.c | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/utimensat.c b/sysdeps/unix/sysv/linux/utimensat.c
index eb16f0f3d5..ea23c2f051 100644
--- a/sysdeps/unix/sysv/linux/utimensat.c
+++ b/sysdeps/unix/sysv/linux/utimensat.c
@@ -28,18 +28,15 @@ int
 __utimensat64_helper (int fd, const char *file,
                       const struct __timespec64 tsp64[2], int flags)
 {
-#ifdef __ASSUME_TIME64_SYSCALLS
-# ifndef __NR_utimensat_time64
-#  define __NR_utimensat_time64 __NR_utimensat
-# endif
-  return INLINE_SYSCALL (utimensat_time64, 4, fd, file, &tsp64[0], flags);
-#else
-# ifdef __NR_utimensat_time64
-  int ret = INLINE_SYSCALL (utimensat_time64, 4, fd, file, &tsp64[0], flags);
+#ifndef __NR_utimensat_time64
+# define __NR_utimensat_time64 __NR_utimensat
+#endif
+  int ret = INLINE_SYSCALL_CALL (utimensat_time64, fd, file, &tsp64[0], flags);
+#ifndef __ASSUME_TIME64_SYSCALLS
   if (ret == 0 || errno != ENOSYS)
     return ret;
-# endif
-  if (tsp64
+
+  if (tsp64 != NULL
       && (! in_time_t_range (tsp64[0].tv_sec)
           || ! in_time_t_range (tsp64[1].tv_sec)))
     {
@@ -54,10 +51,10 @@ __utimensat64_helper (int fd, const char *file,
       tsp32[1] = valid_timespec64_to_timespec (tsp64[1]);
     }
 
-  return INLINE_SYSCALL (utimensat, 4, fd, file, tsp64 ? &tsp32[0] : NULL,
-                         flags);
+  ret = INLINE_SYSCALL_CALL (utimensat, fd, file, tsp64 ? &tsp32[0] : NULL,
+     flags);
 #endif
-
+  return ret;
 }
 libc_hidden_def (__utimensat64_helper)
 
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 12/23] linux: Add helper function to optimize 64-bit time_t fallback support

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
These helper functions are used to optimize the 64-bit time_t support on
configurations that requires support for 32-bit time_t fallback
(!__ASSUME_TIME64_SYSCALLS).  The idea is once the kernel advertises that
it does not have 64-bit time_t support, glibc will stop to try issue the
64-bit time_t syscall altogether.

For instance:

  #ifndef __NR_symbol_time64
  # define __NR_symbol_time64 __NR_symbol
  #endif
  int r;
  if (supports_time64 ())
    {
      r = INLINE_SYSCALL_CALL (symbol, ...);
      if (r == 0 || errno != ENOSYS)
        return r;

      mark_time64_unsupported ();
    }
  #ifndef __ASSUME_TIME64_SYSCALLS
  <32-bit fallback syscall>
  #endif
  return r;

On configuration with default 64-bit time_t these optimization should be
optimized away by the compiler resulting in no overhead.
---
 sysdeps/unix/sysv/linux/Makefile         |  3 +-
 sysdeps/unix/sysv/linux/time64-support.c | 23 ++++++++
 sysdeps/unix/sysv/linux/time64-support.h | 70 ++++++++++++++++++++++++
 3 files changed, 95 insertions(+), 1 deletion(-)
 create mode 100644 sysdeps/unix/sysv/linux/time64-support.c
 create mode 100644 sysdeps/unix/sysv/linux/time64-support.h

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 1932ccf7df..75c60a58f3 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -60,7 +60,8 @@ sysdep_routines += adjtimex clone umount umount2 readahead sysctl \
    personality epoll_wait tee vmsplice splice \
    open_by_handle_at mlock2 pkey_mprotect pkey_set pkey_get \
    timerfd_gettime timerfd_settime prctl \
-   process_vm_readv process_vm_writev clock_adjtime
+   process_vm_readv process_vm_writev clock_adjtime \
+   time64-support
 
 CFLAGS-gethostid.c = -fexceptions
 CFLAGS-tee.c = -fexceptions -fasynchronous-unwind-tables
diff --git a/sysdeps/unix/sysv/linux/time64-support.c b/sysdeps/unix/sysv/linux/time64-support.c
new file mode 100644
index 0000000000..9f03c9adda
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/time64-support.c
@@ -0,0 +1,23 @@
+/* Auxiliary definitions for 64-bit time_t support.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <time64-support.h>
+
+#ifndef __ASSUME_TIME64_SYSCALLS
+int __time64_support = 1;
+#endif
diff --git a/sysdeps/unix/sysv/linux/time64-support.h b/sysdeps/unix/sysv/linux/time64-support.h
new file mode 100644
index 0000000000..a997042fea
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/time64-support.h
@@ -0,0 +1,70 @@
+/* Auxiliary definitions for 64-bit time_t support.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <stdbool.h>
+#include <atomic.h>
+
+/* These helper functions are used to optimize the 64-bit time_t support on
+   configurations that requires support for 32-bit time_t fallback
+   (!__ASSUME_TIME64_SYSCALLS).  The idea is once the kernel advertises that
+   it does not have 64-bit time_t support, glibc will stop to try issue the
+   64-bit time_t syscall altogether.
+
+   For instance:
+
+     #ifndef __NR_symbol_time64
+     # define __NR_symbol_time64 __NR_symbol
+     #endif
+     int r;
+     if (supports_time64 ())
+       {
+         r = INLINE_SYSCALL_CALL (symbol, ...);
+         if (r == 0 || errno != ENOSYS)
+   return r;
+
+         mark_time64_unsupported ();
+       }
+     #ifndef __ASSUME_TIME64_SYSCALLS
+       <32-bit fallback syscall>
+     #endif
+     return r;
+
+   On configuration with default 64-bit time_t these optimization should be
+   optimized away by the compiler resulting in no overhead.  */
+
+#ifndef __ASSUME_TIME64_SYSCALLS
+extern int __time64_support attribute_hidden;
+#endif
+
+static inline bool
+supports_time64 (void)
+{
+#ifdef __ASSUME_TIME64_SYSCALLS
+  return true;
+#else
+  return atomic_load_relaxed (&__time64_support) != 0;
+#endif
+}
+
+static inline void
+mark_time64_unsupported (void)
+{
+#ifndef __ASSUME_TIME64_SYSCALLS
+  atomic_store_relaxed (&__time64_support, 0);
+#endif
+}
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 13/23] linux: Simplify clock_getres

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
With arch-syscall.h it can now assumes the existance of either
__NR_clock_getres or __NR_clock_getres_time64.  The 32-bit time_t
support is now only build for !__ASSUME_TIME64_SYSCALLS.

It also uses the time64-support functions to simplify it further.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 sysdeps/unix/sysv/linux/clock_getres.c | 38 ++++++++++----------------
 1 file changed, 15 insertions(+), 23 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/clock_getres.c b/sysdeps/unix/sysv/linux/clock_getres.c
index 5f6955ab10..6be73c94de 100644
--- a/sysdeps/unix/sysv/linux/clock_getres.c
+++ b/sysdeps/unix/sysv/linux/clock_getres.c
@@ -21,6 +21,7 @@
 #include <time.h>
 
 #include <sysdep-vdso.h>
+#include <time64-support.h>
 #include <shlib-compat.h>
 #include <kernel-features.h>
 
@@ -28,36 +29,26 @@
 int
 __clock_getres64 (clockid_t clock_id, struct __timespec64 *res)
 {
-#ifdef __ASSUME_TIME64_SYSCALLS
-  /* 64 bit ABIs or Newer 32-bit ABIs that only support 64-bit time_t.  */
-# ifndef __NR_clock_getres_time64
-#  define __NR_clock_getres_time64 __NR_clock_getres
-# endif
-# ifdef HAVE_CLOCK_GETRES64_VSYSCALL
-  return INLINE_VSYSCALL (clock_getres_time64, 2, clock_id, res);
-# else
-  return INLINE_SYSCALL_CALL (clock_getres_time64, clock_id, res);
-# endif
-#else
   int r;
-  /* Old 32-bit ABI with possible 64-bit time_t support.  */
-# ifdef __NR_clock_getres_time64
-  /* Avoid issue a __NR_clock_getres_time64 syscall on kernels that do not
-     support 64-bit time_t.  */
-  static int time64_support = 1;
-  if (atomic_load_relaxed (&time64_support) != 0)
+
+#ifndef __NR_clock_getres_time64
+# define __NR_clock_getres_time64 __NR_clock_getres
+#endif
+  if (supports_time64 ())
     {
-#  ifdef HAVE_CLOCK_GETRES64_VSYSCALL
+#ifdef HAVE_CLOCK_GETRES64_VSYSCALL
       r = INLINE_VSYSCALL (clock_getres_time64, 2, clock_id, res);
-#  else
+#else
       r = INLINE_SYSCALL_CALL (clock_getres_time64, clock_id, res);
-#  endif
+#endif
+
       if (r == 0 || errno != ENOSYS)
  return r;
 
-      atomic_store_relaxed (&time64_support, 0);
+      mark_time64_unsupported ();
     }
-# endif
+
+#ifndef __ASSUME_TIME64_SYSCALLS
   /* Fallback code that uses 32-bit support.  */
   struct timespec ts32;
 # ifdef HAVE_CLOCK_GETRES_VSYSCALL
@@ -67,8 +58,9 @@ __clock_getres64 (clockid_t clock_id, struct __timespec64 *res)
 # endif
   if (r == 0)
     *res = valid_timespec_to_timespec64 (ts32);
-  return r;
 #endif
+
+  return r;
 }
 
 #if __TIMESIZE != 64
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 14/23] linux: Add ppoll time64 optimization

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
It avoid issues the __NR_ppoll_time64 syscall if the kernel does not
support it.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 sysdeps/unix/sysv/linux/ppoll.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/ppoll.c b/sysdeps/unix/sysv/linux/ppoll.c
index 079d56b5eb..c4e5b0e733 100644
--- a/sysdeps/unix/sysv/linux/ppoll.c
+++ b/sysdeps/unix/sysv/linux/ppoll.c
@@ -22,7 +22,7 @@
 #include <sys/poll.h>
 #include <sysdep-cancel.h>
 #include <kernel-features.h>
-
+#include <time64-support.h>
 
 int
 __ppoll64 (struct pollfd *fds, nfds_t nfds, const struct __timespec64 *timeout,
@@ -40,13 +40,20 @@ __ppoll64 (struct pollfd *fds, nfds_t nfds, const struct __timespec64 *timeout,
 #ifndef __NR_ppoll_time64
 # define __NR_ppoll_time64 __NR_ppoll
 #endif
-  int ret = SYSCALL_CANCEL (ppoll_time64, fds, nfds, timeout, sigmask,
+  int ret;
+
+  if (supports_time64 ())
+    {
+      ret = SYSCALL_CANCEL (ppoll_time64, fds, nfds, timeout, sigmask,
     __NSIG_BYTES);
 
-#ifdef __ASSUME_TIME64_SYSCALLS
-  if (ret >= 0 || errno != ENOSYS)
-    return ret;
+      if (ret == 0 || errno != ENOSYS)
+ return ret;
+
+      mark_time64_unsupported ();
+    }
 
+#ifndef __ASSUME_TIME64_SYSCALLS
   struct timespec ts32;
   if (timeout)
     {
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 15/23] linux: Add time64 semtimedop support

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
Either the __NR_semtimedop_time64 (for 32-bit) or the __NR_semtimedop
(for 64-bit) syscall is used as default.  The 32-bit fallback is used
iff __ASSUME_TIME64_SYSCALLS is not defined, which assumes the kernel
ABI provides either __NR_ipc or __NR_semtimeop (for 32-bit time_t).

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 sysdeps/unix/sysv/linux/include/sys/sem.h |  6 +++
 sysdeps/unix/sysv/linux/semtimedop.c      | 57 +++++++++++++++++++----
 2 files changed, 55 insertions(+), 8 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/include/sys/sem.h b/sysdeps/unix/sysv/linux/include/sys/sem.h
index a9151e057d..f369c6b6d3 100644
--- a/sysdeps/unix/sysv/linux/include/sys/sem.h
+++ b/sysdeps/unix/sysv/linux/include/sys/sem.h
@@ -7,9 +7,15 @@ __typeof__ (semtimedop) __semtimedop attribute_hidden;
 
 #if __TIMESIZE == 64
 # define __semctl64 __semctl
+# define __semtimedop64 __semtimedop
 #else
+# include <struct___timespec64.h>
+
 extern int __semctl64 (int semid, int semnum, int cmd, ...);
 libc_hidden_proto (__semctl64);
+extern int __semtimedop64 (int semid, struct sembuf *sops, size_t nsops,
+   const struct __timespec64 *tmo);
+libc_hidden_proto (__semtimedop64);
 #endif
 
 # endif
diff --git a/sysdeps/unix/sysv/linux/semtimedop.c b/sysdeps/unix/sysv/linux/semtimedop.c
index 6fdde09bad..d755a820d8 100644
--- a/sysdeps/unix/sysv/linux/semtimedop.c
+++ b/sysdeps/unix/sysv/linux/semtimedop.c
@@ -22,18 +22,59 @@
 #include <errno.h>
 
 /* Perform user-defined atomical operation of array of semaphores.  */
+int
+__semtimedop64 (int semid, struct sembuf *sops, size_t nsops,
+ const struct __timespec64 *timeout)
+{
+#if defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS
+# ifndef __NR_semtimedop_time64
+#  define __NR_semtimedop_time64 __NR_semtimedop
+# endif
+  int r = INLINE_SYSCALL_CALL (semtimedop_time64, semid, sops, nsops,
+       timeout);
+#else
+  int r = INLINE_SYSCALL_CALL (ipc, IPCOP_semtimedop, semid,
+       SEMTIMEDOP_IPC_ARGS (nsops, sops, timeout));
+#endif
+
+#ifndef __ASSUME_TIME64_SYSCALLS
+  if (r == 0 || errno != ENOSYS)
+    return r;
+
+  struct timespec ts32, *pts32 = NULL;
+  if (timeout != NULL)
+    {
+      if (! in_time_t_range (timeout->tv_sec))
+ {
+  __set_errno (EINVAL);
+  return -1;
+ }
+      ts32 = valid_timespec64_to_timespec (*timeout);
+      pts32 = &ts32;
+    }
+# if defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS
+  r = INLINE_SYSCALL_CALL (semtimedop, semid, sops, nsops, pts32);
+# else
+  r = INLINE_SYSCALL_CALL (ipc, IPCOP_semtimedop, semid,
+   SEMTIMEDOP_IPC_ARGS (nsops, sops, pts32));
+# endif
+#endif /* __ASSUME_TIME64_SYSCALLS  */
+  return r;
+}
+#if __TIMESIZE != 64
+libc_hidden_def (__semtimedop64)
 
 int
 __semtimedop (int semid, struct sembuf *sops, size_t nsops,
       const struct timespec *timeout)
 {
-  /* semtimedop wire-up syscall is not exported for 32-bit ABIs (they have
-     semtimedop_time64 instead with uses a 64-bit time_t).  */
-#if defined __ASSUME_DIRECT_SYSVIPC_SYSCALLS && defined __NR_semtimedop
-  return INLINE_SYSCALL_CALL (semtimedop, semid, sops, nsops, timeout);
-#else
-  return INLINE_SYSCALL_CALL (ipc, IPCOP_semtimedop, semid,
-      SEMTIMEDOP_IPC_ARGS (nsops, sops, timeout));
-#endif
+  struct __timespec64 ts64, *pts64 = NULL;
+  if (timeout != 0)
+    {
+      ts64 = valid_timespec_to_timespec64 (*timeout);
+      pts64 = &ts64;
+    }
+  return __semtimedop64 (semid, sops, nsops, pts64);
 }
+#endif
 weak_alias (__semtimedop, semtimedop)
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 16/23] linux: Add time64 pselect support

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
The syscall __NR_pselect6_time64 (32-bit) or __NR_pselect6 (64-bit)
is used as default.  For architectures with __ASSUME_TIME64_SYSCALLS
the 32-bit fallback uses __NR_pselec6.

To accomodate microblaze missing pselect6 support on kernel older
than 3.15 the fallback is moved to its own function to the microblaze
specific implementation can override it.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 include/sys/select.h                         | 10 +++
 sysdeps/unix/sysv/linux/microblaze/pselect.c | 38 ++++------
 sysdeps/unix/sysv/linux/pselect.c            | 80 +++++++++++++++++---
 3 files changed, 93 insertions(+), 35 deletions(-)

diff --git a/include/sys/select.h b/include/sys/select.h
index 07bb49b994..460dee9295 100644
--- a/include/sys/select.h
+++ b/include/sys/select.h
@@ -3,6 +3,16 @@
 
 #ifndef _ISOMAC
 /* Now define the internal interfaces.  */
+# if __TIMESIZE == 64
+#  define __pselect64 __pselect
+#else
+# include <struct___timespec64.h>
+extern int __pselect64 (int __nfds, fd_set *__readfds,
+ fd_set *__writefds, fd_set *__exceptfds,
+ const struct __timespec64 *__timeout,
+ const __sigset_t *__sigmask);
+libc_hidden_proto (__pselect64)
+#endif
 extern int __pselect (int __nfds, fd_set *__readfds,
       fd_set *__writefds, fd_set *__exceptfds,
       const struct timespec *__timeout,
diff --git a/sysdeps/unix/sysv/linux/microblaze/pselect.c b/sysdeps/unix/sysv/linux/microblaze/pselect.c
index 1dfc3b8fc9..e73a98e178 100644
--- a/sysdeps/unix/sysv/linux/microblaze/pselect.c
+++ b/sysdeps/unix/sysv/linux/microblaze/pselect.c
@@ -23,38 +23,27 @@
 #include <sysdep-cancel.h>
 
 #ifndef __ASSUME_PSELECT
-# define __pselect __pselect_syscall
-#endif
-
-/* If pselect is supported, just use the Linux generic implementation.  */
-#include <sysdeps/unix/sysv/linux/pselect.c>
-
-#ifndef __ASSUME_PSELECT
-# undef __pselect
-int
-__pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
-   const struct timespec *timeout, const sigset_t *sigmask)
+static int
+__pselect64_fallback (int nfds, fd_set *readfds, fd_set *writefds,
+      fd_set *exceptfds, const struct __timespec64 *timeout,
+      const sigset_t *sigmask)
 {
-  int ret = __pselect_syscall (nfds, readfds, writefds, exceptfds, timeout,
-       sigmask);
-  if (ret >= 0 || errno != ENOSYS)
-    return ret;
-
   /* The fallback uses 'select' which shows the race condition regarding
      signal mask set/restore, requires two additional syscalls, and has
      a worse timeout precision (microseconds instead of nanoseconds).  */
 
-  struct timeval tval, *ptval = NULL;
+  struct timeval tv32, *ptv32 = NULL;
   if (timeout != NULL)
     {
-      if (! valid_nanoseconds (timeout->tv_nsec))
+      if (! in_time_t_range (timeout->tv_sec)
+  || ! valid_nanoseconds (timeout->tv_nsec))
  {
   __set_errno (EINVAL);
   return -1;
  }
 
-      TIMESPEC_TO_TIMEVAL (&tval, timeout);
-      ptval = &tval;
+      tv32 = valid_timespec64_to_timeval (*timeout);
+      ptv32 = &tv32;
     }
 
   sigset_t savemask;
@@ -62,12 +51,15 @@ __pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
     __sigprocmask (SIG_SETMASK, sigmask, &savemask);
 
   /* select itself is a cancellation entrypoint.  */
-  ret = __select (nfds, readfds, writefds, exceptfds, ptval);
+  int r = __select (nfds, readfds, writefds, exceptfds, ptv32);
 
   if (sigmask != NULL)
     __sigprocmask (SIG_SETMASK, &savemask, NULL);
 
-  return ret;
+  return r;
 }
-weak_alias (__pselect, pselect)
+# define PSELECT64_FALLBACK
 #endif
+
+/* If pselect is supported, just use the Linux generic implementation.  */
+#include <sysdeps/unix/sysv/linux/pselect.c>
diff --git a/sysdeps/unix/sysv/linux/pselect.c b/sysdeps/unix/sysv/linux/pselect.c
index 304db03338..c31a13767a 100644
--- a/sysdeps/unix/sysv/linux/pselect.c
+++ b/sysdeps/unix/sysv/linux/pselect.c
@@ -18,14 +18,41 @@
 
 #include <sys/select.h>
 #include <sysdep-cancel.h>
+#include <time64-support.h>
+
+#if !defined (__ASSUME_TIME64_SYSCALLS) && !defined (PSELECT64_FALLBACK)
+static int
+__pselect64_fallback (int nfds, fd_set *readfds, fd_set *writefds,
+      fd_set *exceptfds, const struct __timespec64 *timeout,
+      const sigset_t *sigmask)
+{
+  struct timespec ts32, *pts32 = NULL;
+  if (timeout != NULL)
+    {
+      if (! in_time_t_range (timeout->tv_sec))
+ {
+  __set_errno (EINVAL);
+  return -1;
+ }
+
+      ts32 = valid_timespec64_to_timespec (*timeout);
+      pts32 = &ts32;
+    }
+
+  return SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds,
+ pts32,
+ ((__syscall_ulong_t[]){ (uintptr_t) sigmask,
+ __NSIG_BYTES }));
+}
+#endif
 
 int
-__pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
-   const struct timespec *timeout, const sigset_t *sigmask)
+__pselect64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+     const struct __timespec64 *timeout, const sigset_t *sigmask)
 {
   /* The Linux kernel can in some situations update the timeout value.
      We do not want that so use a local variable.  */
-  struct timespec tval;
+  struct __timespec64 tval;
   if (timeout != NULL)
     {
       tval = *timeout;
@@ -36,18 +63,47 @@ __pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
      we can only pass in 6 directly.  If there is an architecture with
      support for more parameters a new version of this file needs to
      be created.  */
-  struct
-  {
-    __syscall_ulong_t ss;
-    __syscall_ulong_t ss_len;
-  } data;
 
-  data.ss = (__syscall_ulong_t) (uintptr_t) sigmask;
-  data.ss_len = __NSIG_BYTES;
+#ifndef __NR_pselect6_time64
+# define __NR_pselect6_time64 __NR_pselect6
+#endif
+  int r;
+  if (supports_time64 ())
+    {
+      r = SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds, exceptfds,
+  timeout,
+  ((__syscall_ulong_t[]){ (uintptr_t) sigmask,
+  __NSIG_BYTES }));
+      if (r == 0 || errno != ENOSYS)
+ return r;
 
-  return SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds,
-                         timeout, &data);
+      mark_time64_unsupported ();
+    }
+
+#ifndef __ASSUME_TIME64_SYSCALLS
+  r = __pselect64_fallback (nfds, readfds, writefds, exceptfds, timeout,
+    sigmask);
+#endif
+  return r;
 }
+
+#if __TIMESIZE != 64
+libc_hidden_def (__pselect64)
+
+int
+__pselect (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+   const struct timespec *timeout, const sigset_t *sigmask)
+{
+  struct __timespec64 ts64, *pts64 = NULL;
+  if (timeout != NULL)
+    {
+      ts64 = valid_timespec_to_timespec64 (*timeout);
+      pts64 = &ts64;
+    }
+  return __pselect64 (nfds, readfds, writefds, exceptfds, pts64, sigmask);
+}
+#endif
+
 #ifndef __pselect
 weak_alias (__pselect, pselect)
 #endif
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 17/23] linux: Add time64 select support

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
The syscall __NR_pselect6_time64 (32-bit) or __NR_pselect6 (64-bit)
is used as default.  For architectures with __ASSUME_TIME64_SYSCALLS
the 32-bit fallback uses __NR_select/__NR__newselect or __NR_pselect6
(it should cover the microblaze case where older kernels do not
provide __NR_pselect6).

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 include/sys/select.h             |  8 +++
 include/time.h                   |  6 ++
 sysdeps/unix/sysv/linux/select.c | 96 +++++++++++++++++++++++---------
 3 files changed, 83 insertions(+), 27 deletions(-)

diff --git a/include/sys/select.h b/include/sys/select.h
index 460dee9295..370b662ea7 100644
--- a/include/sys/select.h
+++ b/include/sys/select.h
@@ -5,13 +5,21 @@
 /* Now define the internal interfaces.  */
 # if __TIMESIZE == 64
 #  define __pselect64 __pselect
+#  define __select64  __select
 #else
 # include <struct___timespec64.h>
+# include <struct___timeval64.h>
+
 extern int __pselect64 (int __nfds, fd_set *__readfds,
  fd_set *__writefds, fd_set *__exceptfds,
  const struct __timespec64 *__timeout,
  const __sigset_t *__sigmask);
 libc_hidden_proto (__pselect64)
+
+extern int __select64 (int __nfds, fd_set *__readfds,
+       fd_set *__writefds, fd_set *__exceptfds,
+       struct __timeval64 *__timeout);
+libc_hidden_proto (__select64)
 #endif
 extern int __pselect (int __nfds, fd_set *__readfds,
       fd_set *__writefds, fd_set *__exceptfds,
diff --git a/include/time.h b/include/time.h
index fe4da9ca10..936486e206 100644
--- a/include/time.h
+++ b/include/time.h
@@ -464,6 +464,12 @@ valid_timespec_to_timeval32 (const struct timespec ts)
   return (struct __timeval32) { (time_t) ts.tv_sec, ts.tv_nsec / 1000 };
 }
 
+static inline struct __timeval64
+valid_timespec_to_timeval64 (const struct timespec ts)
+{
+  return (struct __timeval64) { (time_t) ts.tv_sec, ts.tv_nsec / 1000 };
+}
+
 /* Check if a value is in the valid nanoseconds range. Return true if
    it is, false otherwise.  */
 static inline bool
diff --git a/sysdeps/unix/sysv/linux/select.c b/sysdeps/unix/sysv/linux/select.c
index 54c50edba2..df4fcc3362 100644
--- a/sysdeps/unix/sysv/linux/select.c
+++ b/sysdeps/unix/sysv/linux/select.c
@@ -21,6 +21,7 @@
 #include <sys/select.h>
 #include <errno.h>
 #include <sysdep-cancel.h>
+#include <time64-support.h>
 
 /* Check the first NFDS descriptors each in READFDS (if not NULL) for read
    readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS
@@ -28,43 +29,84 @@
    after waiting the interval specified therein.  Returns the number of ready
    descriptors, or -1 for errors.  */
 
-#ifdef __NR__newselect
-# undef __NR_select
-# define __NR_select __NR__newselect
-#endif
-
 int
-__select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
-  struct timeval *timeout)
+__select64 (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+    struct __timeval64 *timeout)
 {
-#ifdef __NR_select
-  return SYSCALL_CANCEL (select, nfds, readfds, writefds, exceptfds,
- timeout);
-#else
-  int result;
-  struct timespec ts, *tsp = NULL;
-
-  if (timeout)
+  struct __timespec64 ts64, *pts64 = NULL;
+  if (timeout != NULL)
     {
-      TIMEVAL_TO_TIMESPEC (timeout, &ts);
-      tsp = &ts;
+      ts64 = timeval64_to_timespec64 (*timeout);
+      pts64 = &ts64;
     }
 
-  result = SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds, tsp,
-   NULL);
-
-  if (timeout)
+#ifndef __NR_pselect6_time64
+# define __NR_pselect6_time64 __NR_pselect6
+#endif
+  int r;
+  if (supports_time64 ())
     {
-      /* Linux by default will update the timeout after a pselect6 syscall
-         (though the pselect() glibc call suppresses this behavior).
-         Since select() on Linux has the same behavior as the pselect6
-         syscall, we update the timeout here.  */
-      TIMESPEC_TO_TIMEVAL (timeout, &ts);
+      r = SYSCALL_CANCEL (pselect6_time64, nfds, readfds, writefds, exceptfds,
+  pts64, NULL);
+      if (r == 0 || errno != ENOSYS)
+ {
+  if (timeout != NULL)
+    TIMEVAL_TO_TIMESPEC (timeout, &ts64);
+  return r;
+ }
+
+      mark_time64_unsupported ();
     }
 
-  return result;
+#ifndef __ASSUME_TIME64_SYSCALLS
+  struct timespec ts32, *pts32 = NULL;
+  if (timeout != NULL)
+    {
+      if (! in_time_t_range (timeout->tv_sec))
+ {
+  __set_errno (EINVAL);
+  return -1;
+ }
+      ts32 = valid_timespec64_to_timespec (ts64);
+      pts32 = &ts32;
+    }
+# ifndef __ASSUME_PSELECT
+#  ifdef __NR__newselect
+#   undef __NR_select
+#   define __NR_select __NR__newselect
+#  endif
+  r = SYSCALL_CANCEL (select, nfds, readfds, writefds, exceptfds, pts32);
+# else
+  r = SYSCALL_CANCEL (pselect6, nfds, readfds, writefds, exceptfds, pts32,
+      NULL);
+# endif
+  if (r >= 0 && timeout != NULL)
+    *timeout = valid_timespec_to_timeval64 (ts32);
 #endif
+
+  return r;
 }
+
+#if __TIMESIZE != 64
+libc_hidden_def (__select64)
+
+int
+__select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+  struct timeval *timeout)
+{
+  struct __timeval64 tv64, *ptv64 = NULL;
+  if (timeout != 0)
+    {
+      tv64 = valid_timeval_to_timeval64 (*timeout);
+      ptv64 = &tv64;
+    }
+  int r = __select64 (nfds, readfds, writefds, exceptfds, ptv64);
+  if (r >= 0 && timeout != NULL)
+    /* The remanining timeout will be always less the input TIMEOUT.  */
+    *timeout = valid_timeval64_to_timeval (tv64);
+  return r;
+}
+#endif
 libc_hidden_def (__select)
 
 weak_alias (__select, select)
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 18/23] linux: Add time64 recvmmsg support

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
The wire-up syscall __NR_recvmmsg_time64 (for 32-bit) or
__NR_recvmmsg (for 64-bit) is used as default.  The 32-bit fallback
is used iff __ASSUME_TIME64_SYSCALLS is not defined, which assumes the
kernel ABI provides either __NR_socketcall or __NR_recvmmsg
(32-bit time_t).

It does not handle the timestamps on ancillary data (SCM_TIMESTAMPING
records).

Checked on x86_64-linux-gnu and i686-linux-gnu.
---
 include/sys/socket.h               |  8 ++++
 sysdeps/unix/sysv/linux/recvmmsg.c | 63 ++++++++++++++++++++++++------
 2 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/include/sys/socket.h b/include/sys/socket.h
index 26db0e0d77..0e39dd2a3a 100644
--- a/include/sys/socket.h
+++ b/include/sys/socket.h
@@ -104,6 +104,14 @@ extern ssize_t __libc_recvmsg (int __fd, struct msghdr *__message,
        int __flags);
 extern ssize_t __recvmsg (int __fd, struct msghdr *__message,
   int __flags) attribute_hidden;
+#if __TIMESIZE == 64
+# define __recvmmsg64 __recvmmsg
+#else
+extern int __recvmmsg64 (int __fd, struct mmsghdr *vmessages,
+ unsigned int vlen, int flags,
+ struct __timespec64 *timeout);
+libc_hidden_proto (__recvmmsg64)
+#endif
 
 /* Set socket FD's option OPTNAME at protocol level LEVEL
    to *OPTVAL (which is OPTLEN bytes long).
diff --git a/sysdeps/unix/sysv/linux/recvmmsg.c b/sysdeps/unix/sysv/linux/recvmmsg.c
index 42c80c59c3..a29c91fb76 100644
--- a/sysdeps/unix/sysv/linux/recvmmsg.c
+++ b/sysdeps/unix/sysv/linux/recvmmsg.c
@@ -16,21 +16,62 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
 #include <sys/socket.h>
-
-#include <sysdep-cancel.h>
-#include <sys/syscall.h>
+#include <sysdep.h>
 #include <socketcall.h>
-#include <kernel-features.h>
 
 int
-recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
-  struct timespec *tmo)
+__recvmmsg64 (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
+      struct __timespec64 *timeout)
 {
-#ifdef __ASSUME_RECVMMSG_SYSCALL
-  return SYSCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
-#else
-  return SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, tmo);
+#ifndef __NR_recvmmsg_time64
+# define __NR_recvmmsg_time64 __NR_recvmmsg
 #endif
+  int r = SYSCALL_CANCEL (recvmmsg_time64, fd, vmessages, vlen, flags,
+  timeout);
+#ifndef __ASSUME_TIME64_SYSCALLS
+  if (r >= 0 || errno != ENOSYS)
+    return r;
+
+  struct timespec ts32, *pts32 = NULL;
+  if (timeout != NULL)
+    {
+      if (! in_time_t_range (timeout->tv_sec))
+ {
+  __set_errno (EINVAL);
+  return -1;
+ }
+      ts32 = valid_timespec64_to_timespec (*timeout);
+      pts32 = &ts32;
+    }
+# ifdef __ASSUME_RECVMMSG_SYSCALL
+  r = SYSCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, pts32);
+# else
+  r = SOCKETCALL_CANCEL (recvmmsg, fd, vmessages, vlen, flags, pts32);
+# endif
+  if (r >= 0 && timeout != NULL)
+    *timeout = valid_timespec_to_timespec64 (ts32);
+#endif /* __ASSUME_TIME64_SYSCALLS  */
+  return r;
 }
+#if __TIMESIZE != 64
+libc_hidden_def (__recvmmsg64)
+
+int
+__recvmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags,
+    struct timespec *timeout)
+{
+  struct __timespec64 ts64, *pts64 = NULL;
+  if (timeout != NULL)
+    {
+      ts64 = valid_timespec_to_timespec64 (*timeout);
+      pts64 = &ts64;
+    }
+  int r = __recvmmsg64 (fd, vmessages, vlen, flags, pts64);
+  if (r >= 0)
+    /* The remanining timeout will be always less the input TIMEOUT.  */
+    *timeout = valid_timespec64_to_timespec (ts64);
+  return r;
+}
+#endif
+weak_alias (__recvmmsg, recvmmsg)
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 19/23] linux: Add time64 sigtimedwait support

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
The syscall __NR_sigtimedwait_time64 (for 32-bit) or __NR_sigtimedwait
(for 64-bit) is used as default.  The 32-bit fallback is used iff
__ASSUME_TIME64_SYSCALLS is not defined, which assumes the kernel ABI
provides either __NR_rt_sigtimedwait (32-bit time_t).

Checked on x86_64-linux-gnu and i686-linux-gnu.
---
 include/signal.h                       |  8 ++++
 sysdeps/unix/sysv/linux/sigtimedwait.c | 59 +++++++++++++++++++++-----
 2 files changed, 56 insertions(+), 11 deletions(-)

diff --git a/include/signal.h b/include/signal.h
index b4ee02d153..544d701bce 100644
--- a/include/signal.h
+++ b/include/signal.h
@@ -38,6 +38,14 @@ extern int __sigwait (const sigset_t *__set, int *__sig);
 libc_hidden_proto (__sigwait)
 extern int __sigwaitinfo (const sigset_t *__set, siginfo_t *__info);
 libc_hidden_proto (__sigwaitinfo)
+#if __TIMESIZE == 64
+# define __sigtimedwait64 __sigtimedwait
+#else
+# include <struct___timespec64.h>
+extern int __sigtimedwait64 (const sigset_t *__set, siginfo_t *__info,
+     const struct __timespec64 *__timeout);
+libc_hidden_proto (__sigtimedwait64)
+#endif
 extern int __sigtimedwait (const sigset_t *__set, siginfo_t *__info,
    const struct timespec *__timeout);
 libc_hidden_proto (__sigtimedwait)
diff --git a/sysdeps/unix/sysv/linux/sigtimedwait.c b/sysdeps/unix/sysv/linux/sigtimedwait.c
index f2ef3aad45..acbc75da16 100644
--- a/sysdeps/unix/sysv/linux/sigtimedwait.c
+++ b/sysdeps/unix/sysv/linux/sigtimedwait.c
@@ -15,20 +15,12 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
 #include <signal.h>
-#include <string.h>
-#include <sysdep-cancel.h>
+#include <sysdep.h>
 
-int
-__sigtimedwait (const sigset_t *set, siginfo_t *info,
- const struct timespec *timeout)
+static int
+adjust_si_code (int result, siginfo_t *info)
 {
-  /* XXX The size argument hopefully will have to be changed to the
-     real size of the user-level sigset_t.  */
-  int result = SYSCALL_CANCEL (rt_sigtimedwait, set, info, timeout,
-       __NSIG_BYTES);
-
   /* The kernel generates a SI_TKILL code in si_code in case tkill is
      used.  tkill is transparently used in raise().  Since having
      SI_TKILL as a code is useful in general we fold the results
@@ -38,5 +30,50 @@ __sigtimedwait (const sigset_t *set, siginfo_t *info,
 
   return result;
 }
+
+int
+__sigtimedwait64 (const sigset_t *set, siginfo_t *info,
+  const struct __timespec64 *timeout)
+{
+#ifndef __NR_rt_sigtimedwait_time64
+# define __NR_rt_sigtimedwait_time64 __NR_rt_sigtimedwait
+#endif
+  int r = SYSCALL_CANCEL (rt_sigtimedwait_time64, set, info, timeout,
+  __NSIG_BYTES);
+#ifndef __ASSUME_TIME64_SYSCALLS
+  if (r >= 0 || errno != ENOSYS)
+    return adjust_si_code (r, info);
+
+  struct timespec ts32, *pts32 = NULL;
+  if (timeout != NULL)
+    {
+      if (! in_time_t_range (timeout->tv_sec))
+ {
+  __set_errno (EINVAL);
+  return -1;
+ }
+      ts32 = valid_timespec64_to_timespec (*timeout);
+      pts32 = &ts32;
+    }
+  r = SYSCALL_CANCEL (rt_sigtimedwait, set, info, pts32, __NSIG_BYTES);
+#endif
+  return adjust_si_code (r, info);
+}
+#if __TIMESIZE != 64
+libc_hidden_def (__sigtimedwait64)
+
+int
+__sigtimedwait (const sigset_t *set, siginfo_t *info,
+ const struct timespec *timeout)
+{
+  struct __timespec64 ts64, *pts64 = NULL;
+  if (timeout != NULL)
+    {
+      ts64 = valid_timespec_to_timespec64 (*timeout);
+      pts64 = &ts64;
+    }
+  return __sigtimedwait64 (set, info, pts64);
+}
+#endif
 libc_hidden_def (__sigtimedwait)
 weak_alias (__sigtimedwait, sigtimedwait)
--
2.25.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 20/23] linux: Use 64-bit time_t syscall on clock_getcputclockid

Sourceware - libc-alpha mailing list
In reply to this post by Sourceware - libc-alpha mailing list
The syscall __NR_clock_getres_time64 (for 32-bit) or __NR_clock_getres
(for 64-bit) is used as default.  The 32-bit fallback is used iff
__ASSUME_TIME64_SYSCALLS is not defined, which assumes the kernel ABI
provides either __NR_rt_sigtimedwait (32-bit time_t).

Since the symbol does not use any type which might be affected by the
time_t, there is no need to add a 64-bit variant.

Checked on x86_64-linux-gnu and i686-linux-gnu (on 5.4 and on 4.15
kernel).
---
 sysdeps/unix/sysv/linux/clock_getcpuclockid.c | 37 ++++++++++++-------
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/clock_getcpuclockid.c b/sysdeps/unix/sysv/linux/clock_getcpuclockid.c
index be1f477187..3c3bdd42ed 100644
--- a/sysdeps/unix/sysv/linux/clock_getcpuclockid.c
+++ b/sysdeps/unix/sysv/linux/clock_getcpuclockid.c
@@ -22,6 +22,20 @@
 #include "kernel-posix-cpu-timers.h"
 #include <shlib-compat.h>
 
+static int
+clock_getcpuclockid_return (int r, clockid_t pidclock, clockid_t *clock_id)
+{
+  if (r == 0)
+    {
+      *clock_id = pidclock;
+      return 0;
+    }
+  if (r == -EINVAL)
+    /* The clock_getres system call checked the PID for us.  */
+    return ESRCH;
+  return -r;
+}
+
 int
 __clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
 {
@@ -30,20 +44,17 @@ __clock_getcpuclockid (pid_t pid, clockid_t *clock_id)
 
   const clockid_t pidclock = MAKE_PROCESS_CPUCLOCK (pid, CPUCLOCK_SCHED);
 
-  int r = INTERNAL_SYSCALL_CALL (clock_getres, pidclock, NULL);
-  if (!INTERNAL_SYSCALL_ERROR_P (r))
-    {
-      *clock_id = pidclock;
-      return 0;
-    }
+#ifndef __NR_clock_getres_time64
+# define __NR_clock_getres_time64 __NR_clock_getres
+#endif
+  int r = INTERNAL_SYSCALL_CALL (clock_getres_time64, pidclock, NULL);
+#ifndef __ASSUME_TIME64_SYSCALLS
+  if (r == 0 && r != -ENOSYS)
+    return clock_getcpuclockid_return (r, pidclock, clock_id);
 
-  if (INTERNAL_SYSCALL_ERRNO (r) == EINVAL)
-    {
-      /* The clock_getres system call checked the PID for us.  */
-      return ESRCH;
-    }
-  else
-    return INTERNAL_SYSCALL_ERRNO (r);
+  r = INTERNAL_SYSCALL_CALL (clock_getres, pidclock, NULL);
+#endif
+  return clock_getcpuclockid_return (r, pidclock, clock_id);
 }
 
 versioned_symbol (libc, __clock_getcpuclockid, clock_getcpuclockid, GLIBC_2_17);
--
2.25.1

12