about summary refs log tree commit diff
path: root/nptl/pthread_join_common.c
diff options
context:
space:
mode:
authorLukasz Majewski <lukma@denx.de>2020-07-20 15:50:12 +0200
committerLukasz Majewski <lukma@denx.de>2020-08-13 14:16:34 +0200
commit4a14cb87cad30bb15bb906e579089109874f3071 (patch)
tree4a5cdc2249d5c749985f5da2833e8e5a337d2573 /nptl/pthread_join_common.c
parent12b2fd0ef9f51642ad00646c1a2e3490e25f4a00 (diff)
downloadglibc-4a14cb87cad30bb15bb906e579089109874f3071.tar.gz
glibc-4a14cb87cad30bb15bb906e579089109874f3071.tar.xz
glibc-4a14cb87cad30bb15bb906e579089109874f3071.zip
y2038: nptl: Convert pthread_{clock|timed}join_np to support 64 bit time
The pthread_clockjoin_np and pthread_timedjoin_np have been converted to
support 64 bit time.

This change introduces new futex_timed_wait_cancel64 function in
./sysdeps/nptl/futex-internal.h, which uses futex_time64 where possible
and tries to replace low-level preprocessor macros from
lowlevellock-futex.h
The pthread_{timed|clock}join_np only accept absolute time. Moreover,
there is no need to check for NULL passed as *abstime pointer as
clockwait_tid() always passes struct __timespec64.

For systems with __TIMESIZE != 64 && __WORDSIZE == 32:
- Conversions between 64 bit time to 32 bit are necessary
- Redirection to __pthread_{clock|timed}join_np64 will provide support
  for 64 bit time

Build tests:
./src/scripts/build-many-glibcs.py glibcs

Run-time tests:
- Run specific tests on ARM/x86 32bit systems (qemu):
  https://github.com/lmajewski/meta-y2038 and run tests:
  https://github.com/lmajewski/y2038-tests/commits/master

Above tests were performed with Y2038 redirection applied as well as without
to test the proper usage of both __pthread_{timed|clock}join_np64 and
__pthread_{timed|clock}join_np.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'nptl/pthread_join_common.c')
-rw-r--r--nptl/pthread_join_common.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/nptl/pthread_join_common.c b/nptl/pthread_join_common.c
index a96ceafde4..67d8e2b780 100644
--- a/nptl/pthread_join_common.c
+++ b/nptl/pthread_join_common.c
@@ -20,6 +20,7 @@
 #include <atomic.h>
 #include <stap-probe.h>
 #include <time.h>
+#include <futex-internal.h>
 
 static void
 cleanup (void *arg)
@@ -37,9 +38,11 @@ cleanup (void *arg)
    afterwards.  The kernel up to version 3.16.3 does not use the private futex
    operations for futex wake-up when the clone terminates.  */
 static int
-clockwait_tid (pid_t *tidp, clockid_t clockid, const struct timespec *abstime)
+clockwait_tid (pid_t *tidp, clockid_t clockid,
+               const struct __timespec64 *abstime)
 {
   pid_t tid;
+  int ret;
 
   if (! valid_nanoseconds (abstime->tv_nsec))
     return EINVAL;
@@ -47,11 +50,11 @@ clockwait_tid (pid_t *tidp, clockid_t clockid, const struct timespec *abstime)
   /* Repeat until thread terminated.  */
   while ((tid = *tidp) != 0)
     {
-      struct timespec rt;
+      struct __timespec64 rt;
 
       /* Get the current time. This can only fail if clockid is
          invalid. */
-      if (__glibc_unlikely (__clock_gettime (clockid, &rt)))
+      if (__glibc_unlikely (__clock_gettime64 (clockid, &rt)))
         return EINVAL;
 
       /* Compute relative timeout.  */
@@ -70,9 +73,9 @@ clockwait_tid (pid_t *tidp, clockid_t clockid, const struct timespec *abstime)
       /* If *tidp == tid, wait until thread terminates or the wait times out.
          The kernel up to version 3.16.3 does not use the private futex
          operations for futex wake-up when the clone terminates.  */
-      if (lll_futex_timed_wait_cancel (tidp, tid, &rt, LLL_SHARED)
-	  == -ETIMEDOUT)
-        return ETIMEDOUT;
+      ret = futex_timed_wait_cancel64 (tidp, tid, &rt, LLL_SHARED);
+      if (ret == -ETIMEDOUT || ret == -EOVERFLOW)
+        return -ret;
     }
 
   return 0;
@@ -80,8 +83,8 @@ clockwait_tid (pid_t *tidp, clockid_t clockid, const struct timespec *abstime)
 
 int
 __pthread_clockjoin_ex (pthread_t threadid, void **thread_return,
-			clockid_t clockid,
-			const struct timespec *abstime, bool block)
+                        clockid_t clockid,
+                        const struct __timespec64 *abstime, bool block)
 {
   struct pthread *pd = (struct pthread *) threadid;