]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
y2038: nptl: Convert pthread_rwlock_{clock|timed}{rd|wr}lock to support 64 bit time
authorLukasz Majewski <lukma@denx.de>
Tue, 8 Sep 2020 09:51:23 +0000 (11:51 +0200)
committerLukasz Majewski <lukma@denx.de>
Sun, 4 Oct 2020 15:13:46 +0000 (17:13 +0200)
The pthread_rwlock_clockrdlock, pthread_rwlock_clockwrlock,
pthread_rwlock_timedrdlock and pthread_rwlock_timedwrlock have been converted
to support 64 bit time.

This change uses new futex_abstimed_wait64 function in
./sysdeps/nptl/futex-helpers.c, which uses futex_time64 where possible.

The pthread_rwlock_{clock|timed}{rd|wr}lock only accepts absolute time.
Moreover, there is no need to check for NULL passed as *abstime pointer to the
syscalls as those calls have exported symbols marked with __nonull attribute
for abstime.

For systems with __TIMESIZE != 64 && __WORDSIZE == 32:
- Conversions between 64 bit time to 32 bit are necessary
- Redirection to pthread_rwlock_{clock|timed}{rd|wr}lock 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_rwlock_{clock|timed}{rd|wr}lock64
and __pthread_rwlock_{clock|timed}{rd|wr}lock.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
nptl/pthreadP.h
nptl/pthread_rwlock_clockrdlock.c
nptl/pthread_rwlock_clockwrlock.c
nptl/pthread_rwlock_common.c
nptl/pthread_rwlock_rdlock.c
nptl/pthread_rwlock_timedrdlock.c
nptl/pthread_rwlock_timedwrlock.c
nptl/pthread_rwlock_wrlock.c

index 9bb44c8535a6ae54ab6588df72ddc8d591e6ca7a..5bcc8a2db5ae8732d46caf47e9b0f4a837128b22 100644 (file)
@@ -464,6 +464,10 @@ extern int __pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);
 # define __pthread_timedjoin_np64 __pthread_timedjoin_np
 # define __pthread_cond_timedwait64 __pthread_cond_timedwait
 # define __pthread_cond_clockwait64 __pthread_cond_clockwait
+# define __pthread_rwlock_clockrdlock64 __pthread_rwlock_clockrdlock
+# define __pthread_rwlock_clockwrlock64 __pthread_rwlock_clockwrlock
+# define __pthread_rwlock_timedrdlock64 __pthread_rwlock_timedrdlock
+# define __pthread_rwlock_timedwrlock64 __pthread_rwlock_timedwrlock
 #else
 extern int __pthread_clockjoin_np64 (pthread_t threadid, void **thread_return,
                                      clockid_t clockid,
@@ -481,6 +485,20 @@ extern int __pthread_cond_clockwait64 (pthread_cond_t *cond,
                                        clockid_t clockid,
                                        const struct __timespec64 *abstime);
 libpthread_hidden_proto (__pthread_cond_clockwait64)
+extern int __pthread_rwlock_clockrdlock64 (pthread_rwlock_t *rwlock,
+                                           clockid_t clockid,
+                                           const struct __timespec64 *abstime);
+libpthread_hidden_proto (__pthread_rwlock_clockrdlock64)
+extern int __pthread_rwlock_clockwrlock64 (pthread_rwlock_t *rwlock,
+                                           clockid_t clockid,
+                                           const struct __timespec64 *abstime);
+libpthread_hidden_proto (__pthread_rwlock_clockwrlock64)
+extern int __pthread_rwlock_timedrdlock64 (pthread_rwlock_t *rwlock,
+                                           const struct __timespec64 *abstime);
+libpthread_hidden_proto (__pthread_rwlock_timedrdlock64)
+extern int __pthread_rwlock_timedwrlock64 (pthread_rwlock_t *rwlock,
+                                           const struct __timespec64 *abstime);
+libpthread_hidden_proto (__pthread_rwlock_timedwrlock64)
 #endif
 
 extern int __pthread_cond_timedwait (pthread_cond_t *cond,
index 4cedfd1dcdbee8f9be3d72543cb1101e8863ee7f..c2bccc2145049a7d8739cedd82cf6b75023a747e 100644 (file)
 
 /* See pthread_rwlock_common.c.  */
 int
-pthread_rwlock_clockrdlock (pthread_rwlock_t *rwlock, clockid_t clockid,
-                           const struct timespec *abstime)
+__pthread_rwlock_clockrdlock64 (pthread_rwlock_t *rwlock, clockid_t clockid,
+                                const struct __timespec64 *abstime)
 {
-  return __pthread_rwlock_rdlock_full (rwlock, clockid, abstime);
+  return __pthread_rwlock_rdlock_full64 (rwlock, clockid, abstime);
 }
+
+#if __TIMESIZE != 64
+libpthread_hidden_def (__pthread_rwlock_clockrdlock64)
+
+int
+__pthread_rwlock_clockrdlock (pthread_rwlock_t *rwlock, clockid_t clockid,
+                              const struct timespec *abstime)
+{
+  struct __timespec64 ts64 = valid_timespec_to_timespec64 (*abstime);
+
+  return __pthread_rwlock_clockrdlock64 (rwlock, clockid, &ts64);
+}
+#endif
+weak_alias (__pthread_rwlock_clockrdlock, pthread_rwlock_clockrdlock)
index 7a954cf52979dd1441cb688e2ff2858d75ba8caf..67a7421c7fe8080c9e58880cb147e734aa3b9dc1 100644 (file)
 
 /* See pthread_rwlock_common.c.  */
 int
-pthread_rwlock_clockwrlock (pthread_rwlock_t *rwlock, clockid_t clockid,
-                           const struct timespec *abstime)
+__pthread_rwlock_clockwrlock64 (pthread_rwlock_t *rwlock, clockid_t clockid,
+                                const struct __timespec64 *abstime)
 {
-  return __pthread_rwlock_wrlock_full (rwlock, clockid, abstime);
+  return __pthread_rwlock_wrlock_full64 (rwlock, clockid, abstime);
 }
+
+#if __TIMESIZE != 64
+libpthread_hidden_def (__pthread_rwlock_clockwrlock64)
+
+int
+__pthread_rwlock_clockwrlock (pthread_rwlock_t *rwlock, clockid_t clockid,
+                              const struct timespec *abstime)
+{
+  struct __timespec64 ts64 = valid_timespec_to_timespec64 (*abstime);
+
+  return __pthread_rwlock_clockwrlock64 (rwlock, clockid, &ts64);
+}
+#endif
+weak_alias (__pthread_rwlock_clockwrlock, pthread_rwlock_clockwrlock)
index 3fbc66ded2176fdb71599c0648c5ad45d5296c6b..4c9f582d3daefec6648b26dc8bcda711fbdcc452 100644 (file)
@@ -278,9 +278,8 @@ __pthread_rwlock_rdunlock (pthread_rwlock_t *rwlock)
 
 
 static __always_inline int
-__pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
-    clockid_t clockid,
-    const struct timespec *abstime)
+__pthread_rwlock_rdlock_full64 (pthread_rwlock_t *rwlock, clockid_t clockid,
+                                const struct __timespec64 *abstime)
 {
   unsigned int r;
 
@@ -330,8 +329,9 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
                      & PTHREAD_RWLOCK_RWAITING) != 0)
                {
                  int private = __pthread_rwlock_get_private (rwlock);
-                 int err = futex_abstimed_wait (&rwlock->__data.__readers,
-                                                r, clockid, abstime, private);
+                 int err = __futex_abstimed_wait64 (&rwlock->__data.__readers,
+                                                    r, clockid, abstime,
+                                                    private);
                  /* We ignore EAGAIN and EINTR.  On time-outs, we can just
                     return because we don't need to clean up anything.  */
                  if (err == ETIMEDOUT)
@@ -457,9 +457,9 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
                  (&rwlock->__data.__wrphase_futex,
                   &wpf, wpf | PTHREAD_RWLOCK_FUTEX_USED)))
            continue;
-         int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
-                                        1 | PTHREAD_RWLOCK_FUTEX_USED,
-                                        clockid, abstime, private);
+         int err = __futex_abstimed_wait64 (&rwlock->__data.__wrphase_futex,
+                                            1 | PTHREAD_RWLOCK_FUTEX_USED,
+                                            clockid, abstime, private);
          if (err == ETIMEDOUT)
            {
              /* If we timed out, we need to unregister.  If no read phase
@@ -585,9 +585,8 @@ __pthread_rwlock_wrunlock (pthread_rwlock_t *rwlock)
 
 
 static __always_inline int
-__pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
-    clockid_t clockid,
-    const struct timespec *abstime)
+__pthread_rwlock_wrlock_full64 (pthread_rwlock_t *rwlock, clockid_t clockid,
+                                const struct __timespec64 *abstime)
 {
   /* Make sure any passed in clockid and timeout value are valid.  Note that
      the previous implementation assumed that this check *must* not be
@@ -728,9 +727,9 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
             share the flag, and another writer will wake one of the writers
             in this group.  */
          may_share_futex_used_flag = true;
-         int err = futex_abstimed_wait (&rwlock->__data.__writers_futex,
-                                        1 | PTHREAD_RWLOCK_FUTEX_USED,
-                                        clockid, abstime, private);
+         int err = __futex_abstimed_wait64 (&rwlock->__data.__writers_futex,
+                                            1 | PTHREAD_RWLOCK_FUTEX_USED,
+                                            clockid, abstime, private);
          if (err == ETIMEDOUT)
            {
              if (prefer_writer)
@@ -827,9 +826,9 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
                  (&rwlock->__data.__wrphase_futex, &wpf,
                   PTHREAD_RWLOCK_FUTEX_USED)))
            continue;
-         int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
-                                        PTHREAD_RWLOCK_FUTEX_USED,
-                                        clockid, abstime, private);
+         int err = __futex_abstimed_wait64 (&rwlock->__data.__wrphase_futex,
+                                            PTHREAD_RWLOCK_FUTEX_USED,
+                                            clockid, abstime, private);
          if (err == ETIMEDOUT)
            {
              if (rwlock->__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP)
index 04cecad39539ec63c510a66150e7120f4434152c..2b8509a49c7b4cafec0bd5e19e210e0c09d1a2a8 100644 (file)
@@ -24,7 +24,7 @@ __pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
 {
   LIBC_PROBE (rdlock_entry, 1, rwlock);
 
-  int result = __pthread_rwlock_rdlock_full (rwlock, CLOCK_REALTIME, NULL);
+  int result = __pthread_rwlock_rdlock_full64 (rwlock, CLOCK_REALTIME, NULL);
   LIBC_PROBE (rdlock_acquire_read, 1, rwlock);
   return result;
 }
index c5d8aee909201d5625e03887f11d1ed47c9d677f..0bf4559a6575ca0a6a71080df434a9cc616d2b49 100644 (file)
 
 /* See pthread_rwlock_common.c.  */
 int
-pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock,
-    const struct timespec *abstime)
+__pthread_rwlock_timedrdlock64 (pthread_rwlock_t *rwlock,
+                                const struct __timespec64 *abstime)
 {
-  return __pthread_rwlock_rdlock_full (rwlock, CLOCK_REALTIME, abstime);
+  return __pthread_rwlock_rdlock_full64 (rwlock, CLOCK_REALTIME, abstime);
 }
+
+#if __TIMESIZE != 64
+libpthread_hidden_def (__pthread_rwlock_timedrdlock64)
+
+int
+__pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock,
+                              const struct timespec *abstime)
+{
+  struct __timespec64 ts64 = valid_timespec_to_timespec64 (*abstime);
+
+  return __pthread_rwlock_timedrdlock64 (rwlock, &ts64);
+}
+#endif
+weak_alias (__pthread_rwlock_timedrdlock, pthread_rwlock_timedrdlock)
index ccee8b77d99adaee13c83babea2313eb302954b4..db17dcfc530ba5a47913d53379237b31741c1def 100644 (file)
 
 /* See pthread_rwlock_common.c.  */
 int
-pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock,
-    const struct timespec *abstime)
+__pthread_rwlock_timedwrlock64 (pthread_rwlock_t *rwlock,
+                                const struct __timespec64 *abstime)
 {
-  return __pthread_rwlock_wrlock_full (rwlock, CLOCK_REALTIME, abstime);
+  return __pthread_rwlock_wrlock_full64 (rwlock, CLOCK_REALTIME, abstime);
 }
+
+#if __TIMESIZE != 64
+libpthread_hidden_def (__pthread_rwlock_timedwrlock64)
+
+int
+__pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock,
+                              const struct timespec *abstime)
+{
+  struct __timespec64 ts64 = valid_timespec_to_timespec64 (*abstime);
+
+  return __pthread_rwlock_timedwrlock64 (rwlock, &ts64);
+}
+#endif
+weak_alias (__pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock)
index a42aa626f07249bf00614d26fe20a22e9d2567ce..210e6cffdc7dd5f4b14eac2e810dd0e3423a0414 100644 (file)
@@ -24,7 +24,7 @@ __pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
 {
   LIBC_PROBE (wrlock_entry, 1, rwlock);
 
-  int result = __pthread_rwlock_wrlock_full (rwlock, CLOCK_REALTIME, NULL);
+  int result = __pthread_rwlock_wrlock_full64 (rwlock, CLOCK_REALTIME, NULL);
   LIBC_PROBE (wrlock_acquire_write, 1, rwlock);
   return result;
 }