unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions
@ 2019-06-18 16:33 Mike Crowe
  2019-06-18 16:33 ` [PATCH v4 01/12] support: Add xclock_now helper function Mike Crowe
                   ` (13 more replies)
  0 siblings, 14 replies; 32+ messages in thread
From: Mike Crowe @ 2019-06-18 16:33 UTC (permalink / raw
  To: libc-alpha; +Cc: Mike Crowe

My attempts[1] to add a variant of pthread_cond_timedwait that would accept
a clockid_t parameter led me to propose[2] to The Austin Group the addition
of an entire family of functions that accept a clockid_t parameter to
indicate the clock that the timespec absolute timeout parameter should be
measured against. They responded positively to the request but an
implementation is required before the proposal can proceed.

This patch series is the second version of the first part of that
implementation in glibc, it contains implementations and tests for
four new functions:

int pthread_cond_clockwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
                           clockid_t clock, const struct timespec *abstime)

int pthread_rwlock_clockrdlock(pthread_rwlock_t *rwlock, clockid_t clock,
                               const struct timespec *abstime)

int pthread_rwlock_clockwrlock(pthread_rwlock_t *rwlock, clockid_t clock,
                               const struct timespec *abstime)

int sem_clockwait(sem_t *restrict, clockid_t clock_id, const struct
                  timespec *restrict)

int pthread_mutex_clocklock (pthread_mutex_t *mutex,
			     clockid_t clockid,
			     const struct timespec *abstime)

These are implemented by replacing the underlying equivalent _timed
functions with ones that accept a clockid_t parameter, and then
implementing the existing _timed functions by passing CLOCK_REALTIME
to the new implementation. This requires clockid_t parameters to be
added to the underlying futex-internal, lowlevellock-futex and
lowlevellock functions.

glibc-specific functions, such as pthread_timedjoin_np are next on the
list after that.

The mq_clockreceive and mq_clocksend functions corresponding to
mq_timedreceive and mq_timedsend require kernel changes before they can be
implemented in glibc.

As implemented, passing an unsupported or invalid clock to these functions
yields EINVAL. I considered returning ENOTSUP for valid-but-unsupported
clocks, but I was worried that there was a risk that the list of valid
clocks would not be updated when a new clock was added to glibc.

Rather than duplicating tests, I've parameterised them so that the same
tests can be run on the existing timedwait functions and the new clockwait
functions.

The changes have been tested with "make check" and "make check-abi" on
x86, x86_64, arm and arm64. I've attempted to update the abilists for
all architectures, but cannot test all of them.

I've compile-tested the powerpc and s390-specific implementations of
lll_clockwait. Although I've updated the sparc32-specific
implementation, I have been unable to test it since it appears that
even Debian hasn't supported sparc32 for nearly twenty years! I was
able to compile-test sparc64 though.

Thanks to everyone that commented on previous versions of this patch
series. They have been a great help, and I hope that I have
incorporated their feedback correctly.

Adhemerval Zanella suggested that timespec validity checks could be
consolidated. I think that's a good idea, but it would need to be a
different change. This series doesn't really make that change any
harder to do, and I can try to tackle that separately.

I've not updated the dates in the ChangeLog entries. Presumably that's
best done just before this lands to ensure that the dates are
monotonic. :)

Changes since v3[7]:

* Include previously-separate pthread_mutex_clocklock
  implementation[6] too.
* Add commit to remove futex_supports_exact_relative_timeouts as
  suggested by Adhemerval Zanella.
* Use xclock_now in new tst-cond27.c.
* Disable verbose output from tst-rwlock6.c by default.
* Add verbose_printf to libsupport and use it in tst-rwlock6.c and
  tst-cond11.c.
* Improve NEWS entry.
* Update comments in futex-internal.h to indicate that the clock for
  abstimed waits is now specified rather than always being
  CLOCK_REALTIME.
* Add __nonnull attribute to __pthread_cond_clockwait declaration.
* Improve comment for lowlevellock.h:__lll_clocklock.
* Cope with __clock_gettime failure in __lll_timedlock_wait.
* Add sparc32 implementation of lll_clocklock.

Changes since v2[5]:
* Don't update hurd abilist since the new functions aren't (yet) in
  htl.

Changes since v1[4]:
* Many whitespace/formatting cleanups
* Rebase on top of tests that use libsupport
* Use futex_abstimed_supported_clockid in __pthread_cond_clockwait.
* Update all abilists.
* Add to NEWS.

[1] https://sourceware.org/ml/libc-alpha/2015-07/msg00193.html
[2] http://austingroupbugs.net/view.php?id=1216
[3] https://sourceware.org/ml/libc-alpha/2019-05/msg00031.html
[4] https://sourceware.org/ml/libc-alpha/2019-02/msg00637.html
[5] https://sourceware.org/ml/libc-alpha/2019-05/msg00131.html
[6] https://sourceware.org/ml/libc-alpha/2019-06/msg00010.html
[7] https://sourceware.org/ml/libc-alpha/2019-05/msg00600.html

Mike Crowe (12):
  support: Add xclock_now helper function.
  support: Invent verbose_printf macro
  nptl: Convert various tests to use libsupport
  nptl: Add clockid parameter to futex timed wait calls
  nptl: Add POSIX-proposed sem_clockwait
  nptl: Add POSIX-proposed pthread_cond_clockwait
  nptl: pthread_rwlock: Move timeout validation into _full functions
  nptl: Add POSIX-proposed pthread_rwlock_clockrdlock & pthread_rwlock_clockwrlock
  nptl: Rename lll_timedlock to lll_clocklock and add clockid parameter
  nptl: Add POSIX-proposed pthread_mutex_clocklock
  Update NEWS for new _clockwait and _clocklock functions
  nptl: Remove futex_supports_exact_relative_timeouts

 ChangeLog                                                       | 498 +++++++-
 NEWS                                                            |   9 +-
 manual/threads.texi                                             |  58 +-
 nptl/DESIGN-systemtap-probes.txt                                |   3 +-
 nptl/Makefile                                                   |  10 +-
 nptl/Versions                                                   |   6 +-
 nptl/eintr.c                                                    |  12 +-
 nptl/forward.c                                                  |   5 +-
 nptl/lll_timedlock_wait.c                                       |  15 +-
 nptl/nptl-init.c                                                |   1 +-
 nptl/pthreadP.h                                                 |   5 +-
 nptl/pthread_cond_wait.c                                        |  63 +-
 nptl/pthread_condattr_setclock.c                                |   5 +-
 nptl/pthread_mutex_timedlock.c                                  |  50 +-
 nptl/pthread_rwlock_clockrdlock.c                               |  29 +-
 nptl/pthread_rwlock_clockwrlock.c                               |  29 +-
 nptl/pthread_rwlock_common.c                                    |  32 +-
 nptl/pthread_rwlock_rdlock.c                                    |   2 +-
 nptl/pthread_rwlock_timedrdlock.c                               |  12 +-
 nptl/pthread_rwlock_timedwrlock.c                               |  12 +-
 nptl/pthread_rwlock_wrlock.c                                    |   2 +-
 nptl/sem_clockwait.c                                            |  45 +-
 nptl/sem_timedwait.c                                            |   3 +-
 nptl/sem_wait.c                                                 |   3 +-
 nptl/sem_waitcommon.c                                           |  15 +-
 nptl/tst-abstime.c                                              |  10 +-
 nptl/tst-cond11.c                                               |  38 +-
 nptl/tst-cond26.c                                               |  77 +-
 nptl/tst-cond27.c                                               |  66 +-
 nptl/tst-eintr1.c                                               |  52 +-
 nptl/tst-eintr2.c                                               |  60 +-
 nptl/tst-eintr3.c                                               |  23 +-
 nptl/tst-eintr4.c                                               |  15 +-
 nptl/tst-eintr5.c                                               |  40 +-
 nptl/tst-mutex-errorcheck.c                                     |  29 +-
 nptl/tst-mutex11.c                                              |  69 +-
 nptl/tst-mutex5.c                                               | 184 +---
 nptl/tst-mutex9.c                                               | 151 +--
 nptl/tst-rwlock14.c                                             |  12 +-
 nptl/tst-rwlock6.c                                              |  95 +-
 nptl/tst-rwlock7.c                                              |  83 +-
 nptl/tst-rwlock9.c                                              | 102 +-
 nptl/tst-sem13.c                                                |  39 +-
 nptl/tst-sem17.c                                                |  76 +-
 nptl/tst-sem5.c                                                 |  23 +-
 support/test-driver.h                                           |   8 +-
 support/xtime.h                                                 |  10 +-
 sysdeps/nptl/futex-internal.h                                   |  18 +-
 sysdeps/nptl/lowlevellock-futex.h                               |  13 +-
 sysdeps/nptl/lowlevellock.h                                     |  16 +-
 sysdeps/nptl/pthread-functions.h                                |   4 +-
 sysdeps/nptl/pthread.h                                          |  36 +-
 sysdeps/pthread/semaphore.h                                     |   7 +-
 sysdeps/sparc/sparc32/lll_timedlock_wait.c                      |   2 +-
 sysdeps/sparc/sparc32/lowlevellock.c                            |  15 +-
 sysdeps/unix/sysv/linux/aarch64/libpthread.abilist              |   5 +-
 sysdeps/unix/sysv/linux/alpha/libpthread.abilist                |   5 +-
 sysdeps/unix/sysv/linux/arm/libpthread.abilist                  |   5 +-
 sysdeps/unix/sysv/linux/csky/libpthread.abilist                 |   5 +-
 sysdeps/unix/sysv/linux/futex-internal.h                        |  34 +-
 sysdeps/unix/sysv/linux/hppa/libpthread.abilist                 |   5 +-
 sysdeps/unix/sysv/linux/i386/libpthread.abilist                 |   5 +-
 sysdeps/unix/sysv/linux/ia64/libpthread.abilist                 |   5 +-
 sysdeps/unix/sysv/linux/lowlevellock-futex.h                    |  33 +-
 sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist        |   5 +-
 sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist          |   5 +-
 sysdeps/unix/sysv/linux/microblaze/libpthread.abilist           |   5 +-
 sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist          |   5 +-
 sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist          |   5 +-
 sysdeps/unix/sysv/linux/nios2/libpthread.abilist                |   5 +-
 sysdeps/unix/sysv/linux/powerpc/elision-timed.c                 |   6 +-
 sysdeps/unix/sysv/linux/powerpc/lowlevellock.h                  |   9 +-
 sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist    |   5 +-
 sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist |   5 +-
 sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist |   5 +-
 sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist           |   5 +-
 sysdeps/unix/sysv/linux/s390/elision-timed.c                    |   6 +-
 sysdeps/unix/sysv/linux/s390/lowlevellock.h                     |   9 +-
 sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist         |   5 +-
 sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist         |   5 +-
 sysdeps/unix/sysv/linux/sh/libpthread.abilist                   |   5 +-
 sysdeps/unix/sysv/linux/sparc/lowlevellock.h                    |  11 +-
 sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist        |   5 +-
 sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist        |   5 +-
 sysdeps/unix/sysv/linux/x86/elision-timed.c                     |   6 +-
 sysdeps/unix/sysv/linux/x86/lowlevellock.h                      |  11 +-
 sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist            |   5 +-
 sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist           |   5 +-
 88 files changed, 1867 insertions(+), 675 deletions(-)
 create mode 100644 nptl/pthread_rwlock_clockrdlock.c
 create mode 100644 nptl/pthread_rwlock_clockwrlock.c
 create mode 100644 nptl/sem_clockwait.c
 create mode 100644 nptl/tst-cond26.c
 create mode 100644 nptl/tst-cond27.c
 create mode 100644 nptl/tst-mutex11.c
 create mode 100644 nptl/tst-sem17.c

base-commit: 02d8b5ab1c89bcef2627d2b621bfb35b573852c2
-- 
git-series 0.9.1

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH v4 01/12] support: Add xclock_now helper function.
  2019-06-18 16:33 [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions Mike Crowe
@ 2019-06-18 16:33 ` Mike Crowe
  2019-06-19 20:01   ` Adhemerval Zanella
  2019-06-18 16:33 ` [PATCH v4 02/12] support: Invent verbose_printf macro Mike Crowe
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 32+ messages in thread
From: Mike Crowe @ 2019-06-18 16:33 UTC (permalink / raw
  To: libc-alpha; +Cc: Mike Crowe

It's easier to read and write tests with:

 const struct timespec ts = xclock_now(CLOCK_REALTIME);

than

 struct timespec ts;
 xclock_gettime(CLOCK_REALTIME, &ts);

* support/xtime.h: Add xclock_now() helper function.
---
 ChangeLog       |  4 ++++
 support/xtime.h | 10 ++++++++++
 2 files changed, 14 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 7401f9f..17fd6ac 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2019-05-30  Mike Crowe  <mac@mcrowe.com>
+
+	* support/xtime.h: Add xclock_now() helper function.
+
 2019-06-17  Rafal Luzynski  <digitalfreak@lingonborough.com>
 
 	[BZ #24614]
diff --git a/support/xtime.h b/support/xtime.h
index 68af1a5..6e19ce1 100644
--- a/support/xtime.h
+++ b/support/xtime.h
@@ -28,6 +28,16 @@ __BEGIN_DECLS
 
 void xclock_gettime (clockid_t clock, struct timespec *ts);
 
+/* This helper can often simplify tests by avoiding an explicit
+   variable declaration or allowing that declaration to be const. */
+
+static inline struct timespec xclock_now (clockid_t clock)
+{
+  struct timespec ts;
+  xclock_gettime (clock, &ts);
+  return ts;
+}
+
 __END_DECLS
 
 #endif /* SUPPORT_TIME_H */
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v4 02/12] support: Invent verbose_printf macro
  2019-06-18 16:33 [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions Mike Crowe
  2019-06-18 16:33 ` [PATCH v4 01/12] support: Add xclock_now helper function Mike Crowe
@ 2019-06-18 16:33 ` Mike Crowe
  2019-06-19 20:15   ` Adhemerval Zanella
  2019-06-18 16:33 ` [PATCH v4 03/12] nptl: Convert various tests to use libsupport Mike Crowe
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 32+ messages in thread
From: Mike Crowe @ 2019-06-18 16:33 UTC (permalink / raw
  To: libc-alpha; +Cc: Mike Crowe

Make it easier for tests to emit progress messages only when --verbose is
specified.

* support/test-driver.h: Add verbose_printf macro.
---
 ChangeLog             | 4 ++++
 support/test-driver.h | 8 ++++++++
 2 files changed, 12 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 17fd6ac..6943d5e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2019-06-18  Mike Crowe <mac@mcrowe.com>
+
+	* support/test-driver.h: Add verbose_printf macro.
+
 2019-05-30  Mike Crowe  <mac@mcrowe.com>
 
 	* support/xtime.h: Add xclock_now() helper function.
diff --git a/support/test-driver.h b/support/test-driver.h
index a9710af..55f355f 100644
--- a/support/test-driver.h
+++ b/support/test-driver.h
@@ -69,6 +69,14 @@ extern const char *test_dir;
    tests.  */
 extern unsigned int test_verbose;
 
+/* Output that is only emitted if at least one --verbose argument was
+   specified. */
+#define verbose_printf(...)                      \
+  do {                                           \
+    if (test_verbose > 0)                        \
+      printf (__VA_ARGS__);                      \
+  } while (0);
+
 int support_test_main (int argc, char **argv, const struct test_config *);
 
 __END_DECLS
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v4 03/12] nptl: Convert various tests to use libsupport
  2019-06-18 16:33 [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions Mike Crowe
  2019-06-18 16:33 ` [PATCH v4 01/12] support: Add xclock_now helper function Mike Crowe
  2019-06-18 16:33 ` [PATCH v4 02/12] support: Invent verbose_printf macro Mike Crowe
@ 2019-06-18 16:33 ` Mike Crowe
  2019-06-19 20:33   ` Adhemerval Zanella
  2019-06-18 16:33 ` [PATCH v4 04/12] nptl: Add clockid parameter to futex timed wait calls Mike Crowe
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 32+ messages in thread
From: Mike Crowe @ 2019-06-18 16:33 UTC (permalink / raw
  To: libc-alpha; +Cc: Mike Crowe

* nptl/eintr.c: Use libsupport.
* nptl/tst-eintr1.c: Use libsupport.
* nptl/tst-eintr2.c: Use libsupport.
* nptl/tst-eintr3.c: Use libsupport.
* nptl/tst-eintr4.c: Use libsupport.
* nptl/tst-eintr5.c: Use libsupport.
* nptl/tst-mutex-errorcheck.c: Use libsupport.
* nptl/tst-mutex5.c: Use libsupport.
---
 ChangeLog                   |  12 +++-
 nptl/eintr.c                |  12 +--
 nptl/tst-eintr1.c           |  52 +-----------
 nptl/tst-eintr2.c           |  60 +++-----------
 nptl/tst-eintr3.c           |  23 +----
 nptl/tst-eintr4.c           |  15 +--
 nptl/tst-eintr5.c           |  40 ++-------
 nptl/tst-mutex-errorcheck.c |  29 ++-----
 nptl/tst-mutex5.c           | 164 ++++++-------------------------------
 nptl/tst-mutex9.c           | 131 ++++++------------------------
 10 files changed, 129 insertions(+), 409 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 6943d5e..e6b36b5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2019-05-30  Mike Crowe  <mac@mcrowe.com>
+
+	* nptl/eintr.c: Use libsupport.
+	* nptl/tst-eintr1.c: Use libsupport.
+	* nptl/tst-eintr2.c: Use libsupport.
+	* nptl/tst-eintr3.c: Use libsupport.
+	* nptl/tst-eintr4.c: Use libsupport.
+	* nptl/tst-eintr5.c: Use libsupport.
+	* nptl/tst-mutex-errorcheck.c: Use libsupport.
+	* nptl/tst-mutex5.c: Use libsupport.
+	* nptl/tst-mutex9.c: Use libsupport.
+
 2019-06-18  Mike Crowe <mac@mcrowe.com>
 
 	* support/test-driver.h: Add verbose_printf macro.
diff --git a/nptl/eintr.c b/nptl/eintr.c
index 4fc4d1c..6e644d2 100644
--- a/nptl/eintr.c
+++ b/nptl/eintr.c
@@ -19,6 +19,9 @@
 #include <pthread.h>
 #include <signal.h>
 #include <unistd.h>
+#include <support/xthread.h>
+#include <support/xsignal.h>
+#include <support/xthread.h>
 
 
 static int the_sig;
@@ -46,7 +49,7 @@ eintr_source (void *arg)
       sigset_t ss;
       sigemptyset (&ss);
       sigaddset (&ss, the_sig);
-      pthread_sigmask (SIG_BLOCK, &ss, NULL);
+      xpthread_sigmask (SIG_BLOCK, &ss, NULL);
     }
 
   while (1)
@@ -79,10 +82,5 @@ setup_eintr (int sig, pthread_t *thp)
   the_sig = sig;
 
   /* Create the thread which will fire off the signals.  */
-  pthread_t th;
-  if (pthread_create (&th, NULL, eintr_source, thp) != 0)
-    {
-      puts ("setup_eintr: pthread_create failed");
-      exit (1);
-    }
+  xpthread_create (NULL, eintr_source, thp);
 }
diff --git a/nptl/tst-eintr1.c b/nptl/tst-eintr1.c
index 8134f0a..b60b796 100644
--- a/nptl/tst-eintr1.c
+++ b/nptl/tst-eintr1.c
@@ -22,11 +22,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-
-static int do_test (void);
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/check.h>
+#include <support/xthread.h>
 
 #include "eintr.c"
 
@@ -43,37 +40,8 @@ tf1 (void *arg)
 {
   while (1)
     {
-      pthread_t th;
-
-      int e = pthread_create (&th, NULL, tf2, NULL);
-      if (e != 0)
-	{
-	  if (e == EINTR)
-	    {
-	      puts ("pthread_create returned EINTR");
-	      exit (1);
-	    }
-
-	  char buf[100];
-	  printf ("tf1: pthread_create failed: %s\n",
-		  strerror_r (e, buf, sizeof (buf)));
-	  exit (1);
-	}
-
-      e = pthread_join (th, NULL);
-      if (e != 0)
-	{
-	  if (e == EINTR)
-	    {
-	      puts ("pthread_join returned EINTR");
-	      exit (1);
-	    }
-
-	  char buf[100];
-	  printf ("tf1: pthread_join failed: %s\n",
-		  strerror_r (e, buf, sizeof (buf)));
-	  exit (1);
-	}
+      pthread_t th = xpthread_create (NULL, tf2, NULL);
+      xpthread_join (th);
     }
 }
 
@@ -86,15 +54,7 @@ do_test (void)
   int i;
   for (i = 0; i < 10; ++i)
     {
-      pthread_t th;
-      int e = pthread_create (&th, NULL, tf1, NULL);
-      if (e != 0)
-	{
-	  char buf[100];
-	  printf ("main: pthread_create failed: %s\n",
-		  strerror_r (e, buf, sizeof (buf)));
-	  exit (1);
-	}
+      pthread_t th = xpthread_create (NULL, tf1, NULL);
     }
 
   delayed_exit (3);
@@ -102,3 +62,5 @@ do_test (void)
   (void) tf1 (NULL);
   return 1;
 }
+
+#include <support/test-driver.c>
diff --git a/nptl/tst-eintr2.c b/nptl/tst-eintr2.c
index 12e2715..c78c19a 100644
--- a/nptl/tst-eintr2.c
+++ b/nptl/tst-eintr2.c
@@ -23,11 +23,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/time.h>
-
-static int do_test (void);
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/check.h>
+#include <support/timespec.h>
+#include <support/xtime.h>
 
 #include "eintr.c"
 
@@ -39,12 +37,8 @@ static pthread_mutex_t m2 = PTHREAD_MUTEX_INITIALIZER;
 static void *
 tf1 (void *arg)
 {
-  struct timespec ts;
-  struct timeval tv;
-
-  gettimeofday (&tv, NULL);
-  TIMEVAL_TO_TIMESPEC (&tv, &ts);
-  ts.tv_sec += 10000;
+  struct timespec ts = timespec_add (xclock_now (CLOCK_REALTIME),
+                                     make_timespec (10000, 0));
 
   /* This call must never return.  */
   int e = pthread_mutex_timedlock (&m1, &ts);
@@ -61,58 +55,34 @@ tf2 (void *arg)
 {
   while (1)
     {
-      int e = pthread_mutex_lock (&m2);
-      if (e != 0)
-	{
-	  puts ("tf2: mutex_lock failed");
-	  exit (1);
-	}
-      e = pthread_mutex_unlock (&m2);
-      if (e != 0)
-	{
-	  puts ("tf2: mutex_unlock failed");
-	  exit (1);
-	}
+      TEST_COMPARE (pthread_mutex_lock (&m2), 0);
+      TEST_COMPARE (pthread_mutex_unlock (&m2), 0);
+
       struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 };
       nanosleep (&ts, NULL);
     }
+  return NULL;
 }
 
 
 static int
 do_test (void)
 {
-  if (pthread_mutex_lock (&m1) != 0)
-    {
-      puts ("mutex_lock failed");
-      exit (1);
-    }
+  TEST_COMPARE (pthread_mutex_lock (&m1), 0);
 
   setup_eintr (SIGUSR1, NULL);
 
-  pthread_t th;
   char buf[100];
-  int e = pthread_create (&th, NULL, tf1, NULL);
-  if (e != 0)
-    {
-      printf ("main: 1st pthread_create failed: %s\n",
-	      strerror_r (e, buf, sizeof (buf)));
-      exit (1);
-    }
-
-  e = pthread_create (&th, NULL, tf2, NULL);
-  if (e != 0)
-    {
-      printf ("main: 2nd pthread_create failed: %s\n",
-	      strerror_r (e, buf, sizeof (buf)));
-      exit (1);
-    }
+  xpthread_create (NULL, tf1, NULL);
+  xpthread_create (NULL, tf2, NULL);
 
   delayed_exit (3);
   /* This call must never return.  */
-  e = pthread_mutex_lock (&m1);
+  int e = pthread_mutex_lock (&m1);
   printf ("main: mutex_lock returned: %s\n",
 	  strerror_r (e, buf, sizeof (buf)));
 
   return 1;
 }
+
+#include <support/test-driver.c>
diff --git a/nptl/tst-eintr3.c b/nptl/tst-eintr3.c
index d6c4e2b..0562eba 100644
--- a/nptl/tst-eintr3.c
+++ b/nptl/tst-eintr3.c
@@ -22,11 +22,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-
-static int do_test (void);
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/check.h>
+#include <support/xthread.h>
 
 #include "eintr.c"
 
@@ -35,9 +32,9 @@ static void *
 tf (void *arg)
 {
   pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
-  pthread_mutex_lock (&m);
+  xpthread_mutex_lock (&m);
   /* This call must not return.  */
-  pthread_mutex_lock (&m);
+  xpthread_mutex_lock (&m);
 
   puts ("tf: mutex_lock returned");
   exit (1);
@@ -51,15 +48,7 @@ do_test (void)
 
   setup_eintr (SIGUSR1, &self);
 
-  pthread_t th;
-  char buf[100];
-  int e = pthread_create (&th, NULL, tf, NULL);
-  if (e != 0)
-    {
-      printf ("main: pthread_create failed: %s\n",
-	      strerror_r (e, buf, sizeof (buf)));
-      exit (1);
-    }
+  pthread_t th = xpthread_create (NULL, tf, NULL);
 
   delayed_exit (1);
   /* This call must never return.  */
@@ -67,3 +56,5 @@ do_test (void)
   puts ("error: pthread_join returned");
   return 1;
 }
+
+#include <support/test-driver.c>
diff --git a/nptl/tst-eintr4.c b/nptl/tst-eintr4.c
index 2d9b299..1f4b711 100644
--- a/nptl/tst-eintr4.c
+++ b/nptl/tst-eintr4.c
@@ -22,11 +22,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-
-static int do_test (void);
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/check.h>
+#include <support/xthread.h>
 
 #include "eintr.c"
 
@@ -39,11 +36,7 @@ do_test (void)
   setup_eintr (SIGUSR1, &self);
 
   pthread_barrier_t b;
-  if (pthread_barrier_init (&b, NULL, 2) != 0)
-    {
-      puts ("barrier_init failed");
-      exit (1);
-    }
+  xpthread_barrier_init (&b, NULL, 2);
 
   delayed_exit (1);
   /* This call must never return.  */
@@ -51,3 +44,5 @@ do_test (void)
   puts ("error: pthread_barrier_wait returned");
   return 1;
 }
+
+#include <support/test-driver.c>
diff --git a/nptl/tst-eintr5.c b/nptl/tst-eintr5.c
index 6eee2a1..da049c4 100644
--- a/nptl/tst-eintr5.c
+++ b/nptl/tst-eintr5.c
@@ -23,11 +23,10 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/time.h>
-
-static int do_test (void);
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/check.h>
+#include <support/timespec.h>
+#include <support/xthread.h>
+#include <support/xtime.h>
 
 #include "eintr.c"
 
@@ -39,20 +38,12 @@ static pthread_cond_t c = PTHREAD_COND_INITIALIZER;
 static void *
 tf (void *arg)
 {
-  struct timespec ts;
-  struct timeval tv;
-
-  gettimeofday (&tv, NULL);
-  TIMEVAL_TO_TIMESPEC (&tv, &ts);
-  ts.tv_sec += 10000;
+  struct timespec ts = timespec_add (xclock_now (CLOCK_REALTIME),
+                                     make_timespec (10000, 0));
 
   /* This call must never return.  */
-  int e = pthread_cond_timedwait (&c, &m, &ts);
-  char buf[100];
-  printf ("tf: cond_timedwait returned: %s\n",
-	  strerror_r (e, buf, sizeof (buf)));
-
-  exit (1);
+  TEST_COMPARE (pthread_cond_timedwait (&c, &m, &ts), 0);
+  FAIL_EXIT1 ("pthread_cond_timedwait returned unexpectedly\n");
 }
 
 
@@ -61,19 +52,12 @@ do_test (void)
 {
   setup_eintr (SIGUSR1, NULL);
 
-  pthread_t th;
-  char buf[100];
-  int e = pthread_create (&th, NULL, tf, NULL);
-  if (e != 0)
-    {
-      printf ("main: pthread_create failed: %s\n",
-	      strerror_r (e, buf, sizeof (buf)));
-      exit (1);
-    }
+  xpthread_create (NULL, tf, NULL);
 
   delayed_exit (3);
   /* This call must never return.  */
   xpthread_cond_wait (&c, &m);
-  puts ("error: pthread_cond_wait returned");
-  return 1;
+  FAIL_RET ("error: pthread_cond_wait returned");
 }
+
+#include <support/test-driver.c>
diff --git a/nptl/tst-mutex-errorcheck.c b/nptl/tst-mutex-errorcheck.c
index 30ff7ea..afc27e7 100644
--- a/nptl/tst-mutex-errorcheck.c
+++ b/nptl/tst-mutex-errorcheck.c
@@ -20,6 +20,7 @@
 #include <errno.h>
 #include <time.h>
 #include <pthread.h>
+#include <support/check.h>
 
 static int
 do_test (void)
@@ -29,33 +30,23 @@ do_test (void)
   pthread_mutexattr_t mutexattr;
   int ret = 0;
 
-  if (pthread_mutexattr_init (&mutexattr) != 0)
-    return 1;
-  if (pthread_mutexattr_settype (&mutexattr, PTHREAD_MUTEX_ERRORCHECK) != 0)
-    return 1;
+  TEST_COMPARE (pthread_mutexattr_init (&mutexattr), 0);
+  TEST_COMPARE (pthread_mutexattr_settype (&mutexattr,
+                                           PTHREAD_MUTEX_ERRORCHECK), 0);
 
-  if (pthread_mutex_init (&mutex, &mutexattr) != 0)
-    return 1;
-  if (pthread_mutexattr_destroy (&mutexattr) != 0)
-    return 1;
+  TEST_COMPARE (pthread_mutex_init (&mutex, &mutexattr), 0);
+  TEST_COMPARE (pthread_mutexattr_destroy (&mutexattr), 0);
 
   /* The call to pthread_mutex_timedlock erroneously enabled lock elision
      on the mutex, which then triggered an assertion failure in
      pthread_mutex_unlock.  It would also defeat the error checking nature
      of the mutex.  */
-  if (pthread_mutex_timedlock (&mutex, &tms) != 0)
-    return 1;
-  if (pthread_mutex_timedlock (&mutex, &tms) != EDEADLK)
-    {
-      printf ("Failed error checking on locked mutex\n");
-      ret = 1;
-    }
+  TEST_COMPARE (pthread_mutex_timedlock (&mutex, &tms), 0);
+  TEST_COMPARE (pthread_mutex_timedlock (&mutex, &tms), EDEADLK);
 
-  if (pthread_mutex_unlock (&mutex) != 0)
-    ret = 1;
+  TEST_COMPARE (pthread_mutex_unlock (&mutex), 0);
 
   return ret;
 }
 
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/nptl/tst-mutex5.c b/nptl/tst-mutex5.c
index 4e1d93b..fb27152 100644
--- a/nptl/tst-mutex5.c
+++ b/nptl/tst-mutex5.c
@@ -24,6 +24,8 @@
 #include <sys/time.h>
 #include <stdint.h>
 #include <config.h>
+#include <support/check.h>
+#include <support/timespec.h>
 
 
 #ifndef TYPE
@@ -35,168 +37,60 @@ static int
 do_test (void)
 {
   pthread_mutex_t m;
-  struct timespec ts;
-  struct timeval tv;
-  struct timeval tv2;
-  int err;
   pthread_mutexattr_t a;
 
-  if (pthread_mutexattr_init (&a) != 0)
-    {
-      puts ("mutexattr_init failed");
-      return 1;
-    }
-
-  if (pthread_mutexattr_settype (&a, TYPE) != 0)
-    {
-      puts ("mutexattr_settype failed");
-      return 1;
-    }
+  TEST_COMPARE (pthread_mutexattr_init (&a), 0);
+  TEST_COMPARE (pthread_mutexattr_settype (&a, TYPE), 0);
 
 #ifdef ENABLE_PI
-  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
-    {
-      puts ("pthread_mutexattr_setprotocol failed");
-      return 1;
-    }
+  TEST_COMPARE (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT), 0);
 #endif
 
-  err = pthread_mutex_init (&m, &a);
+  int err = pthread_mutex_init (&m, &a);
   if (err != 0)
     {
 #ifdef ENABLE_PI
       if (err == ENOTSUP)
-	{
-	  puts ("PI mutexes unsupported");
-	  return 0;
-	}
+        FAIL_UNSUPPORTED ("PI mutexes unsupported");
 #endif
-      puts ("mutex_init failed");
-      return 1;
-    }
-
-  if (pthread_mutexattr_destroy (&a) != 0)
-    {
-      puts ("mutexattr_destroy failed");
-      return 1;
-    }
-
-  if (pthread_mutex_lock (&m) != 0)
-    {
-      puts ("mutex_lock failed");
-      return 1;
+      FAIL_EXIT1 ("mutex_init failed");
     }
 
+  TEST_COMPARE (pthread_mutexattr_destroy (&a), 0);
+  TEST_COMPARE (pthread_mutex_lock (&m), 0);
   if (pthread_mutex_trylock (&m) == 0)
-    {
-      puts ("mutex_trylock succeeded");
-      return 1;
-    }
+    FAIL_EXIT1 ("mutex_trylock succeeded");
 
-  gettimeofday (&tv, NULL);
-  TIMEVAL_TO_TIMESPEC (&tv, &ts);
-
-  ts.tv_sec += 2;	/* Wait 2 seconds.  */
-
-  err = pthread_mutex_timedlock (&m, &ts);
-  if (err == 0)
-    {
-      puts ("timedlock succeeded");
-      return 1;
-    }
-  else if (err != ETIMEDOUT)
-    {
-      printf ("timedlock error != ETIMEDOUT: %d\n", err);
-      return 1;
-    }
-  else
-    {
-      int clk_tck = sysconf (_SC_CLK_TCK);
-
-      gettimeofday (&tv2, NULL);
-
-      tv2.tv_sec -= tv.tv_sec;
-      tv2.tv_usec -= tv.tv_usec;
-      if (tv2.tv_usec < 0)
-	{
-	  tv2.tv_usec += 1000000;
-	  tv2.tv_sec -= 1;
-	}
-
-      /* Be a bit tolerant, add one CLK_TCK.  */
-      tv2.tv_usec += 1000000 / clk_tck;
-      if (tv2.tv_usec >= 1000000)
-	{
-	  tv2.tv_usec -= 1000000;
-	  ++tv2.tv_sec;
-	}
-
-      if (tv2.tv_sec < 2)
-	{
-	  printf ("premature timeout: %jd.%06jd difference\n",
-		  (intmax_t) tv2.tv_sec, (intmax_t) tv2.tv_usec);
-	  return 1;
-	}
-    }
+  /* Wait 2 seconds.  */
+  struct timespec ts_timeout = timespec_add (xclock_now (CLOCK_REALTIME),
+                                             make_timespec (2, 0));
 
-  (void) gettimeofday (&tv, NULL);
-  TIMEVAL_TO_TIMESPEC (&tv, &ts);
+  TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), ETIMEDOUT);
+  TEST_TIMESPEC_BEFORE_NOW (ts_timeout, CLOCK_REALTIME);
 
-  ts.tv_sec += 2;	/* Wait 2 seconds.  */
   /* The following makes the ts value invalid.  */
-  ts.tv_nsec += 1000000000;
+  ts_timeout.tv_nsec += 1000000000;
 
-  err = pthread_mutex_timedlock (&m, &ts);
-  if (err == 0)
-    {
-      puts ("2nd timedlock succeeded");
-      return 1;
-    }
-  else if (err != EINVAL)
-    {
-      printf ("2nd timedlock error != EINVAL: %d\n", err);
-      return 1;
-    }
+  TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), EINVAL);
+  TEST_COMPARE (pthread_mutex_unlock (&m), 0);
 
-  if (pthread_mutex_unlock (&m) != 0)
-    {
-      puts ("mutex_unlock failed");
-      return 1;
-    }
+  const struct timespec ts_start = xclock_now (CLOCK_REALTIME);
 
-  (void) gettimeofday (&tv, NULL);
-  TIMEVAL_TO_TIMESPEC (&tv, &ts);
+  /* Wait 2 seconds.  */
+  ts_timeout = timespec_add (ts_start, make_timespec (2, 0));
 
-  ts.tv_sec += 2;	/* Wait 2 seconds.  */
-  if (pthread_mutex_timedlock (&m, &ts) != 0)
-    {
-      puts ("3rd timedlock failed");
-    }
+  TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), 0);
 
-  (void) gettimeofday (&tv2, NULL);
+  const struct timespec ts_end = xclock_now (CLOCK_REALTIME);
 
   /* Check that timedlock didn't delay.  We use a limit of 0.1 secs.  */
-  timersub (&tv2, &tv, &tv2);
-  if (tv2.tv_sec > 0 || tv2.tv_usec > 100000)
-    {
-      puts ("3rd timedlock didn't return right away");
-      return 1;
-    }
+  TEST_TIMESPEC_BEFORE (ts_end,
+                        timespec_add (ts_start, make_timespec (0, 100000000)));
 
-  if (pthread_mutex_unlock (&m) != 0)
-    {
-      puts ("final mutex_unlock failed");
-      return 1;
-    }
-
-  if (pthread_mutex_destroy (&m) != 0)
-    {
-      puts ("mutex_destroy failed");
-      return 1;
-    }
+  TEST_COMPARE (pthread_mutex_unlock (&m), 0);
+  TEST_COMPARE (pthread_mutex_destroy (&m), 0);
 
   return 0;
 }
 
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
diff --git a/nptl/tst-mutex9.c b/nptl/tst-mutex9.c
index 917276e..e9fd8e2 100644
--- a/nptl/tst-mutex9.c
+++ b/nptl/tst-mutex9.c
@@ -26,6 +26,9 @@
 #include <sys/mman.h>
 #include <sys/time.h>
 #include <sys/wait.h>
+#include <support/check.h>
+#include <support/timespec.h>
+#include <support/xunistd.h>
 
 
 static int
@@ -42,10 +45,7 @@ do_test (void)
 
   fd = mkstemp (tmpfname);
   if (fd == -1)
-    {
-      printf ("cannot open temporary file: %m\n");
-      return 1;
-    }
+      FAIL_EXIT1 ("cannot open temporary file: %m\n");
 
   /* Make sure it is always removed.  */
   unlink (tmpfname);
@@ -54,46 +54,21 @@ do_test (void)
   memset (data, '\0', ps);
 
   /* Write the data to the file.  */
-  if (write (fd, data, ps) != (ssize_t) ps)
-    {
-      puts ("short write");
-      return 1;
-    }
+  xwrite (fd, data, ps);
 
-  mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
-  if (mem == MAP_FAILED)
-    {
-      printf ("mmap failed: %m\n");
-      return 1;
-    }
+  mem = xmmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd);
 
   m = (pthread_mutex_t *) (((uintptr_t) mem + __alignof (pthread_mutex_t))
 			   & ~(__alignof (pthread_mutex_t) - 1));
 
-  if (pthread_mutexattr_init (&a) != 0)
-    {
-      puts ("mutexattr_init failed");
-      return 1;
-    }
+  TEST_COMPARE (pthread_mutexattr_init (&a), 0);
 
-  if (pthread_mutexattr_setpshared (&a, PTHREAD_PROCESS_SHARED) != 0)
-    {
-      puts ("mutexattr_setpshared failed");
-      return 1;
-    }
+  TEST_COMPARE (pthread_mutexattr_setpshared (&a, PTHREAD_PROCESS_SHARED), 0);
 
-  if (pthread_mutexattr_settype (&a, PTHREAD_MUTEX_RECURSIVE) != 0)
-    {
-      puts ("mutexattr_settype failed");
-      return 1;
-    }
+  TEST_COMPARE (pthread_mutexattr_settype (&a, PTHREAD_MUTEX_RECURSIVE), 0);
 
 #ifdef ENABLE_PI
-  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
-    {
-      puts ("pthread_mutexattr_setprotocol failed");
-      return 1;
-    }
+  TEST_COMPARE (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT), 0);
 #endif
 
   int e;
@@ -101,70 +76,29 @@ do_test (void)
     {
 #ifdef ENABLE_PI
       if (e == ENOTSUP)
-	{
-	  puts ("PI mutexes unsupported");
-	  return 0;
-	}
+        FAIL_UNSUPPORTED ("PI mutexes unsupported");
 #endif
-      puts ("mutex_init failed");
-      return 1;
+      FAIL_EXIT1 ("mutex_init failed");
     }
 
-  if (pthread_mutex_lock (m) != 0)
-    {
-      puts ("mutex_lock failed");
-      return 1;
-    }
+  TEST_COMPARE (pthread_mutex_lock (m), 0);
 
-  if (pthread_mutexattr_destroy (&a) != 0)
-    {
-      puts ("mutexattr_destroy failed");
-      return 1;
-    }
+  TEST_COMPARE (pthread_mutexattr_destroy (&a), 0);
 
   puts ("going to fork now");
-  pid = fork ();
-  if (pid == -1)
-    {
-      puts ("fork failed");
-      return 1;
-    }
-  else if (pid == 0)
+  pid = xfork ();
+  if (pid == 0)
     {
       if (pthread_mutex_trylock (m) == 0)
-	{
-	  puts ("child: mutex_trylock succeeded");
-	  exit (1);
-	}
+        FAIL_EXIT1 ("child: mutex_trylock succeeded");
 
       if (pthread_mutex_unlock (m) == 0)
-	{
-	  puts ("child: mutex_unlock succeeded");
-	  exit (1);
-	}
-
-      struct timeval tv;
-      gettimeofday (&tv, NULL);
-      struct timespec ts;
-      TIMEVAL_TO_TIMESPEC (&tv, &ts);
-      ts.tv_nsec += 500000000;
-      if (ts.tv_nsec >= 1000000000)
-	{
-	  ++ts.tv_sec;
-	  ts.tv_nsec -= 1000000000;
-	}
-
-      e = pthread_mutex_timedlock (m, &ts);
-      if (e == 0)
-	{
-	  puts ("child: mutex_timedlock succeeded");
-	  exit (1);
-	}
-      if (e != ETIMEDOUT)
-	{
-	  puts ("child: mutex_timedlock didn't time out");
-	  exit (1);
-	}
+        FAIL_EXIT1 ("child: mutex_unlock succeeded");
+
+      const struct timespec ts = timespec_add (xclock_now (CLOCK_REALTIME),
+                                               make_timespec (0, 500000000));
+
+      TEST_COMPARE (pthread_mutex_timedlock (m, &ts), ETIMEDOUT);
 
       alarm (1);
 
@@ -179,23 +113,12 @@ do_test (void)
 
   int status;
   if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
-    {
-      puts ("waitpid failed");
-      return 1;
-    }
+    FAIL_EXIT1 ("waitpid failed");
   if (! WIFSIGNALED (status))
-    {
-      puts ("child not killed by signal");
-      return 1;
-    }
-  if (WTERMSIG (status) != SIGALRM)
-    {
-      puts ("child not killed by SIGALRM");
-      return 1;
-    }
+    FAIL_EXIT1 ("child not killed by signal");
+  TEST_COMPARE (WTERMSIG (status), SIGALRM);
 
   return 0;
 }
 
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v4 04/12] nptl: Add clockid parameter to futex timed wait calls
  2019-06-18 16:33 [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions Mike Crowe
                   ` (2 preceding siblings ...)
  2019-06-18 16:33 ` [PATCH v4 03/12] nptl: Convert various tests to use libsupport Mike Crowe
@ 2019-06-18 16:33 ` Mike Crowe
  2019-06-21 14:51   ` Adhemerval Zanella
  2019-06-18 16:33 ` [PATCH v4 05/12] nptl: Add POSIX-proposed sem_clockwait Mike Crowe
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 32+ messages in thread
From: Mike Crowe @ 2019-06-18 16:33 UTC (permalink / raw
  To: libc-alpha; +Cc: Mike Crowe

In preparation for adding POSIX clockwait variants of timedwait functions,
add a clockid_t parameter to futex_abstimed_wait functions and pass
CLOCK_REALTIME from all callers for the time being.

Replace lll_futex_timed_wait_bitset with lll_futex_clock_wait_bitset which
takes a clockid_t parameter rather than the magic clockbit.

* sysdeps/nptl/lowlevellock-futex.h,
  sysdeps/unix/sysv/linux/lowlevellock-futex.h: Replace
  lll_futex_timed_wait_bitset with lll_futex_clock_wait_bitset that takes a
  clockid rather than a special clockbit.

* sysdeps/nptl/lowlevellock-futex.h: Add lll_futex_supported_clockid so
  that client functions can check whether their clockid parameter is valid
  even if they don't ultimately end up calling lll_futex_clock_wait_bitset.

* sysdeps/nptl/futex-internal.h, sysdeps/unix/sysv/linux/futex-internal.h
  (futex_abstimed_wait, futex_abstimed_wait_cancelable): Add clockid_t
  parameter to indicate which clock the absolute time passed should be
  measured against. Pass that clockid onto lll_futex_clock_wait_bitset.
  Add invalid clock as reason for returning -EINVAL.

* sysdeps/nptl/futex-internal.h, sysdeps/unix/sysv/linux/futex-internal.h:
  Introduce futex_abstimed_supported_clockid so that client functions can
  check whether their clockid parameter is valid even if they don't
  ultimately end up calling futex_abstimed_wait.

* nptl/pthread_cond_wait.c (__pthread_cond_wait_common): Remove code to
  calculate relative timeout for __PTHREAD_COND_CLOCK_MONOTONIC_MASK and
  just pass CLOCK_MONOTONIC or CLOCK_REALTIME as required to
  futex_abstimed_wait_cancelable.

* nptl/pthread_rwlock_common (__pthread_rwlock_rdlock_full,
  __pthread_wrlock_full), nptl/sem_waitcommon (do_futex_wait): Pass
  additional CLOCK_REALTIME to futex_abstimed_wait_cancelable.

* nptl/pthread_mutex_timedlock.c (__pthread_mutex_timedlock): Switch to
  lll_futex_clock_wait_bitset and pass CLOCK_REALTIME
---
 ChangeLog                                    | 40 +++++++++++++++++++++-
 nptl/pthread_cond_wait.c                     | 32 +++--------------
 nptl/pthread_mutex_timedlock.c               |  4 +-
 nptl/pthread_rwlock_common.c                 |  8 ++--
 nptl/sem_waitcommon.c                        |  6 ++-
 sysdeps/nptl/futex-internal.h                |  9 ++++-
 sysdeps/nptl/lowlevellock-futex.h            | 13 ++++---
 sysdeps/unix/sysv/linux/futex-internal.h     | 26 ++++++++++----
 sysdeps/unix/sysv/linux/lowlevellock-futex.h | 33 +++++++++++++----
 9 files changed, 119 insertions(+), 52 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e6b36b5..dc84553 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,43 @@
+2019-05-27  Mike Crowe  <mac@mcrowe.com>
+
+	nptl: Add clockid parameter to futex timed wait calls
+
+	* sysdeps/nptl/lowlevellock-futex.h,
+	sysdeps/unix/sysv/linux/lowlevellock-futex.h: Replace
+	lll_futex_timed_wait_bitset with lll_futex_clock_wait_bitset that
+	takes a clockid rather than a special clockbit.
+
+	* sysdeps/nptl/lowlevellock-futex.h: Add
+	lll_futex_supported_clockid so that client functions can check
+	whether their clockid parameter is valid even if they don't
+	ultimately end up calling lll_futex_clock_wait_bitset.
+
+	* sysdeps/nptl/futex-internal.h,
+	sysdeps/unix/sysv/linux/futex-internal.h
+	(futex_abstimed_wait, futex_abstimed_wait_cancelable): Add
+	clockid_t parameter to indicate which clock the absolute time
+	passed should be measured against. Pass that clockid onto
+	lll_futex_clock_wait_bitset. Add invalid clock as reason for
+	returning -EINVAL.
+
+	* sysdeps/nptl/futex-internal.h,
+	sysdeps/unix/sysv/linux/futex-internal.h: Introduce
+	futex_abstimed_supported_clockid so that client functions can check
+	whether their clockid parameter is valid even if they don't
+	ultimately end up calling futex_abstimed_wait.
+
+	* nptl/pthread_cond_wait.c (__pthread_cond_wait_common): Remove
+	code to calculate relative timeout for
+	__PTHREAD_COND_CLOCK_MONOTONIC_MASK and just pass CLOCK_MONOTONIC
+	or CLOCK_REALTIME as required to futex_abstimed_wait_cancelable.
+
+	* nptl/pthread_rwlock_common (__pthread_rwlock_rdlock_full)
+	(__pthread_wrlock_full), nptl/sem_waitcommon (do_futex_wait): Pass
+	additional CLOCK_REALTIME to futex_abstimed_wait_cancelable.
+
+	* nptl/pthread_mutex_timedlock.c (__pthread_mutex_timedlock):
+	Switch to lll_futex_clock_wait_bitset and pass CLOCK_REALTIME
+
 2019-05-30  Mike Crowe  <mac@mcrowe.com>
 
 	* nptl/eintr.c: Use libsupport.
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
index 9a0f29e..7385562 100644
--- a/nptl/pthread_cond_wait.c
+++ b/nptl/pthread_cond_wait.c
@@ -509,35 +509,15 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
 		 values despite them being valid.  */
 	      if (__glibc_unlikely (abstime->tv_sec < 0))
 	        err = ETIMEDOUT;
-
-	      else if ((flags & __PTHREAD_COND_CLOCK_MONOTONIC_MASK) != 0)
-		{
-		  /* CLOCK_MONOTONIC is requested.  */
-		  struct timespec rt;
-		  if (__clock_gettime (CLOCK_MONOTONIC, &rt) != 0)
-		    __libc_fatal ("clock_gettime does not support "
-				  "CLOCK_MONOTONIC\n");
-		  /* Convert the absolute timeout value to a relative
-		     timeout.  */
-		  rt.tv_sec = abstime->tv_sec - rt.tv_sec;
-		  rt.tv_nsec = abstime->tv_nsec - rt.tv_nsec;
-		  if (rt.tv_nsec < 0)
-		    {
-		      rt.tv_nsec += 1000000000;
-		      --rt.tv_sec;
-		    }
-		  /* Did we already time out?  */
-		  if (__glibc_unlikely (rt.tv_sec < 0))
-		    err = ETIMEDOUT;
-		  else
-		    err = futex_reltimed_wait_cancelable
-			(cond->__data.__g_signals + g, 0, &rt, private);
-		}
 	      else
 		{
-		  /* Use CLOCK_REALTIME.  */
+		  const clockid_t clockid =
+		    ((flags & __PTHREAD_COND_CLOCK_MONOTONIC_MASK) != 0) ?
+		    CLOCK_MONOTONIC : CLOCK_REALTIME;
+
 		  err = futex_abstimed_wait_cancelable
-		      (cond->__data.__g_signals + g, 0, abstime, private);
+                    (cond->__data.__g_signals + g, 0, clockid, abstime,
+                     private);
 		}
 	    }
 
diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
index 270b072..d4d11cc 100644
--- a/nptl/pthread_mutex_timedlock.c
+++ b/nptl/pthread_mutex_timedlock.c
@@ -266,8 +266,8 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
 	  assume_other_futex_waiters |= FUTEX_WAITERS;
 
 	  /* Block using the futex.  */
-	  int err = lll_futex_timed_wait_bitset (&mutex->__data.__lock,
-	      oldval, abstime, FUTEX_CLOCK_REALTIME,
+	  int err = lll_futex_clock_wait_bitset (&mutex->__data.__lock,
+	      oldval, CLOCK_REALTIME, abstime,
 	      PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
 	  /* The futex call timed out.  */
 	  if (err == -ETIMEDOUT)
diff --git a/nptl/pthread_rwlock_common.c b/nptl/pthread_rwlock_common.c
index 2560734..89ba21a 100644
--- a/nptl/pthread_rwlock_common.c
+++ b/nptl/pthread_rwlock_common.c
@@ -319,7 +319,7 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
 		{
 		  int private = __pthread_rwlock_get_private (rwlock);
 		  int err = futex_abstimed_wait (&rwlock->__data.__readers,
-						 r, abstime, private);
+						 r, CLOCK_REALTIME, 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)
@@ -447,7 +447,7 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
 	    continue;
 	  int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
 					 1 | PTHREAD_RWLOCK_FUTEX_USED,
-					 abstime, private);
+					 CLOCK_REALTIME, abstime, private);
 	  if (err == ETIMEDOUT)
 	    {
 	      /* If we timed out, we need to unregister.  If no read phase
@@ -707,7 +707,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 	  may_share_futex_used_flag = true;
 	  int err = futex_abstimed_wait (&rwlock->__data.__writers_futex,
 					 1 | PTHREAD_RWLOCK_FUTEX_USED,
-					 abstime, private);
+					 CLOCK_REALTIME, abstime, private);
 	  if (err == ETIMEDOUT)
 	    {
 	      if (prefer_writer)
@@ -806,7 +806,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 	    continue;
 	  int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
 					 PTHREAD_RWLOCK_FUTEX_USED,
-					 abstime, private);
+					 CLOCK_REALTIME, abstime, private);
 	  if (err == ETIMEDOUT)
 	    {
 	      if (rwlock->__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP)
diff --git a/nptl/sem_waitcommon.c b/nptl/sem_waitcommon.c
index 5646bea..425d040 100644
--- a/nptl/sem_waitcommon.c
+++ b/nptl/sem_waitcommon.c
@@ -109,11 +109,13 @@ do_futex_wait (struct new_sem *sem, const struct timespec *abstime)
 
 #if __HAVE_64B_ATOMICS
   err = futex_abstimed_wait_cancelable (
-      (unsigned int *) &sem->data + SEM_VALUE_OFFSET, 0, abstime,
+      (unsigned int *) &sem->data + SEM_VALUE_OFFSET, 0,
+      CLOCK_REALTIME, abstime,
       sem->private);
 #else
   err = futex_abstimed_wait_cancelable (&sem->value, SEM_NWAITERS_MASK,
-					abstime, sem->private);
+					CLOCK_REALTIME, abstime,
+					sem->private);
 #endif
 
   return err;
diff --git a/sysdeps/nptl/futex-internal.h b/sysdeps/nptl/futex-internal.h
index 86a0818..bc29bdb 100644
--- a/sysdeps/nptl/futex-internal.h
+++ b/sysdeps/nptl/futex-internal.h
@@ -49,7 +49,7 @@
    futex word.
 
    Both absolute and relative timeouts can be used.  An absolute timeout
-   expires when the given specific point in time on the CLOCK_REALTIME clock
+   expires when the given specific point in time on the specified clock
    passes, or when it already has passed.  A relative timeout expires when
    the given duration of time on the CLOCK_MONOTONIC clock passes.  Relative
    timeouts may be imprecise (see futex_supports_exact_relative_timeouts).
@@ -159,16 +159,23 @@ futex_reltimed_wait_cancelable (unsigned int* futex_word,
 				unsigned int expected,
 			        const struct timespec* reltime, int private);
 
+/* Check whether the specified clockid is supported by
+   futex_abstimed_wait and futex_abstimed_wait_cancelable. */
+static __always_inline int
+futex_abstimed_supported_clockid (clockid_t clockid);
+
 /* Like futex_reltimed_wait, but the provided timeout (ABSTIME) is an
    absolute point in time; a call will time out after this point in time.  */
 static __always_inline int
 futex_abstimed_wait (unsigned int* futex_word, unsigned int expected,
+		     clockid_t clockid,
 		     const struct timespec* abstime, int private);
 
 /* Like futex_reltimed_wait but is a POSIX cancellation point.  */
 static __always_inline int
 futex_abstimed_wait_cancelable (unsigned int* futex_word,
 				unsigned int expected,
+				clockid_t clockid,
 			        const struct timespec* abstime, int private);
 
 /* Atomically wrt other futex operations on the same futex, this unblocks the
diff --git a/sysdeps/nptl/lowlevellock-futex.h b/sysdeps/nptl/lowlevellock-futex.h
index 63d917d..35fcfbb 100644
--- a/sysdeps/nptl/lowlevellock-futex.h
+++ b/sysdeps/nptl/lowlevellock-futex.h
@@ -43,10 +43,15 @@
 #define lll_futex_timed_wait(futexp, val, timeout, private)             \
   -ENOSYS
 
-/* If CLOCKBIT is zero, this is identical to lll_futex_timed_wait.
-   If CLOCKBIT has FUTEX_CLOCK_REALTIME set, then it's the same but
-   TIMEOUT is counted by CLOCK_REALTIME rather than CLOCK_MONOTONIC.  */
-#define lll_futex_timed_wait_bitset(futexp, val, timeout, clockbit, private) \
+/* Verify whether the supplied clockid is supported by
+   lll_futex_clock_wait_bitset */
+#define lll_futex_supported_clockid(clockid)				\
+  (0)
+
+/* Wait until a lll_futex_wake call on FUTEXP, or the absolute TIMEOUT
+   measured against CLOCKID elapses. CLOCKID may be CLOCK_REALTIME or
+   CLOCK_MONOTONIC. */
+#define lll_futex_clock_wait_bitset(futexp, val, clockid, timeout, private) \
   -ENOSYS
 
 /* Wake up up to NR waiters on FUTEXP.  */
diff --git a/sysdeps/unix/sysv/linux/futex-internal.h b/sysdeps/unix/sysv/linux/futex-internal.h
index 501f993..03312d6 100644
--- a/sysdeps/unix/sysv/linux/futex-internal.h
+++ b/sysdeps/unix/sysv/linux/futex-internal.h
@@ -162,15 +162,24 @@ futex_reltimed_wait_cancelable (unsigned int *futex_word,
 
 /* See sysdeps/nptl/futex-internal.h for details.  */
 static __always_inline int
+futex_abstimed_supported_clockid (clockid_t clockid)
+{
+  return lll_futex_supported_clockid (clockid);
+}
+
+/* See sysdeps/nptl/futex-internal.h for details.  */
+static __always_inline int
 futex_abstimed_wait (unsigned int *futex_word, unsigned int expected,
+		     clockid_t clockid,
 		     const struct timespec *abstime, int private)
 {
   /* Work around the fact that the kernel rejects negative timeout values
      despite them being valid.  */
   if (__glibc_unlikely ((abstime != NULL) && (abstime->tv_sec < 0)))
     return ETIMEDOUT;
-  int err = lll_futex_timed_wait_bitset (futex_word, expected, abstime,
-					 FUTEX_CLOCK_REALTIME, private);
+  int err = lll_futex_clock_wait_bitset (futex_word, expected,
+					 clockid, abstime,
+					 private);
   switch (err)
     {
     case 0:
@@ -180,9 +189,10 @@ futex_abstimed_wait (unsigned int *futex_word, unsigned int expected,
       return -err;
 
     case -EFAULT: /* Must have been caused by a glibc or application bug.  */
-    case -EINVAL: /* Either due to wrong alignment or due to the timeout not
-		     being normalized.  Must have been caused by a glibc or
-		     application bug.  */
+    case -EINVAL: /* Either due to wrong alignment, unsupported
+		     clockid or due to the timeout not being
+		     normalized. Must have been caused by a glibc or
+		     application bug. */
     case -ENOSYS: /* Must have been caused by a glibc bug.  */
     /* No other errors are documented at this time.  */
     default:
@@ -194,6 +204,7 @@ futex_abstimed_wait (unsigned int *futex_word, unsigned int expected,
 static __always_inline int
 futex_abstimed_wait_cancelable (unsigned int *futex_word,
 				unsigned int expected,
+				clockid_t clockid,
 			        const struct timespec *abstime, int private)
 {
   /* Work around the fact that the kernel rejects negative timeout values
@@ -202,8 +213,9 @@ futex_abstimed_wait_cancelable (unsigned int *futex_word,
     return ETIMEDOUT;
   int oldtype;
   oldtype = __pthread_enable_asynccancel ();
-  int err = lll_futex_timed_wait_bitset (futex_word, expected, abstime,
-					 FUTEX_CLOCK_REALTIME, private);
+  int err = lll_futex_clock_wait_bitset (futex_word, expected,
+					clockid, abstime,
+					private);
   __pthread_disable_asynccancel (oldtype);
   switch (err)
     {
diff --git a/sysdeps/unix/sysv/linux/lowlevellock-futex.h b/sysdeps/unix/sysv/linux/lowlevellock-futex.h
index 030a14b..ba01197 100644
--- a/sysdeps/unix/sysv/linux/lowlevellock-futex.h
+++ b/sysdeps/unix/sysv/linux/lowlevellock-futex.h
@@ -82,12 +82,33 @@
 		     __lll_private_flag (FUTEX_WAIT, private),  \
 		     val, timeout)
 
-#define lll_futex_timed_wait_bitset(futexp, val, timeout, clockbit, private) \
-  lll_futex_syscall (6, futexp,                                         \
-		     __lll_private_flag (FUTEX_WAIT_BITSET | (clockbit), \
-					 private),                      \
-		     val, timeout, NULL /* Unused.  */,                 \
-		     FUTEX_BITSET_MATCH_ANY)
+/* Verify whether the supplied clockid is supported by
+   lll_futex_clock_wait_bitset */
+#define lll_futex_supported_clockid(clockid)			\
+  ((clockid) == CLOCK_REALTIME || (clockid) == CLOCK_MONOTONIC)
+
+/* The kernel currently only supports CLOCK_MONOTONIC or
+ * CLOCK_REALTIME timeouts for FUTEX_WAIT_BITSET. We could attempt to
+ * convert others here but currently do not.
+ */
+#define lll_futex_clock_wait_bitset(futexp, val, clockid, timeout, private) \
+  ({									\
+    long int __ret;							\
+    if (lll_futex_supported_clockid (clockid))                          \
+      {                                                                 \
+        const unsigned int clockbit =                                   \
+          (clockid == CLOCK_REALTIME) ? FUTEX_CLOCK_REALTIME : 0;       \
+        const int op =                                                  \
+          __lll_private_flag (FUTEX_WAIT_BITSET | clockbit, private);   \
+                                                                        \
+        __ret = lll_futex_syscall (6, futexp, op, val,                  \
+                                   timeout, NULL /* Unused.  */,	\
+                                   FUTEX_BITSET_MATCH_ANY);		\
+      }                                                                 \
+    else                                                                \
+      __ret = -EINVAL;							\
+    __ret;								\
+  })
 
 #define lll_futex_wake(futexp, nr, private)                             \
   lll_futex_syscall (4, futexp,                                         \
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v4 05/12] nptl: Add POSIX-proposed sem_clockwait
  2019-06-18 16:33 [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions Mike Crowe
                   ` (3 preceding siblings ...)
  2019-06-18 16:33 ` [PATCH v4 04/12] nptl: Add clockid parameter to futex timed wait calls Mike Crowe
@ 2019-06-18 16:33 ` Mike Crowe
  2019-06-21 16:02   ` Adhemerval Zanella
  2019-06-18 16:33 ` [PATCH v4 06/12] nptl: Add POSIX-proposed pthread_cond_clockwait Mike Crowe
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 32+ messages in thread
From: Mike Crowe @ 2019-06-18 16:33 UTC (permalink / raw
  To: libc-alpha; +Cc: Mike Crowe

Add:

 int sem_clockwait (sem_t *sem, clockid_t clock, const struct timespec *abstime)

which behaves just like sem_timedwait, but measures abstime against the
specified clock. Currently supports CLOCK_REALTIME and CLOCK_MONOTONIC and
sets errno == EINVAL if any other clock is specified.

* nptl/sem_waitcommon.c (do_futex_wait, __new_sem_wait_slow): Add clockid
  parameters to indicate the clock which abstime should be measured
  against.

* nptl/sem_timedwait.c (sem_timedwait), nptl/sem_wait.c (__new_sem_wait):
  Pass CLOCK_REALTIME as clockid to __new_sem_wait_slow.

* nptl/sem_clockwait.c: New file to implement sem_clockwait based on
  sem_timedwait.c.

* nptl/Makefile: Add sem_clockwait.c source file. Add CFLAGS for
  sem_clockwait.c to match those used for sem_timedwait.c.

* sysdeps/pthread/semaphore.h: Add sem_clockwait.

* nptl/Versions (GLIBC_2.30): Likewise.

* sysdeps/unix/sysv/linux/aarch64/libpthread.abilist (GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/alpha/libpthread.abilist (GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/arm/libpthread.abilist (GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/csky/libpthread.abilist (GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/hppa/libpthread.abilist (GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/i386/libpthread.abilist (GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/ia64/libpthread.abilist (GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist (GLIBC_2.30):
  Likewise.
* sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist (GLIBC_2.30):
  Likewise.
* sysdeps/unix/sysv/linux/microblaze/libpthread.abilist (GLIBC_2.30):
  Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist (GLIBC_2.30):
  Likewise.
* sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist (GLIBC_2.30):
  Likewise.
* sysdeps/unix/sysv/linux/nios2/libpthread.abilist (GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
  (GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
  (GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
  (GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist	(GLIBC_2.30):
  Likewise.
* sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist (GLIBC_2.30):
  Likewise.
* sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist (GLIBC_2.30):
  Likewise.
* sysdeps/unix/sysv/linux/sh/libpthread.abilist (GLIBC_2.30): Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist (GLIBC_2.30):
  Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist (GLIBC_2.30):
  Likewise.
* sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist (GLIBC_2.30):
  Likewise.
* sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist (GLIBC_2.30):
  Likewise.

* nptl/tst-sem17.c: Add new test for passing invalid clock to
  sem_clockwait.

* nptl/tst-sem13.c, nptl/tst-sem5.c: Modify existing sem_timedwait tests to
  also test sem_clockwait.

* manual/threads.texi: Document sem_clockwait.
---
 ChangeLog                                                       | 71 +++++++-
 manual/threads.texi                                             | 10 +-
 nptl/Makefile                                                   |  5 +-
 nptl/Versions                                                   |  4 +-
 nptl/sem_clockwait.c                                            | 45 ++++-
 nptl/sem_timedwait.c                                            |  3 +-
 nptl/sem_wait.c                                                 |  3 +-
 nptl/sem_waitcommon.c                                           | 15 +-
 nptl/tst-sem13.c                                                | 39 +++-
 nptl/tst-sem17.c                                                | 76 +++++++-
 nptl/tst-sem5.c                                                 | 23 +-
 sysdeps/pthread/semaphore.h                                     |  7 +-
 sysdeps/unix/sysv/linux/aarch64/libpthread.abilist              |  1 +-
 sysdeps/unix/sysv/linux/alpha/libpthread.abilist                |  1 +-
 sysdeps/unix/sysv/linux/arm/libpthread.abilist                  |  1 +-
 sysdeps/unix/sysv/linux/csky/libpthread.abilist                 |  1 +-
 sysdeps/unix/sysv/linux/hppa/libpthread.abilist                 |  1 +-
 sysdeps/unix/sysv/linux/i386/libpthread.abilist                 |  1 +-
 sysdeps/unix/sysv/linux/ia64/libpthread.abilist                 |  1 +-
 sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist        |  1 +-
 sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist          |  1 +-
 sysdeps/unix/sysv/linux/microblaze/libpthread.abilist           |  1 +-
 sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist          |  1 +-
 sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist          |  1 +-
 sysdeps/unix/sysv/linux/nios2/libpthread.abilist                |  1 +-
 sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist    |  1 +-
 sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist |  1 +-
 sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist |  1 +-
 sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist           |  1 +-
 sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist         |  1 +-
 sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist         |  1 +-
 sysdeps/unix/sysv/linux/sh/libpthread.abilist                   |  1 +-
 sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist        |  1 +-
 sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist        |  1 +-
 sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist            |  1 +-
 sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist           |  1 +-
 36 files changed, 305 insertions(+), 20 deletions(-)
 create mode 100644 nptl/sem_clockwait.c
 create mode 100644 nptl/tst-sem17.c

diff --git a/ChangeLog b/ChangeLog
index dc84553..33502da 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,76 @@
 2019-05-27  Mike Crowe  <mac@mcrowe.com>
 
+	nptl: Add POSIX-proposed sem_clockwait which behaves just like
+	sem_timedwait, but measures abstime against the specified clock.
+
+	* nptl/sem_waitcommon.c (do_futex_wait, __new_sem_wait_slow): Add
+	clockid parameters to indicate the clock which abstime should be
+	measured against.
+
+	* nptl/sem_timedwait.c (sem_timedwait), nptl/sem_wait.c
+	(__new_sem_wait): Pass CLOCK_REALTIME as clockid to
+	__new_sem_wait_slow.
+
+	* nptl/sem_clockwait.c: New file to implement sem_clockwait based
+	on sem_timedwait.c.
+
+	* nptl/Makefile: Add sem_clockwait.c source file. Add CFLAGS for
+	sem_clockwait.c to match those used for sem_timedwait.c.
+
+	* sysdeps/pthread/semaphore.h: Add sem_clockwait.
+
+	* nptl/Versions (GLIBC_2.30): Likewise.
+
+	* sysdeps/unix/sysv/linux/aarch64/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/alpha/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/arm/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/csky/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/hppa/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/i386/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/ia64/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/nios2/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/sh/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+
+	* nptl/tst-sem17.c: Add new test for passing invalid clock to
+	sem_clockwait.
+
+	* nptl/tst-sem13.c, nptl/tst-sem5.c: Modify existing sem_timedwait
+	tests to also test sem_clockwait.
+
+	* manual/threads.texi: Document sem_clockwait.
+
+2019-05-27  Mike Crowe  <mac@mcrowe.com>
+
 	nptl: Add clockid parameter to futex timed wait calls
 
 	* sysdeps/nptl/lowlevellock-futex.h,
diff --git a/manual/threads.texi b/manual/threads.texi
index 87fda7d..674267c 100644
--- a/manual/threads.texi
+++ b/manual/threads.texi
@@ -669,6 +669,16 @@ The system does not have sufficient memory.
 @end table
 @end deftypefun
 
+@comment semaphore.h
+@comment POSIX-proposed
+@deftypefun int sem_clockwait (sem_t *@var{sem}, clockid_t @var{clockid},
+                               const struct timespec *@var{abstime})
+Behaves like @code{sem_timedwait} except the time @var{abstime} is measured
+against the clock specified by @var{clockid} rather than
+@code{CLOCK_REALTIME}. Currently, @var{clockid} must be either
+@code{CLOCK_MONOTONIC} or @code{CLOCK_REALTIME}.
+@end deftypefun
+
 @c FIXME these are undocumented:
 @c pthread_atfork
 @c pthread_attr_destroy
diff --git a/nptl/Makefile b/nptl/Makefile
index de312b3..43a99dc 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -113,7 +113,7 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \
 		      sem_init sem_destroy \
 		      sem_open sem_close sem_unlink \
 		      sem_getvalue \
-		      sem_wait sem_timedwait sem_post \
+		      sem_wait sem_timedwait sem_clockwait sem_post \
 		      cleanup cleanup_defer cleanup_compat \
 		      cleanup_defer_compat unwind \
 		      pt-longjmp pt-cleanup\
@@ -193,6 +193,7 @@ CFLAGS-pthread_once.c += $(uses-callbacks) -fexceptions \
 CFLAGS-pthread_cond_wait.c += -fexceptions -fasynchronous-unwind-tables
 CFLAGS-sem_wait.c += -fexceptions -fasynchronous-unwind-tables
 CFLAGS-sem_timedwait.c += -fexceptions -fasynchronous-unwind-tables
+CFLAGS-sem_clockwait.c = -fexceptions -fasynchronous-unwind-tables
 
 # These are the function wrappers we have to duplicate here.
 CFLAGS-fcntl.c += -fexceptions -fasynchronous-unwind-tables
@@ -262,7 +263,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
 	tst-key1 tst-key2 tst-key3 tst-key4 \
 	tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem5 tst-sem6 tst-sem7 \
 	tst-sem8 tst-sem9 tst-sem10 tst-sem14 \
-	tst-sem15 tst-sem16 \
+	tst-sem15 tst-sem16 tst-sem17 \
 	tst-barrier1 tst-barrier2 tst-barrier3 tst-barrier4 \
 	tst-align tst-align3 \
 	tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \
diff --git a/nptl/Versions b/nptl/Versions
index e7f691d..cd1806c 100644
--- a/nptl/Versions
+++ b/nptl/Versions
@@ -277,6 +277,10 @@ libpthread {
     cnd_timedwait; cnd_wait; tss_create; tss_delete; tss_get; tss_set;
   }
 
+  GLIBC_2.30 {
+    sem_clockwait;
+  }
+
   GLIBC_PRIVATE {
     __pthread_initialize_minimal;
     __pthread_clock_gettime; __pthread_clock_settime;
diff --git a/nptl/sem_clockwait.c b/nptl/sem_clockwait.c
new file mode 100644
index 0000000..c0cd667
--- /dev/null
+++ b/nptl/sem_clockwait.c
@@ -0,0 +1,45 @@
+/* sem_clockwait -- wait on a semaphore with timeout using
+   the specified clock.
+
+   Copyright (C) 2003-2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include "sem_waitcommon.c"
+
+int
+sem_clockwait (sem_t *sem, clockid_t clockid,
+	       const struct timespec *abstime)
+{
+  /* Check that supplied clockid is one we support, even if we don't
+     end up waiting. */
+  if (!futex_abstimed_supported_clockid (clockid))
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0)
+    return 0;
+  else
+    return __new_sem_wait_slow ((struct new_sem *) sem, clockid, abstime);
+}
diff --git a/nptl/sem_timedwait.c b/nptl/sem_timedwait.c
index 3dd71ab..0918d8b 100644
--- a/nptl/sem_timedwait.c
+++ b/nptl/sem_timedwait.c
@@ -36,5 +36,6 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime)
   if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0)
     return 0;
   else
-    return __new_sem_wait_slow((struct new_sem *) sem, abstime);
+    return __new_sem_wait_slow ((struct new_sem *) sem,
+				CLOCK_REALTIME, abstime);
 }
diff --git a/nptl/sem_wait.c b/nptl/sem_wait.c
index 6a2d26b..20a8b9d 100644
--- a/nptl/sem_wait.c
+++ b/nptl/sem_wait.c
@@ -39,7 +39,8 @@ __new_sem_wait (sem_t *sem)
   if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0)
     return 0;
   else
-    return __new_sem_wait_slow((struct new_sem *) sem, NULL);
+    return __new_sem_wait_slow ((struct new_sem *) sem,
+				CLOCK_REALTIME, NULL);
 }
 versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1);
 
diff --git a/nptl/sem_waitcommon.c b/nptl/sem_waitcommon.c
index 425d040..cad56e9 100644
--- a/nptl/sem_waitcommon.c
+++ b/nptl/sem_waitcommon.c
@@ -103,19 +103,19 @@ __sem_wait_cleanup (void *arg)
    users don't seem to need it.  */
 static int
 __attribute__ ((noinline))
-do_futex_wait (struct new_sem *sem, const struct timespec *abstime)
+do_futex_wait (struct new_sem *sem, clockid_t clockid,
+	       const struct timespec *abstime)
 {
   int err;
 
 #if __HAVE_64B_ATOMICS
   err = futex_abstimed_wait_cancelable (
       (unsigned int *) &sem->data + SEM_VALUE_OFFSET, 0,
-      CLOCK_REALTIME, abstime,
+      clockid, abstime,
       sem->private);
 #else
   err = futex_abstimed_wait_cancelable (&sem->value, SEM_NWAITERS_MASK,
-					CLOCK_REALTIME, abstime,
-					sem->private);
+					clockid, abstime, sem->private);
 #endif
 
   return err;
@@ -162,7 +162,8 @@ __new_sem_wait_fast (struct new_sem *sem, int definitive_result)
 /* Slow path that blocks.  */
 static int
 __attribute__ ((noinline))
-__new_sem_wait_slow (struct new_sem *sem, const struct timespec *abstime)
+__new_sem_wait_slow (struct new_sem *sem, clockid_t clockid,
+		     const struct timespec *abstime)
 {
   int err = 0;
 
@@ -180,7 +181,7 @@ __new_sem_wait_slow (struct new_sem *sem, const struct timespec *abstime)
       /* If there is no token available, sleep until there is.  */
       if ((d & SEM_VALUE_MASK) == 0)
 	{
-	  err = do_futex_wait (sem, abstime);
+	  err = do_futex_wait (sem, clockid, abstime);
 	  /* A futex return value of 0 or EAGAIN is due to a real or spurious
 	     wake-up, or due to a change in the number of tokens.  We retry in
 	     these cases.
@@ -281,7 +282,7 @@ __new_sem_wait_slow (struct new_sem *sem, const struct timespec *abstime)
 	  if ((v >> SEM_VALUE_SHIFT) == 0)
 	    {
 	      /* See __HAVE_64B_ATOMICS variant.  */
-	      err = do_futex_wait(sem, abstime);
+	      err = do_futex_wait (sem, clockid, abstime);
 	      if (err == ETIMEDOUT || err == EINTR)
 		{
 		  __set_errno (err);
diff --git a/nptl/tst-sem13.c b/nptl/tst-sem13.c
index 28d37ed..21c3b7e 100644
--- a/nptl/tst-sem13.c
+++ b/nptl/tst-sem13.c
@@ -6,9 +6,14 @@
 #include <internaltypes.h>
 #include <support/check.h>
 
+/* A bogus clock value that tells run_test to use
+   sem_timedwait rather than sem_clockwait */
+#define CLOCK_USE_TIMEDWAIT (-1)
 
-static int
-do_test (void)
+typedef int (*waitfn_t)(sem_t *, struct timespec *);
+
+static void
+do_test_wait (waitfn_t waitfn, const char *fnname)
 {
   union
   {
@@ -16,11 +21,13 @@ do_test (void)
     struct new_sem ns;
   } u;
 
+  printf ("do_test_wait: %s\n", fnname);
+
   TEST_COMPARE (sem_init (&u.s, 0, 0), 0);
 
   struct timespec ts = { 0, 1000000001 };	/* Invalid.  */
   errno = 0;
-  TEST_VERIFY_EXIT (sem_timedwait (&u.s, &ts) < 0);
+  TEST_VERIFY_EXIT (waitfn (&u.s, &ts) < 0);
   TEST_COMPARE (errno, EINVAL);
 
 #if __HAVE_64B_ATOMICS
@@ -33,7 +40,7 @@ do_test (void)
   ts.tv_sec = /* Invalid.  */ -2;
   ts.tv_nsec = 0;
   errno = 0;
-  TEST_VERIFY_EXIT (sem_timedwait (&u.s, &ts) < 0);
+  TEST_VERIFY_EXIT (waitfn (&u.s, &ts) < 0);
   TEST_COMPARE (errno, ETIMEDOUT);
 #if __HAVE_64B_ATOMICS
   nwaiters = (u.ns.data >> SEM_NWAITERS_SHIFT);
@@ -41,7 +48,31 @@ do_test (void)
   nwaiters = u.ns.nwaiters;
 #endif
   TEST_COMPARE (nwaiters, 0);
+}
 
+int test_sem_timedwait (sem_t *sem, struct timespec *ts)
+{
+  return sem_timedwait (sem, ts);
+}
+
+int test_sem_clockwait_monotonic (sem_t *sem, struct timespec *ts)
+{
+  return sem_clockwait (sem, CLOCK_MONOTONIC, ts);
+}
+
+int test_sem_clockwait_realtime (sem_t *sem, struct timespec *ts)
+{
+  return sem_clockwait (sem, CLOCK_REALTIME, ts);
+}
+
+static int do_test (void)
+{
+  do_test_wait (&test_sem_timedwait,
+                "sem_timedwait");
+  do_test_wait (&test_sem_clockwait_monotonic,
+                "sem_clockwait(monotonic)");
+  do_test_wait (&test_sem_clockwait_realtime,
+                "sem_clockwait(realtime)");
   return 0;
 }
 
diff --git a/nptl/tst-sem17.c b/nptl/tst-sem17.c
new file mode 100644
index 0000000..78c52c8
--- /dev/null
+++ b/nptl/tst-sem17.c
@@ -0,0 +1,76 @@
+/* Test unsupported/bad clocks passed to sem_clockwait.
+
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <support/check.h>
+#include <support/timespec.h>
+
+
+#define NOT_A_VALID_CLOCK 123456
+
+static int
+do_test (void)
+{
+  sem_t s;
+  TEST_COMPARE (sem_init (&s, 0, 1), 0);
+
+  const struct timespec ts = make_timespec (0, 0);
+
+  /* These clocks are meaningless to sem_clockwait. */
+#if defined(CLOCK_PROCESS_CPUTIME_ID)
+  TEST_COMPARE (sem_clockwait (&s, CLOCK_PROCESS_CPUTIME_ID, &ts), -1);
+  TEST_COMPARE (errno, EINVAL);
+#endif
+#if defined(CLOCK_THREAD_CPUTIME_ID)
+  TEST_COMPARE (sem_clockwait (&s, CLOCK_THREAD_CPUTIME_ID, &ts), -1);
+  TEST_COMPARE (errno, EINVAL);
+#endif
+
+  /* These clocks might be meaningful, but are currently unsupported
+     by pthread_cond_clockwait. */
+#if defined(CLOCK_REALTIME_COARSE)
+  TEST_COMPARE (sem_clockwait (&s, CLOCK_REALTIME_COARSE, &ts), -1);
+  TEST_COMPARE (errno, EINVAL);
+#endif
+#if defined(CLOCK_MONOTONIC_RAW)
+  TEST_COMPARE (sem_clockwait (&s, CLOCK_MONOTONIC_RAW, &ts), -1);
+  TEST_COMPARE (errno, EINVAL);
+#endif
+#if defined(CLOCK_MONOTONIC_COARSE)
+  TEST_COMPARE (sem_clockwait (&s, CLOCK_MONOTONIC_COARSE, &ts), -1);
+  TEST_COMPARE (errno, EINVAL);
+#endif
+#if defined(CLOCK_BOOTTIME)
+  TEST_COMPARE (sem_clockwait (&s, CLOCK_BOOTTIME, &ts), -1);
+  TEST_COMPARE (errno, EINVAL);
+#endif
+
+  /* This is a completely invalid clock */
+  TEST_COMPARE (sem_clockwait (&s, NOT_A_VALID_CLOCK, &ts), -1);
+  TEST_COMPARE (errno, EINVAL);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/nptl/tst-sem5.c b/nptl/tst-sem5.c
index 396222b..843839b 100644
--- a/nptl/tst-sem5.c
+++ b/nptl/tst-sem5.c
@@ -25,10 +25,15 @@
 #include <support/timespec.h>
 #include <support/xtime.h>
 
+/* A bogus clock value that tells run_test to use
+   sem_timedwait rather than sem_clockwait */
+#define CLOCK_USE_TIMEDWAIT (-1)
 
-static int
-do_test (void)
+static void
+do_test_clock (clockid_t clockid)
 {
+  const clockid_t clockid_for_get =
+    clockid == CLOCK_USE_TIMEDWAIT ? CLOCK_REALTIME : clockid;
   sem_t s;
   struct timespec ts;
 
@@ -36,14 +41,22 @@ do_test (void)
   TEST_COMPARE (TEMP_FAILURE_RETRY (sem_wait (&s)), 0);
 
   /* We wait for half a second.  */
-  xclock_gettime (CLOCK_REALTIME, &ts);
+  xclock_gettime (clockid_for_get, &ts);
   ts = timespec_add (ts, make_timespec (0, TIMESPEC_HZ/2));
 
   errno = 0;
-  TEST_COMPARE (TEMP_FAILURE_RETRY (sem_timedwait (&s, &ts)), -1);
+  TEST_COMPARE (TEMP_FAILURE_RETRY ((clockid == CLOCK_USE_TIMEDWAIT)
+                                    ? sem_timedwait (&s, &ts)
+                                    : sem_clockwait (&s, clockid, &ts)), -1);
   TEST_COMPARE (errno, ETIMEDOUT);
-  TEST_TIMESPEC_NOW_OR_AFTER (CLOCK_REALTIME, ts);
+  TEST_TIMESPEC_NOW_OR_AFTER (clockid_for_get, ts);
+}
 
+static int do_test (void)
+{
+  do_test_clock (CLOCK_USE_TIMEDWAIT);
+  do_test_clock (CLOCK_REALTIME);
+  do_test_clock (CLOCK_MONOTONIC);
   return 0;
 }
 
diff --git a/sysdeps/pthread/semaphore.h b/sysdeps/pthread/semaphore.h
index 87c0543..6e74aa3 100644
--- a/sysdeps/pthread/semaphore.h
+++ b/sysdeps/pthread/semaphore.h
@@ -64,6 +64,13 @@ extern int sem_timedwait (sem_t *__restrict __sem,
   __nonnull ((1, 2));
 #endif
 
+#ifdef __USE_GNU
+extern int sem_clockwait (sem_t *__restrict __sem,
+			  clockid_t clock,
+			  const struct timespec *__restrict __abstime)
+  __nonnull ((1, 3));
+#endif
+
 /* Test whether SEM is posted.  */
 extern int sem_trywait (sem_t *__sem) __THROWNL __nonnull ((1));
 
diff --git a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
index 9a9e4ce..0294cb3 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
@@ -243,3 +243,4 @@ GLIBC_2.28 tss_create F
 GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
+GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
index b413007..1f63759 100644
--- a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
@@ -227,6 +227,7 @@ GLIBC_2.28 tss_create F
 GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
+GLIBC_2.30 sem_clockwait F
 GLIBC_2.3.2 pthread_cond_broadcast F
 GLIBC_2.3.2 pthread_cond_destroy F
 GLIBC_2.3.2 pthread_cond_init F
diff --git a/sysdeps/unix/sysv/linux/arm/libpthread.abilist b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
index af82a4c..905392e 100644
--- a/sysdeps/unix/sysv/linux/arm/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
@@ -27,6 +27,7 @@ GLIBC_2.28 tss_create F
 GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
+GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 _IO_flockfile F
 GLIBC_2.4 _IO_ftrylockfile F
 GLIBC_2.4 _IO_funlockfile F
diff --git a/sysdeps/unix/sysv/linux/csky/libpthread.abilist b/sysdeps/unix/sysv/linux/csky/libpthread.abilist
index ea4b79a..fdf577c 100644
--- a/sysdeps/unix/sysv/linux/csky/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libpthread.abilist
@@ -233,3 +233,4 @@ GLIBC_2.29 tss_set F
 GLIBC_2.29 wait F
 GLIBC_2.29 waitpid F
 GLIBC_2.29 write F
+GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
index bcba07f..fa02154 100644
--- a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
@@ -245,6 +245,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
 GLIBC_2.4 pthread_mutex_setprioceiling F
diff --git a/sysdeps/unix/sysv/linux/i386/libpthread.abilist b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
index bece86d..86eb656 100644
--- a/sysdeps/unix/sysv/linux/i386/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
@@ -253,6 +253,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
 GLIBC_2.4 pthread_mutex_setprioceiling F
diff --git a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
index ccc9449..406da6f 100644
--- a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
@@ -247,6 +247,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
 GLIBC_2.4 pthread_mutex_setprioceiling F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
index af82a4c..905392e 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
@@ -27,6 +27,7 @@ GLIBC_2.28 tss_create F
 GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
+GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 _IO_flockfile F
 GLIBC_2.4 _IO_ftrylockfile F
 GLIBC_2.4 _IO_funlockfile F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
index bece86d..86eb656 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
@@ -253,6 +253,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
 GLIBC_2.4 pthread_mutex_setprioceiling F
diff --git a/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
index 5067375..bd9455d 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
@@ -243,3 +243,4 @@ GLIBC_2.28 tss_create F
 GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
+GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
index 0214496..c1792c5 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
@@ -255,6 +255,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
 GLIBC_2.4 pthread_mutex_setprioceiling F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
index 0214496..c1792c5 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
@@ -255,6 +255,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
 GLIBC_2.4 pthread_mutex_setprioceiling F
diff --git a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
index 78cac2a..8eca3c2 100644
--- a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
@@ -241,3 +241,4 @@ GLIBC_2.28 tss_create F
 GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
+GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
index 09e8447..ca68bd7 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
@@ -255,6 +255,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.3.4 siglongjmp F
+GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
 GLIBC_2.4 pthread_mutex_setprioceiling F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
index 8300958..9e0500d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
@@ -246,6 +246,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.3.4 siglongjmp F
+GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
 GLIBC_2.4 pthread_mutex_setprioceiling F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
index 9a9e4ce..0294cb3 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
@@ -243,3 +243,4 @@ GLIBC_2.28 tss_create F
 GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
+GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
index c370fda..c6bddf9 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
@@ -235,3 +235,4 @@ GLIBC_2.28 tss_create F
 GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
+GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
index d05468f..581e3be 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
@@ -255,6 +255,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
 GLIBC_2.4 pthread_mutex_setprioceiling F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
index e8161aa..ed422c3 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
@@ -247,6 +247,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
 GLIBC_2.4 pthread_mutex_setprioceiling F
diff --git a/sysdeps/unix/sysv/linux/sh/libpthread.abilist b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
index bcba07f..fa02154 100644
--- a/sysdeps/unix/sysv/linux/sh/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
@@ -245,6 +245,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
 GLIBC_2.4 pthread_mutex_setprioceiling F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
index b413007..e31e905 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
@@ -255,6 +255,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
 GLIBC_2.4 pthread_mutex_setprioceiling F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
index ccc9449..406da6f 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
@@ -247,6 +247,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
 GLIBC_2.4 pthread_mutex_setprioceiling F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
index 931c827..454d340 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
@@ -245,6 +245,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
 GLIBC_2.4 pthread_mutex_setprioceiling F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
index c09c9b0..db565a1 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
@@ -243,3 +243,4 @@ GLIBC_2.28 tss_create F
 GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
+GLIBC_2.30 sem_clockwait F
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v4 06/12] nptl: Add POSIX-proposed pthread_cond_clockwait
  2019-06-18 16:33 [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions Mike Crowe
                   ` (4 preceding siblings ...)
  2019-06-18 16:33 ` [PATCH v4 05/12] nptl: Add POSIX-proposed sem_clockwait Mike Crowe
@ 2019-06-18 16:33 ` Mike Crowe
  2019-06-24 19:35   ` Adhemerval Zanella
  2019-06-18 16:33 ` [PATCH v4 07/12] nptl: pthread_rwlock: Move timeout validation into _full functions Mike Crowe
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 32+ messages in thread
From: Mike Crowe @ 2019-06-18 16:33 UTC (permalink / raw
  To: libc-alpha; +Cc: Mike Crowe

Add:

 int pthread_cond_clockwait (pthread_cond_t *cond,
                             pthread_mutex_t *mutex,
                             clockid_t clockid,
                             const struct timespec *abstime)

which behaves just like pthread_cond_timedwait except it always measures
abstime against the supplied clockid. Currently supports CLOCK_REALTIME and
CLOCK_MONOTONIC and returns EINVAL if any other clock is specified.

Includes feedback from many others. This function was originally
proposed[1] as pthread_cond_timedwaitonclock_np, but The Austin Group
preferred the new name.

	* nptl/Makefile: Add tst-cond26 and tst-cond27

	* nptl/Versions (GLIBC_2.30): Add pthread_cond_clockwait

	* sysdeps/nptl/pthread.h: Likewise

	* nptl/forward.c: Add __pthread_cond_clockwait

	* nptl/forward.c: Likewise

	* nptl/pthreadP.h: Likewise

	* sysdeps/nptl/pthread-functions.h: Likewise

	* nptl/pthread_cond_wait.c (__pthread_cond_wait_common): Add
	clockid parameter and comment describing why we don't need to check
	its value. Use that value when calling
	futex_abstimed_wait_cancelable rather than reading the clock from
	the flags. (__pthread_cond_wait): Pass unused clockid parameter.
	(__pthread_cond_timedwait): Read clock from flags and pass it to
	__pthread_cond_wait_common. (__pthread_cond_clockwait): Add new
	function with weak alias from pthread_cond_clockwait.

	* sysdeps/mach/hurd/i386/libpthread.abilist (GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/aarch64/libpthread.abilist (GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/alpha/libpthread.abilist (GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/arm/libpthread.abilist (GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/csky/libpthread.abilist (GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/hppa/libpthread.abilist (GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/i386/libpthread.abilist (GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/ia64/libpthread.abilist (GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/nios2/libpthread.abilist (GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/sh/libpthread.abilist (GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
	(GLIBC_2.30): Likewise.

	* nptl/tst-cond11.c (run_test): Support testing
	pthread_cond_clockwait too by using a special magic
	CLOCK_USE_ATTR_CLOCK value to determine whether to call
	pthread_cond_timedwait or pthread_cond_clockwait. (do_test): Pass
	CLOCK_USE_ATTR_CLOCK for existing tests, and add new tests using
	all combinations of CLOCK_MONOTONIC and CLOCK_REALTIME.

	* ntpl/tst-cond26.c: New test for passing unsupported and invalid
	clocks to pthread_cond_clockwait.

	* nptl/tst-cond27.c: Add test similar to tst-cond5.c, but using
	struct timespec and pthread_cond_clockwait.

	* manual/threads.texi: Document pthread_cond_clockwait. The comment
	was provided by Carlos O'Donell.

[1] https://sourceware.org/ml/libc-alpha/2015-07/msg00193.html
---
 ChangeLog                                                       | 85 +++++++-
 manual/threads.texi                                             | 20 ++-
 nptl/Makefile                                                   |  1 +-
 nptl/Versions                                                   |  2 +-
 nptl/forward.c                                                  |  5 +-
 nptl/nptl-init.c                                                |  1 +-
 nptl/pthreadP.h                                                 |  5 +-
 nptl/pthread_cond_wait.c                                        | 44 +++-
 nptl/tst-cond11.c                                               | 38 ++-
 nptl/tst-cond26.c                                               | 77 ++++++-
 nptl/tst-cond27.c                                               | 66 +++++-
 sysdeps/nptl/pthread-functions.h                                |  4 +-
 sysdeps/nptl/pthread.h                                          | 15 +-
 sysdeps/unix/sysv/linux/aarch64/libpthread.abilist              |  1 +-
 sysdeps/unix/sysv/linux/alpha/libpthread.abilist                |  1 +-
 sysdeps/unix/sysv/linux/arm/libpthread.abilist                  |  1 +-
 sysdeps/unix/sysv/linux/csky/libpthread.abilist                 |  1 +-
 sysdeps/unix/sysv/linux/hppa/libpthread.abilist                 |  1 +-
 sysdeps/unix/sysv/linux/i386/libpthread.abilist                 |  1 +-
 sysdeps/unix/sysv/linux/ia64/libpthread.abilist                 |  1 +-
 sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist        |  1 +-
 sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist          |  1 +-
 sysdeps/unix/sysv/linux/microblaze/libpthread.abilist           |  1 +-
 sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist          |  1 +-
 sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist          |  1 +-
 sysdeps/unix/sysv/linux/nios2/libpthread.abilist                |  1 +-
 sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist    |  1 +-
 sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist |  1 +-
 sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist |  1 +-
 sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist           |  1 +-
 sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist         |  1 +-
 sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist         |  1 +-
 sysdeps/unix/sysv/linux/sh/libpthread.abilist                   |  1 +-
 sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist        |  1 +-
 sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist        |  1 +-
 sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist            |  1 +-
 sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist           |  1 +-
 37 files changed, 369 insertions(+), 18 deletions(-)
 create mode 100644 nptl/tst-cond26.c
 create mode 100644 nptl/tst-cond27.c

diff --git a/ChangeLog b/ChangeLog
index 33502da..8386d5b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,90 @@
 2019-05-27  Mike Crowe  <mac@mcrowe.com>
 
+	nptl: Add POSIX-proposed pthread_cond_clockwait which behaves just
+	like pthread_cond_timedwait except it always measures abstime
+	against the supplied clockid.
+
+	* nptl/Makefile: Add tst-cond26 and tst-cond27
+
+	* nptl/Versions (GLIBC_2.30): Add pthread_cond_clockwait
+
+	* sysdeps/nptl/pthread.h: Likewise
+
+	* nptl/forward.c: Add __pthread_cond_clockwait
+
+	* nptl/forward.c: Likewise
+
+	* nptl/pthreadP.h: Likewise
+
+	* sysdeps/nptl/pthread-functions.h: Likewise
+
+	* nptl/pthread_cond_wait.c (__pthread_cond_wait_common): Add
+	clockid parameter and comment describing why we don't need to check
+	its value. Use that value when calling
+	futex_abstimed_wait_cancelable rather than reading the clock from
+	the flags. (__pthread_cond_wait): Pass unused clockid parameter.
+	(__pthread_cond_timedwait): Read clock from flags and pass it to
+	__pthread_cond_wait_common. (__pthread_cond_clockwait): Add new
+	function with weak alias from pthread_cond_clockwait.
+
+	* sysdeps/unix/sysv/linux/aarch64/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/alpha/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/arm/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/csky/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/hppa/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/i386/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/ia64/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/nios2/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/sh/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+
+	* nptl/tst-cond11.c (run_test): Support testing
+	pthread_cond_clockwait too by using a special magic
+	CLOCK_USE_ATTR_CLOCK value to determine whether to call
+	pthread_cond_timedwait or pthread_cond_clockwait. (do_test): Pass
+	CLOCK_USE_ATTR_CLOCK for existing tests, and add new tests using
+	all combinations of CLOCK_MONOTONIC and CLOCK_REALTIME.
+
+	* ntpl/tst-cond26.c: New test for passing unsupported and invalid
+	clocks to pthread_cond_clockwait.
+
+	* nptl/tst-cond27.c: Add test similar to tst-cond5.c, but using
+	struct timespec and pthread_cond_clockwait.
+
+	* manual/threads.texi: Document pthread_cond_clockwait. The comment
+	was provided by Carlos O'Donell.
+
+2019-05-27  Mike Crowe  <mac@mcrowe.com>
+
 	nptl: Add POSIX-proposed sem_clockwait which behaves just like
 	sem_timedwait, but measures abstime against the specified clock.
 
diff --git a/manual/threads.texi b/manual/threads.texi
index 674267c..91462f5 100644
--- a/manual/threads.texi
+++ b/manual/threads.texi
@@ -679,6 +679,26 @@ against the clock specified by @var{clockid} rather than
 @code{CLOCK_MONOTONIC} or @code{CLOCK_REALTIME}.
 @end deftypefun
 
+@comment pthread.h
+@comment POSIX-proposed
+@deftypefun int pthread_cond_clockwait (pthread_cond_t *@var{cond}, pthread_mutex_t *@var{mutex},
+                                        clockid_t @var{clockid}, const struct timespec *@var{abstime})
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+@c If exactly the same function with arguments is called from a signal
+@c handler that interrupts between the mutex unlock and sleep then it
+@c will unlock the mutex twice resulting in undefined behaviour. Keep
+@c in mind that the unlock and sleep are only atomic with respect to other
+@c threads (really a happens-after relationship for pthread_cond_broadcast
+@c and pthread_cond_signal).
+@c In the AC case we would cancel the thread and the mutex would remain
+@c locked and we can't recover from that.
+Behaves like @code{pthread_cond_timedwait} except the time @var{abstime} is
+measured against the clock specified by @var{clockid} rather than the clock
+specified or defaulted when @code{pthread_cond_init} was called. Currently,
+@var{clockid} must be either @code{CLOCK_MONOTONIC} or
+@code{CLOCK_REALTIME}.
+@end deftypefun
+
 @c FIXME these are undocumented:
 @c pthread_atfork
 @c pthread_attr_destroy
diff --git a/nptl/Makefile b/nptl/Makefile
index 43a99dc..70a2139 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -250,6 +250,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
 	tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
 	tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
 	tst-cond20 tst-cond21 tst-cond22 tst-cond23 tst-cond24 tst-cond25 \
+	tst-cond26 tst-cond27 \
 	tst-cond-except \
 	tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
 	tst-robust6 tst-robust7 tst-robust8 tst-robust9 \
diff --git a/nptl/Versions b/nptl/Versions
index cd1806c..8c094d0 100644
--- a/nptl/Versions
+++ b/nptl/Versions
@@ -278,7 +278,7 @@ libpthread {
   }
 
   GLIBC_2.30 {
-    sem_clockwait;
+    sem_clockwait; pthread_cond_clockwait;
   }
 
   GLIBC_PRIVATE {
diff --git a/nptl/forward.c b/nptl/forward.c
index ed1e7d0..50f358f 100644
--- a/nptl/forward.c
+++ b/nptl/forward.c
@@ -164,6 +164,11 @@ FORWARD (__pthread_cond_timedwait,
 	  const struct timespec *abstime), (cond, mutex, abstime), 0)
 versioned_symbol (libc, __pthread_cond_timedwait, pthread_cond_timedwait,
 		  GLIBC_2_3_2);
+FORWARD (__pthread_cond_clockwait,
+	 (pthread_cond_t *cond, pthread_mutex_t *mutex, clockid_t clockid,
+	  const struct timespec *abstime), (cond, mutex, clockid, abstime),
+	 0)
+weak_alias (__pthread_cond_clockwait, pthread_cond_clockwait);
 
 
 FORWARD (pthread_equal, (pthread_t thread1, pthread_t thread2),
diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c
index 73935f8..9c2a3d7 100644
--- a/nptl/nptl-init.c
+++ b/nptl/nptl-init.c
@@ -95,6 +95,7 @@ static const struct pthread_functions pthread_functions =
     .ptr___pthread_cond_signal = __pthread_cond_signal,
     .ptr___pthread_cond_wait = __pthread_cond_wait,
     .ptr___pthread_cond_timedwait = __pthread_cond_timedwait,
+    .ptr___pthread_cond_clockwait = __pthread_cond_clockwait,
 # if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_3_2)
     .ptr___pthread_cond_broadcast_2_0 = __pthread_cond_broadcast_2_0,
     .ptr___pthread_cond_destroy_2_0 = __pthread_cond_destroy_2_0,
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index 66527d8..d80662a 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -449,6 +449,11 @@ extern int __pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);
 extern int __pthread_cond_timedwait (pthread_cond_t *cond,
 				     pthread_mutex_t *mutex,
 				     const struct timespec *abstime);
+extern int __pthread_cond_clockwait (pthread_cond_t *cond,
+				     pthread_mutex_t *mutex,
+				     clockid_t clockid,
+				     const struct timespec *abstime)
+  __nonnull ((1, 2, 4));
 extern int __pthread_condattr_destroy (pthread_condattr_t *attr);
 extern int __pthread_condattr_init (pthread_condattr_t *attr);
 extern int __pthread_key_create (pthread_key_t *key, void (*destr) (void *));
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
index 7385562..558f930 100644
--- a/nptl/pthread_cond_wait.c
+++ b/nptl/pthread_cond_wait.c
@@ -378,6 +378,7 @@ __condvar_cleanup_waiting (void *arg)
 */
 static __always_inline int
 __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
+    clockid_t clockid,
     const struct timespec *abstime)
 {
   const int maxspin = 0;
@@ -386,6 +387,11 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
 
   LIBC_PROBE (cond_wait, 2, cond, mutex);
 
+  /* clockid will already have been checked by
+     __pthread_cond_clockwait or pthread_condattr_setclock, or we
+     don't use it if abstime is NULL, so we don't need to check it
+     here. */
+
   /* Acquire a position (SEQ) in the waiter sequence (WSEQ).  We use an
      atomic operation because signals and broadcasts may update the group
      switch without acquiring the mutex.  We do not need release MO here
@@ -511,10 +517,6 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
 	        err = ETIMEDOUT;
 	      else
 		{
-		  const clockid_t clockid =
-		    ((flags & __PTHREAD_COND_CLOCK_MONOTONIC_MASK) != 0) ?
-		    CLOCK_MONOTONIC : CLOCK_REALTIME;
-
 		  err = futex_abstimed_wait_cancelable
                     (cond->__data.__g_signals + g, 0, clockid, abstime,
                      private);
@@ -632,7 +634,8 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
 int
 __pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)
 {
-  return __pthread_cond_wait_common (cond, mutex, NULL);
+  /* clockid is unused when abstime is NULL. */
+  return __pthread_cond_wait_common (cond, mutex, 0, NULL);
 }
 
 /* See __pthread_cond_wait_common.  */
@@ -644,10 +647,39 @@ __pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
      it can assume that abstime is not NULL.  */
   if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
     return EINVAL;
-  return __pthread_cond_wait_common (cond, mutex, abstime);
+
+  /* Relaxed MO is suffice because clock ID bit is only modified
+     in condition creation.  */
+  unsigned int flags = atomic_load_relaxed (&cond->__data.__wrefs);
+  clockid_t clockid = (flags & __PTHREAD_COND_CLOCK_MONOTONIC_MASK)
+                    ? CLOCK_MONOTONIC : CLOCK_REALTIME;
+  return __pthread_cond_wait_common (cond, mutex, clockid, abstime);
+}
+
+/* See __pthread_cond_wait_common.  */
+int
+__pthread_cond_clockwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
+			  clockid_t clockid,
+			  const struct timespec *abstime)
+{
+  /* Check parameter validity.  This should also tell the compiler that
+     it can assume that abstime is not NULL.  */
+  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+    return EINVAL;
+
+  if (!futex_abstimed_supported_clockid (clockid))
+    return EINVAL;
+
+  /* If we do not support waiting using CLOCK_MONOTONIC, return an error.  */
+  if (clockid == CLOCK_MONOTONIC
+      && !futex_supports_exact_relative_timeouts ())
+    return EINVAL;
+
+  return __pthread_cond_wait_common (cond, mutex, clockid, abstime);
 }
 
 versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
 		  GLIBC_2_3_2);
 versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
 		  GLIBC_2_3_2);
+weak_alias (__pthread_cond_clockwait, pthread_cond_clockwait);
diff --git a/nptl/tst-cond11.c b/nptl/tst-cond11.c
index 3bc4ff4..09346c6 100644
--- a/nptl/tst-cond11.c
+++ b/nptl/tst-cond11.c
@@ -22,28 +22,32 @@
 #include <time.h>
 #include <unistd.h>
 #include <support/check.h>
+#include <support/test-driver.h>
 #include <support/timespec.h>
 #include <support/xthread.h>
 #include <support/xtime.h>
 
+/* A bogus clock value that tells run_test to use
+   pthread_cond_timedwait rather than pthread_condclockwait. */
+#define CLOCK_USE_ATTR_CLOCK (-1)
 
 #if defined _POSIX_CLOCK_SELECTION && _POSIX_CLOCK_SELECTION >= 0
 static int
-run_test (clockid_t cl)
+run_test (clockid_t attr_clock, clockid_t wait_clock)
 {
   pthread_condattr_t condattr;
   pthread_cond_t cond;
   pthread_mutexattr_t mutattr;
   pthread_mutex_t mut;
 
-  printf ("clock = %d\n", (int) cl);
+  verbose_printf ("attr_clock = %d\n", (int) attr_clock);
 
   TEST_COMPARE (pthread_condattr_init (&condattr), 0);
-  TEST_COMPARE (pthread_condattr_setclock (&condattr, cl), 0);
+  TEST_COMPARE (pthread_condattr_setclock (&condattr, attr_clock), 0);
 
-  clockid_t cl2;
-  TEST_COMPARE (pthread_condattr_getclock (&condattr, &cl2), 0);
-  TEST_COMPARE (cl, cl2);
+  clockid_t attr_clock_read;
+  TEST_COMPARE (pthread_condattr_getclock (&condattr, &attr_clock_read), 0);
+  TEST_COMPARE (attr_clock, attr_clock_read);
 
   TEST_COMPARE (pthread_cond_init (&cond, &condattr), 0);
   TEST_COMPARE (pthread_condattr_destroy (&condattr), 0);
@@ -57,13 +61,20 @@ run_test (clockid_t cl)
   TEST_COMPARE (pthread_mutex_lock (&mut), EDEADLK);
 
   struct timespec ts_timeout;
-  xclock_gettime (cl, &ts_timeout);
+  xclock_gettime (wait_clock == CLOCK_USE_ATTR_CLOCK ? attr_clock : wait_clock,
+                  &ts_timeout);
 
   /* Wait one second.  */
   ++ts_timeout.tv_sec;
 
-  TEST_COMPARE (pthread_cond_timedwait (&cond, &mut, &ts_timeout), ETIMEDOUT);
-  TEST_TIMESPEC_BEFORE_NOW (ts_timeout, cl);
+  if (wait_clock == CLOCK_USE_ATTR_CLOCK) {
+    TEST_COMPARE (pthread_cond_timedwait (&cond, &mut, &ts_timeout), ETIMEDOUT);
+    TEST_TIMESPEC_BEFORE_NOW (ts_timeout, attr_clock);
+  } else {
+    TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, wait_clock, &ts_timeout),
+                  ETIMEDOUT);
+    TEST_TIMESPEC_BEFORE_NOW (ts_timeout, wait_clock);
+  }
 
   xpthread_mutex_unlock (&mut);
   xpthread_mutex_destroy (&mut);
@@ -83,7 +94,7 @@ do_test (void)
 
 #else
 
-  run_test (CLOCK_REALTIME);
+  run_test (CLOCK_REALTIME, CLOCK_USE_ATTR_CLOCK);
 
 # if defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0
 #  if _POSIX_MONOTONIC_CLOCK == 0
@@ -93,8 +104,13 @@ do_test (void)
   else if (e == 0)
       FAIL_RET ("sysconf (_SC_MONOTONIC_CLOCK) must not return 0");
   else
+    {
 #  endif
-    run_test (CLOCK_MONOTONIC);
+      run_test (CLOCK_MONOTONIC, CLOCK_USE_ATTR_CLOCK);
+      run_test (CLOCK_REALTIME, CLOCK_MONOTONIC);
+      run_test (CLOCK_MONOTONIC, CLOCK_MONOTONIC);
+      run_test (CLOCK_MONOTONIC, CLOCK_REALTIME);
+    }
 # else
   puts ("_POSIX_MONOTONIC_CLOCK not defined");
 # endif
diff --git a/nptl/tst-cond26.c b/nptl/tst-cond26.c
new file mode 100644
index 0000000..2db7d2e
--- /dev/null
+++ b/nptl/tst-cond26.c
@@ -0,0 +1,77 @@
+/* Test unsupported/bad clocks passed to pthread_cond_clockwait.
+
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <support/check.h>
+#include <support/timespec.h>
+#include <support/xthread.h>
+
+static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
+
+#define NOT_A_VALID_CLOCK 123456
+
+static int
+do_test (void)
+{
+  xpthread_mutex_lock (&mut);
+
+  const struct timespec ts = make_timespec (0, 0);
+
+  /* These clocks are meaningless to sem_clockwait. */
+#if defined(CLOCK_PROCESS_CPUTIME_ID)
+  TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
+                                        CLOCK_PROCESS_CPUTIME_ID, &ts), EINVAL);
+#endif
+#if defined(CLOCK_THREAD_CPUTIME_ID)
+  TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
+                                        CLOCK_THREAD_CPUTIME_ID, &ts), EINVAL);
+#endif
+
+  /* These clocks might be meaningful, but are currently unsupported
+     by pthread_cond_clockwait. */
+#if defined(CLOCK_REALTIME_COARSE)
+  TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
+                                        CLOCK_REALTIME_COARSE, &ts), EINVAL);
+#endif
+#if defined(CLOCK_MONOTONIC_RAW)
+  TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
+                                        CLOCK_MONOTONIC_RAW, &ts), EINVAL);
+#endif
+#if defined(CLOCK_MONOTONIC_COARSE)
+  TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
+                                        CLOCK_MONOTONIC_COARSE, &ts), EINVAL);
+#endif
+#if defined(CLOCK_BOOTTIME)
+  TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
+                                        CLOCK_BOOTTIME, &ts), EINVAL);
+#endif
+
+  /* This is a completely invalid clock */
+  TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
+                                        NOT_A_VALID_CLOCK, &ts), EINVAL);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/nptl/tst-cond27.c b/nptl/tst-cond27.c
new file mode 100644
index 0000000..0f18821
--- /dev/null
+++ b/nptl/tst-cond27.c
@@ -0,0 +1,66 @@
+/* Test pthread_cond_clockwait timeout.
+
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <support/check.h>
+#include <support/timespec.h>
+#include <support/xthread.h>
+
+
+static pthread_mutex_t mut = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
+static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+
+
+static int
+do_test_clock (clockid_t clockid)
+{
+  /* Get the mutex.  */
+  xpthread_mutex_lock (&mut);
+
+  /* Waiting for the condition will fail.  But we want the timeout here.  */
+  const struct timespec ts_now = xclock_now (clockid);
+  const struct timespec ts_timeout =
+    timespec_add (ts_now, make_timespec (0, 500000000));
+
+  /* In theory pthread_cond_clockwait could return zero here due to
+     spurious wakeup. However that can't happen without a signal or an
+     additional waiter. */
+  TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, clockid, &ts_timeout),
+                ETIMEDOUT);
+
+  xpthread_mutex_unlock (&mut);
+
+  return 0;
+}
+
+static int
+do_test (void)
+{
+  do_test_clock (CLOCK_MONOTONIC);
+  do_test_clock (CLOCK_REALTIME);
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/nptl/pthread-functions.h b/sysdeps/nptl/pthread-functions.h
index cd5e94d..cfa9660 100644
--- a/sysdeps/nptl/pthread-functions.h
+++ b/sysdeps/nptl/pthread-functions.h
@@ -55,6 +55,10 @@ struct pthread_functions
   int (*ptr___pthread_cond_wait) (pthread_cond_t *, pthread_mutex_t *);
   int (*ptr___pthread_cond_timedwait) (pthread_cond_t *, pthread_mutex_t *,
 				       const struct timespec *);
+  int (*ptr___pthread_cond_clockwait) (pthread_cond_t *,
+				       pthread_mutex_t *,
+				       clockid_t,
+				       const struct timespec *);
   int (*ptr___pthread_cond_broadcast_2_0) (pthread_cond_2_0_t *);
   int (*ptr___pthread_cond_destroy_2_0) (pthread_cond_2_0_t *);
   int (*ptr___pthread_cond_init_2_0) (pthread_cond_2_0_t *,
diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
index 704a3c4..f000b1e 100644
--- a/sysdeps/nptl/pthread.h
+++ b/sysdeps/nptl/pthread.h
@@ -1003,6 +1003,21 @@ extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,
 				   const struct timespec *__restrict __abstime)
      __nonnull ((1, 2, 3));
 
+# ifdef __USE_GNU
+/* Wait for condition variable COND to be signaled or broadcast until
+   ABSTIME measured by the specified clock. MUTEX is assumed to be
+   locked before. CLOCK is the clock to use. ABSTIME is an absolute
+   time specification against CLOCK's epoch.
+
+   This function is a cancellation point and therefore not marked with
+   __THROW. */
+extern int pthread_cond_clockwait (pthread_cond_t *__restrict __cond,
+				   pthread_mutex_t *__restrict __mutex,
+				   __clockid_t __clock_id,
+				   const struct timespec *__restrict __abstime)
+     __nonnull ((1, 2, 4));
+# endif
+
 /* Functions for handling condition variable attributes.  */
 
 /* Initialize condition variable attribute ATTR.  */
diff --git a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
index 0294cb3..5af4b8a 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
@@ -243,4 +243,5 @@ GLIBC_2.28 tss_create F
 GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
index 1f63759..a00adfb 100644
--- a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
@@ -227,6 +227,7 @@ GLIBC_2.28 tss_create F
 GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.3.2 pthread_cond_broadcast F
 GLIBC_2.3.2 pthread_cond_destroy F
diff --git a/sysdeps/unix/sysv/linux/arm/libpthread.abilist b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
index 905392e..4aeee7b 100644
--- a/sysdeps/unix/sysv/linux/arm/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
@@ -27,6 +27,7 @@ GLIBC_2.28 tss_create F
 GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 _IO_flockfile F
 GLIBC_2.4 _IO_ftrylockfile F
diff --git a/sysdeps/unix/sysv/linux/csky/libpthread.abilist b/sysdeps/unix/sysv/linux/csky/libpthread.abilist
index fdf577c..2c08b76 100644
--- a/sysdeps/unix/sysv/linux/csky/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libpthread.abilist
@@ -233,4 +233,5 @@ GLIBC_2.29 tss_set F
 GLIBC_2.29 wait F
 GLIBC_2.29 waitpid F
 GLIBC_2.29 write F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
index fa02154..dc0d4ad 100644
--- a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
@@ -245,6 +245,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/i386/libpthread.abilist b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
index 86eb656..1830e40 100644
--- a/sysdeps/unix/sysv/linux/i386/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
@@ -253,6 +253,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
index 406da6f..0811d73 100644
--- a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
@@ -247,6 +247,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
index 905392e..4aeee7b 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
@@ -27,6 +27,7 @@ GLIBC_2.28 tss_create F
 GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 _IO_flockfile F
 GLIBC_2.4 _IO_ftrylockfile F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
index 86eb656..1830e40 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
@@ -253,6 +253,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
index bd9455d..f2be6b4 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
@@ -243,4 +243,5 @@ GLIBC_2.28 tss_create F
 GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
index c1792c5..41527fe 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
@@ -255,6 +255,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
index c1792c5..41527fe 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
@@ -255,6 +255,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
index 8eca3c2..04fc3a6 100644
--- a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
@@ -241,4 +241,5 @@ GLIBC_2.28 tss_create F
 GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
index ca68bd7..ebdab1a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
@@ -255,6 +255,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.3.4 siglongjmp F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
index 9e0500d..8a1fb34 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
@@ -246,6 +246,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.3.4 siglongjmp F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
index 0294cb3..5af4b8a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
@@ -243,4 +243,5 @@ GLIBC_2.28 tss_create F
 GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
index c6bddf9..a1c8c2e 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
@@ -235,4 +235,5 @@ GLIBC_2.28 tss_create F
 GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
index 581e3be..0feb3cf 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
@@ -255,6 +255,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
index ed422c3..cc4f160 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
@@ -247,6 +247,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/sh/libpthread.abilist b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
index fa02154..dc0d4ad 100644
--- a/sysdeps/unix/sysv/linux/sh/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
@@ -245,6 +245,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
index e31e905..ed0574a 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
@@ -255,6 +255,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
index 406da6f..0811d73 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
@@ -247,6 +247,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
index 454d340..aaa1c3b 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
@@ -245,6 +245,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
 GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
index db565a1..5d02b03 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
@@ -243,4 +243,5 @@ GLIBC_2.28 tss_create F
 GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
+GLIBC_2.30 pthread_cond_clockwait F
 GLIBC_2.30 sem_clockwait F
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v4 07/12] nptl: pthread_rwlock: Move timeout validation into _full functions
  2019-06-18 16:33 [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions Mike Crowe
                   ` (5 preceding siblings ...)
  2019-06-18 16:33 ` [PATCH v4 06/12] nptl: Add POSIX-proposed pthread_cond_clockwait Mike Crowe
@ 2019-06-18 16:33 ` Mike Crowe
  2019-06-25 20:42   ` Adhemerval Zanella
  2019-06-18 16:33 ` [PATCH v4 08/12] nptl: Add POSIX-proposed pthread_rwlock_clockrdlock & pthread_rwlock_clockwrlock Mike Crowe
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 32+ messages in thread
From: Mike Crowe @ 2019-06-18 16:33 UTC (permalink / raw
  To: libc-alpha; +Cc: Mike Crowe

As recommended by the comments in the implementations of
pthread_rwlock_timedrdlock and pthread_rwlock_timedwrlock, let's move the
timeout validity checks into the corresponding pthread_rwlock_rdlock_full
and pthread_rwlock_wrlock_full functions. Since these functions may be
called with abstime == NULL, an extra check for that is necessary too.

	* nptl/pthread_rwlock_common.c (__pthread_rwlock_rdlock_full):
	Check validity of abstime parameter.
	(__pthread_rwlock_rwlock_full): Likewise.

	* nptl/pthread_rwlock_timedrdlock.c (pthread_rwlock_timedrdlock):
	Remove check for validity of abstime parameter.

	* nptl/pthread_rwlock_timedwrlock.c (pthread_rwlock_timedwrlock):
	Likewise.
---
 ChangeLog                         | 14 ++++++++++++++
 nptl/pthread_rwlock_common.c      | 20 ++++++++++++++++++++
 nptl/pthread_rwlock_timedrdlock.c | 10 ----------
 nptl/pthread_rwlock_timedwrlock.c | 10 ----------
 4 files changed, 34 insertions(+), 20 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 8386d5b..452d047 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
 2019-05-27  Mike Crowe  <mac@mcrowe.com>
 
+	nptl: pthread_rwlock: Move timeout validation into _full functions
+
+	* nptl/pthread_rwlock_common.c (__pthread_rwlock_rdlock_full):
+	Check validity of abstime parameter.
+	(__pthread_rwlock_rwlock_full): Likewise.
+
+	* nptl/pthread_rwlock_timedrdlock.c (pthread_rwlock_timedrdlock):
+	Remove check for validity of abstime parameter.
+
+	* nptl/pthread_rwlock_timedwrlock.c (pthread_rwlock_timedwrlock):
+	Likewise.
+
+2019-05-27  Mike Crowe  <mac@mcrowe.com>
+
 	nptl: Add POSIX-proposed pthread_cond_clockwait which behaves just
 	like pthread_cond_timedwait except it always measures abstime
 	against the supplied clockid.
diff --git a/nptl/pthread_rwlock_common.c b/nptl/pthread_rwlock_common.c
index 89ba21a..120b880 100644
--- a/nptl/pthread_rwlock_common.c
+++ b/nptl/pthread_rwlock_common.c
@@ -282,6 +282,16 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
 {
   unsigned int r;
 
+  /* Make sure any passed in timeout value is valid.  Note that the previous
+     implementation assumed that this check *must* not be performed if there
+     would in fact be no blocking; however, POSIX only requires that "the
+     validity of the abstime parameter need not be checked if the lock can be
+     immediately acquired" (i.e., we need not but may check it).  */
+  if (abstime
+      && __glibc_unlikely (abstime->tv_nsec >= 1000000000
+      || abstime->tv_nsec < 0))
+    return EINVAL;
+
   /* Make sure we are not holding the rwlock as a writer.  This is a deadlock
      situation we recognize and report.  */
   if (__glibc_unlikely (atomic_load_relaxed (&rwlock->__data.__cur_writer)
@@ -576,6 +586,16 @@ static __always_inline int
 __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
     const struct timespec *abstime)
 {
+  /* Make sure any passed in timeout value is valid.  Note that the previous
+     implementation assumed that this check *must* not be performed if there
+     would in fact be no blocking; however, POSIX only requires that "the
+     validity of the abstime parameter need not be checked if the lock can be
+     immediately acquired" (i.e., we need not but may check it).  */
+  if (abstime
+      && __glibc_unlikely (abstime->tv_nsec >= 1000000000
+      || abstime->tv_nsec < 0))
+    return EINVAL;
+
   /* Make sure we are not holding the rwlock as a writer.  This is a deadlock
      situation we recognize and report.  */
   if (__glibc_unlikely (atomic_load_relaxed (&rwlock->__data.__cur_writer)
diff --git a/nptl/pthread_rwlock_timedrdlock.c b/nptl/pthread_rwlock_timedrdlock.c
index aa00530..84c1983 100644
--- a/nptl/pthread_rwlock_timedrdlock.c
+++ b/nptl/pthread_rwlock_timedrdlock.c
@@ -23,15 +23,5 @@ int
 pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock,
     const struct timespec *abstime)
 {
-  /* Make sure the passed in timeout value is valid.  Note that the previous
-     implementation assumed that this check *must* not be performed if there
-     would in fact be no blocking; however, POSIX only requires that "the
-     validity of the abstime parameter need not be checked if the lock can be
-     immediately acquired" (i.e., we need not but may check it).  */
-  /* ??? Just move this to __pthread_rwlock_rdlock_full?  */
-  if (__glibc_unlikely (abstime->tv_nsec >= 1000000000
-      || abstime->tv_nsec < 0))
-    return EINVAL;
-
   return __pthread_rwlock_rdlock_full (rwlock, abstime);
 }
diff --git a/nptl/pthread_rwlock_timedwrlock.c b/nptl/pthread_rwlock_timedwrlock.c
index 3c92e44..f0b745d 100644
--- a/nptl/pthread_rwlock_timedwrlock.c
+++ b/nptl/pthread_rwlock_timedwrlock.c
@@ -23,15 +23,5 @@ int
 pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock,
     const struct timespec *abstime)
 {
-  /* Make sure the passed in timeout value is valid.  Note that the previous
-     implementation assumed that this check *must* not be performed if there
-     would in fact be no blocking; however, POSIX only requires that "the
-     validity of the abstime parameter need not be checked if the lock can be
-     immediately acquired" (i.e., we need not but may check it).  */
-  /* ??? Just move this to __pthread_rwlock_wrlock_full?  */
-  if (__glibc_unlikely (abstime->tv_nsec >= 1000000000
-      || abstime->tv_nsec < 0))
-    return EINVAL;
-
   return __pthread_rwlock_wrlock_full (rwlock, abstime);
 }
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v4 08/12] nptl: Add POSIX-proposed pthread_rwlock_clockrdlock & pthread_rwlock_clockwrlock
  2019-06-18 16:33 [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions Mike Crowe
                   ` (6 preceding siblings ...)
  2019-06-18 16:33 ` [PATCH v4 07/12] nptl: pthread_rwlock: Move timeout validation into _full functions Mike Crowe
@ 2019-06-18 16:33 ` Mike Crowe
  2019-06-25 21:26   ` Adhemerval Zanella
  2019-06-18 16:33 ` [PATCH v4 09/12] nptl: Rename lll_timedlock to lll_clocklock and add clockid parameter Mike Crowe
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 32+ messages in thread
From: Mike Crowe @ 2019-06-18 16:33 UTC (permalink / raw
  To: libc-alpha; +Cc: Mike Crowe

Add:
 int pthread_rwlock_clockrdlock (pthread_rwlock_t *rwlock,
                                 clockid_t clockid,
                                 const struct timespec *abstime)
and:
 int pthread_rwlock_clockwrlock (pthread_rwlock_t *rwlock,
                                 clockid_t clockid,
                                 const struct timespec *abstime)

which behave like pthread_rwlock_timedrdlock and pthread_rwlock_timedwrlock
respectively, except they always measure abstime against the supplied
clockid. The functions currently support CLOCK_REALTIME and CLOCK_MONOTONIC
and return EINVAL if any other clock is specified.

	* sysdeps/nptl/pthread.h: Add pthread_rwlock_clockrdlock and
	pthread_wrlock_clockwrlock.

	* nptl/Makefile: Build pthread_rwlock_clockrdlock.c and
	pthread_rwlock_clockwrlock.c.

	* nptl/pthread_rwlock_clockrdlock.c: Implement
	pthread_rwlock_clockrdlock.

	* nptl/pthread_rwlock_clockwrlock.c: Implement
	pthread_rwlock_clockwrlock.

	* nptl/pthread_rwlock_common.c (__pthread_rwlock_rdlock_full): Add
	clockid parameter and verify that it indicates a supported clock on
	entry so that we fail even if it doesn't end up being used. Pass
	that clock on to futex_abstimed_wait when necessary.
	(__pthread_rwlock_wrlock_full): Likewise.

	* nptl/pthread_rwlock_rdlock.c: (__pthread_rwlock_rdlock): Pass
	CLOCK_REALTIME to __pthread_rwlock_rdlock_full even though it won't
	be used because there's no timeout.

	* nptl/pthread_rwlock_wrlock.c (__pthread_rwlock_wrlock): Pass
	CLOCK_REALTIME to __pthread_rwlock_wrlock_full even though it won't
	be used because there is no timeout.

	* nptl/pthread_rwlock_timedrdlock.c (pthread_rwlock_timedrdlock):
	Pass CLOCK_REALTIME to __pthread_rwlock_rdlock_full since abstime
	uses that clock.

	* nptl/pthread_rwlock_timedwrlock.c (pthread_rwlock_timedwrlock):
	Pass CLOCK_REALTIME to __pthread_rwlock_wrlock_full since abstime
	uses that clock.

	* sysdeps/mach/hurd/i386/libpthread.abilist (GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/aarch64/libpthread.abilist (GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/alpha/libpthread.abilist (GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/arm/libpthread.abilist (GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/csky/libpthread.abilist (GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/hppa/libpthread.abilist (GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/i386/libpthread.abilist (GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/ia64/libpthread.abilist (GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/nios2/libpthread.abilist (GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/sh/libpthread.abilist (GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
	(GLIBC_2.30): Likewise.
	* sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
	(GLIBC_2.30): Likewise.

	* nptl/tst-abstime.c (th): Add pthread_rwlock_clockrdlock and
	pthread_rwlock_clockwrlock timeout tests to match the existing
	pthread_rwlock_timedrdloock and pthread_rwlock_timedwrlock tests.

	* nptl/tst-rwlock14.c (do_test): Likewise.

	* nptl/tst-rwlock6.c Invent verbose_printf macro, and use for
	ancillary output throughout. (tf): Accept thread_args structure so
	that rwlock, a clockid and function name can be passed to the
	thread. (do_test_clock): Rename from do_test. Accept clockid
	parameter to specify test clock. Use the magic clockid value of
	CLOCK_USE_TIMEDLOCK to indicate that pthread_rwlock_timedrdlock and
	pthread_rwlock_timedwrlock should be tested, otherwise pass the
	specified clockid to pthread_rwlock_clockrdlock and
	pthread_rwlock_clockwrlock. Use xpthread_create and xpthread_join.
	(do_test): Call do_test_clock to test each clockid in turn.

	* nptl/tst-rwlock7.c: Likewise.

	* nptl/tst-rwlock9.c (writer_thread, reader_thread): Accept
	thread_args structure so that the (now int) thread number, the
	clockid and the function name can be passed to the thread.
	(do_test_clock): Renamed from do_test. Pass the necessary
	thread_args when creating the reader and writer threads. Use
	xpthread_create and xpthread_join.
	(do_test): Call do_test_clock to test each clockid in turn.

	* manual/threads.texi: Add documentation for
	pthread_rwlock_clockrdlock and pthread_rwlock_clockwrclock.
---
 ChangeLog                                                       | 114 +++++++-
 manual/threads.texi                                             |  28 ++-
 nptl/Makefile                                                   |   2 +-
 nptl/Versions                                                   |   1 +-
 nptl/pthread_rwlock_clockrdlock.c                               |  29 ++-
 nptl/pthread_rwlock_clockwrlock.c                               |  29 ++-
 nptl/pthread_rwlock_common.c                                    |  40 +-
 nptl/pthread_rwlock_rdlock.c                                    |   2 +-
 nptl/pthread_rwlock_timedrdlock.c                               |   2 +-
 nptl/pthread_rwlock_timedwrlock.c                               |   2 +-
 nptl/pthread_rwlock_wrlock.c                                    |   2 +-
 nptl/tst-abstime.c                                              |   8 +-
 nptl/tst-rwlock14.c                                             |  12 +-
 nptl/tst-rwlock6.c                                              |  95 ++++--
 nptl/tst-rwlock7.c                                              |  83 +++--
 nptl/tst-rwlock9.c                                              | 102 ++++--
 sysdeps/nptl/pthread.h                                          |  14 +-
 sysdeps/unix/sysv/linux/aarch64/libpthread.abilist              |   2 +-
 sysdeps/unix/sysv/linux/alpha/libpthread.abilist                |   2 +-
 sysdeps/unix/sysv/linux/arm/libpthread.abilist                  |   2 +-
 sysdeps/unix/sysv/linux/csky/libpthread.abilist                 |   2 +-
 sysdeps/unix/sysv/linux/hppa/libpthread.abilist                 |   2 +-
 sysdeps/unix/sysv/linux/i386/libpthread.abilist                 |   2 +-
 sysdeps/unix/sysv/linux/ia64/libpthread.abilist                 |   2 +-
 sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist        |   2 +-
 sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist          |   2 +-
 sysdeps/unix/sysv/linux/microblaze/libpthread.abilist           |   2 +-
 sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist          |   2 +-
 sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist          |   2 +-
 sysdeps/unix/sysv/linux/nios2/libpthread.abilist                |   2 +-
 sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist    |   2 +-
 sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist |   2 +-
 sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist |   2 +-
 sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist           |   2 +-
 sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist         |   2 +-
 sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist         |   2 +-
 sysdeps/unix/sysv/linux/sh/libpthread.abilist                   |   2 +-
 sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist        |   2 +-
 sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist        |   2 +-
 sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist            |   2 +-
 sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist           |   2 +-
 41 files changed, 513 insertions(+), 100 deletions(-)
 create mode 100644 nptl/pthread_rwlock_clockrdlock.c
 create mode 100644 nptl/pthread_rwlock_clockwrlock.c

diff --git a/ChangeLog b/ChangeLog
index 452d047..bd84ee4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,119 @@
 2019-05-27  Mike Crowe  <mac@mcrowe.com>
 
+	nptl: Add POSIX-proposed pthread_rwlock_clockrdlock &
+	pthread_rwlock_clockwrlock which behave like
+	pthread_rwlock_timedrdlock and pthread_rwlock_timedwrlock
+	respectively, except they always measure abstime against the
+	supplied clockid. The functions currently support CLOCK_REALTIME
+	and CLOCK_MONOTONIC and return EINVAL if any other clock is
+	specified.
+
+	* sysdeps/nptl/pthread.h: Add pthread_rwlock_clockrdlock and
+	pthread_wrlock_clockwrlock.
+
+	* nptl/Makefile: Build pthread_rwlock_clockrdlock.c and
+	pthread_rwlock_clockwrlock.c.
+
+	* nptl/pthread_rwlock_clockrdlock.c: Implement
+	pthread_rwlock_clockrdlock.
+
+	* nptl/pthread_rwlock_clockwrlock.c: Implement
+	pthread_rwlock_clockwrlock.
+
+	* nptl/pthread_rwlock_common.c (__pthread_rwlock_rdlock_full): Add
+	clockid parameter and verify that it indicates a supported clock on
+	entry so that we fail even if it doesn't end up being used. Pass
+	that clock on to futex_abstimed_wait when necessary.
+	(__pthread_rwlock_wrlock_full): Likewise.
+
+	* nptl/pthread_rwlock_rdlock.c: (__pthread_rwlock_rdlock): Pass
+	CLOCK_REALTIME to __pthread_rwlock_rdlock_full even though it won't
+	be used because there's no timeout.
+
+	* nptl/pthread_rwlock_wrlock.c (__pthread_rwlock_wrlock): Pass
+	CLOCK_REALTIME to __pthread_rwlock_wrlock_full even though it won't
+	be used because there is no timeout.
+
+	* nptl/pthread_rwlock_timedrdlock.c (pthread_rwlock_timedrdlock):
+	Pass CLOCK_REALTIME to __pthread_rwlock_rdlock_full since abstime
+	uses that clock.
+
+	* nptl/pthread_rwlock_timedwrlock.c (pthread_rwlock_timedwrlock):
+	Pass CLOCK_REALTIME to __pthread_rwlock_wrlock_full since abstime
+	uses that clock.
+
+	* sysdeps/unix/sysv/linux/aarch64/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/alpha/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/arm/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/csky/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/hppa/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/i386/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/ia64/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/nios2/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/sh/libpthread.abilist (GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+
+	* nptl/tst-abstime.c (th): Add pthread_rwlock_clockrdlock and
+	pthread_rwlock_clockwrlock timeout tests to match the existing
+	pthread_rwlock_timedrdloock and pthread_rwlock_timedwrlock tests.
+
+	* nptl/tst-rwlock14.c (do_test): Likewise.
+
+	* nptl/tst-rwlock6.c Invent verbose_printf macro, and use for
+	ancillary output throughout. (tf): Accept thread_args structure so
+	that rwlock, a clockid and function name can be passed to the
+	thread. (do_test_clock): Rename from do_test. Accept clockid
+	parameter to specify test clock. Use the magic clockid value of
+	CLOCK_USE_TIMEDLOCK to indicate that pthread_rwlock_timedrdlock and
+	pthread_rwlock_timedwrlock should be tested, otherwise pass the
+	specified clockid to pthread_rwlock_clockrdlock and
+	pthread_rwlock_clockwrlock. Use xpthread_create and xpthread_join.
+	(do_test): Call do_test_clock to test each clockid in turn.
+
+	* nptl/tst-rwlock7.c: Likewise.
+
+	* nptl/tst-rwlock9.c (writer_thread, reader_thread): Accept
+	thread_args structure so that the (now int) thread number, the
+	clockid and the function name can be passed to the thread.
+	(do_test_clock): Renamed from do_test. Pass the necessary
+	thread_args when creating the reader and writer threads. Use
+	xpthread_create and xpthread_join.
+	(do_test): Call do_test_clock to test each clockid in turn.
+
+	* manual/threads.texi: Add documentation for
+	pthread_rwlock_clockrdlock and pthread_rwlock_clockwrclock.
+
+2019-05-27  Mike Crowe  <mac@mcrowe.com>
+
 	nptl: pthread_rwlock: Move timeout validation into _full functions
 
 	* nptl/pthread_rwlock_common.c (__pthread_rwlock_rdlock_full):
diff --git a/manual/threads.texi b/manual/threads.texi
index 91462f5..83b8bb6 100644
--- a/manual/threads.texi
+++ b/manual/threads.texi
@@ -699,6 +699,34 @@ specified or defaulted when @code{pthread_cond_init} was called. Currently,
 @code{CLOCK_REALTIME}.
 @end deftypefun
 
+@comment pthread.h
+@comment POSIX-proposed
+@deftypefun int pthread_rwlock_clockrdlock (pthread_rwlock_t *@var{rwlock},
+				       clockid_t @var{clockid},
+				       const struct timespec *@var{abstime})
+
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+Behaves like @code{pthread_rwlock_timedrdlock} except the time
+@var{abstime} is measured against the clock specified by @var{clockid}
+rather than @code{CLOCK_REALTIME}. Currently, @var{clockid} must be either
+@code{CLOCK_MONOTONIC} or @code{CLOCK_REALTIME}, otherwise @code{EINVAL} is
+returned.
+@end deftypefun
+
+@comment pthread.h
+@comment POSIX-proposed
+@deftypefun int pthread_rwlock_clockwrlock (pthread_rwlock_t *@var{rwlock},
+				       clockid_t @var{clockid},
+				       const struct timespec *@var{abstime})
+
+@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
+Behaves like @code{pthread_rwlock_timedwrlock} except the time
+@var{abstime} is measured against the clock specified by @var{clockid}
+rather than @code{CLOCK_REALTIME}. Currently, @var{clockid} must be either
+@code{CLOCK_MONOTONIC} or @code{CLOCK_REALTIME}, otherwise @code{EINVAL} is
+returned.
+@end deftypefun
+
 @c FIXME these are undocumented:
 @c pthread_atfork
 @c pthread_attr_destroy
diff --git a/nptl/Makefile b/nptl/Makefile
index 70a2139..d86513a 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -76,7 +76,9 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \
 		      pthread_mutexattr_gettype pthread_mutexattr_settype \
 		      pthread_rwlock_init pthread_rwlock_destroy \
 		      pthread_rwlock_rdlock pthread_rwlock_timedrdlock \
+		      pthread_rwlock_clockrdlock \
 		      pthread_rwlock_wrlock pthread_rwlock_timedwrlock \
+		      pthread_rwlock_clockwrlock \
 		      pthread_rwlock_tryrdlock pthread_rwlock_trywrlock \
 		      pthread_rwlock_unlock \
 		      pthread_rwlockattr_init pthread_rwlockattr_destroy \
diff --git a/nptl/Versions b/nptl/Versions
index 8c094d0..ce79959 100644
--- a/nptl/Versions
+++ b/nptl/Versions
@@ -279,6 +279,7 @@ libpthread {
 
   GLIBC_2.30 {
     sem_clockwait; pthread_cond_clockwait;
+    pthread_rwlock_clockrdlock; pthread_rwlock_clockwrlock;
   }
 
   GLIBC_PRIVATE {
diff --git a/nptl/pthread_rwlock_clockrdlock.c b/nptl/pthread_rwlock_clockrdlock.c
new file mode 100644
index 0000000..3c252f5
--- /dev/null
+++ b/nptl/pthread_rwlock_clockrdlock.c
@@ -0,0 +1,29 @@
+/* Implement pthread_rwlock_clockrdlock.
+
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include "pthread_rwlock_common.c"
+
+/* See pthread_rwlock_common.c.  */
+int
+pthread_rwlock_clockrdlock (pthread_rwlock_t *rwlock,
+    clockid_t clockid,
+    const struct timespec *abstime)
+{
+  return __pthread_rwlock_rdlock_full (rwlock, clockid, abstime);
+}
diff --git a/nptl/pthread_rwlock_clockwrlock.c b/nptl/pthread_rwlock_clockwrlock.c
new file mode 100644
index 0000000..38ba693
--- /dev/null
+++ b/nptl/pthread_rwlock_clockwrlock.c
@@ -0,0 +1,29 @@
+/* Implement pthread_rwlock_clockwrlock.
+
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include "pthread_rwlock_common.c"
+
+/* See pthread_rwlock_common.c.  */
+int
+pthread_rwlock_clockwrlock (pthread_rwlock_t *rwlock,
+    clockid_t clockid,
+    const struct timespec *abstime)
+{
+  return __pthread_rwlock_wrlock_full (rwlock, clockid, abstime);
+}
diff --git a/nptl/pthread_rwlock_common.c b/nptl/pthread_rwlock_common.c
index 120b880..50a366e 100644
--- a/nptl/pthread_rwlock_common.c
+++ b/nptl/pthread_rwlock_common.c
@@ -278,17 +278,19 @@ __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)
 {
   unsigned int r;
 
-  /* Make sure any passed in timeout value is valid.  Note that the previous
-     implementation assumed that this check *must* not be performed if there
-     would in fact be no blocking; however, POSIX only requires that "the
-     validity of the abstime parameter need not be checked if the lock can be
-     immediately acquired" (i.e., we need not but may check it).  */
-  if (abstime
-      && __glibc_unlikely (abstime->tv_nsec >= 1000000000
+  /* Make sure any passed in clockid and timeout value are valid. Note
+     that the previous implementation assumed that this check *must*
+     not be performed if there would in fact be no blocking; however,
+     POSIX only requires that "the validity of the abstime parameter
+     need not be checked if the lock can be immediately acquired"
+     (i.e., we need not but may check it). */
+  if (abstime && __glibc_unlikely (!futex_abstimed_supported_clockid (clockid)
+      || abstime->tv_nsec >= 1000000000
       || abstime->tv_nsec < 0))
     return EINVAL;
 
@@ -329,7 +331,7 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
 		{
 		  int private = __pthread_rwlock_get_private (rwlock);
 		  int err = futex_abstimed_wait (&rwlock->__data.__readers,
-						 r, CLOCK_REALTIME, abstime, private);
+						 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,7 +459,7 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
 	    continue;
 	  int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
 					 1 | PTHREAD_RWLOCK_FUTEX_USED,
-					 CLOCK_REALTIME, abstime, private);
+					 clockid, abstime, private);
 	  if (err == ETIMEDOUT)
 	    {
 	      /* If we timed out, we need to unregister.  If no read phase
@@ -584,15 +586,17 @@ __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)
 {
-  /* Make sure any passed in timeout value is valid.  Note that the previous
-     implementation assumed that this check *must* not be performed if there
-     would in fact be no blocking; however, POSIX only requires that "the
-     validity of the abstime parameter need not be checked if the lock can be
-     immediately acquired" (i.e., we need not but may check it).  */
-  if (abstime
-      && __glibc_unlikely (abstime->tv_nsec >= 1000000000
+  /* Make sure any passed in clockid and timeout value are valid. Note
+     that the previous implementation assumed that this check *must*
+     not be performed if there would in fact be no blocking; however,
+     POSIX only requires that "the validity of the abstime parameter
+     need not be checked if the lock can be immediately acquired"
+     (i.e., we need not but may check it). */
+  if (abstime && __glibc_unlikely (!futex_abstimed_supported_clockid (clockid)
+      || abstime->tv_nsec >= 1000000000
       || abstime->tv_nsec < 0))
     return EINVAL;
 
@@ -727,7 +731,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 	  may_share_futex_used_flag = true;
 	  int err = futex_abstimed_wait (&rwlock->__data.__writers_futex,
 					 1 | PTHREAD_RWLOCK_FUTEX_USED,
-					 CLOCK_REALTIME, abstime, private);
+					 clockid, abstime, private);
 	  if (err == ETIMEDOUT)
 	    {
 	      if (prefer_writer)
@@ -826,7 +830,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 	    continue;
 	  int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
 					 PTHREAD_RWLOCK_FUTEX_USED,
-					 CLOCK_REALTIME, abstime, private);
+					 clockid, abstime, private);
 	  if (err == ETIMEDOUT)
 	    {
 	      if (rwlock->__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP)
diff --git a/nptl/pthread_rwlock_rdlock.c b/nptl/pthread_rwlock_rdlock.c
index 5fdc89e..387c824 100644
--- a/nptl/pthread_rwlock_rdlock.c
+++ b/nptl/pthread_rwlock_rdlock.c
@@ -24,7 +24,7 @@ __pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
 {
   LIBC_PROBE (rdlock_entry, 1, rwlock);
 
-  int result = __pthread_rwlock_rdlock_full (rwlock, NULL);
+  int result = __pthread_rwlock_rdlock_full (rwlock, CLOCK_REALTIME, NULL);
   LIBC_PROBE (rdlock_acquire_read, 1, rwlock);
   return result;
 }
diff --git a/nptl/pthread_rwlock_timedrdlock.c b/nptl/pthread_rwlock_timedrdlock.c
index 84c1983..8f8e680 100644
--- a/nptl/pthread_rwlock_timedrdlock.c
+++ b/nptl/pthread_rwlock_timedrdlock.c
@@ -23,5 +23,5 @@ int
 pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock,
     const struct timespec *abstime)
 {
-  return __pthread_rwlock_rdlock_full (rwlock, abstime);
+  return __pthread_rwlock_rdlock_full (rwlock, CLOCK_REALTIME, abstime);
 }
diff --git a/nptl/pthread_rwlock_timedwrlock.c b/nptl/pthread_rwlock_timedwrlock.c
index f0b745d..a5616de 100644
--- a/nptl/pthread_rwlock_timedwrlock.c
+++ b/nptl/pthread_rwlock_timedwrlock.c
@@ -23,5 +23,5 @@ int
 pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock,
     const struct timespec *abstime)
 {
-  return __pthread_rwlock_wrlock_full (rwlock, abstime);
+  return __pthread_rwlock_wrlock_full (rwlock, CLOCK_REALTIME, abstime);
 }
diff --git a/nptl/pthread_rwlock_wrlock.c b/nptl/pthread_rwlock_wrlock.c
index 194a14c..da246d8 100644
--- a/nptl/pthread_rwlock_wrlock.c
+++ b/nptl/pthread_rwlock_wrlock.c
@@ -24,7 +24,7 @@ __pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
 {
   LIBC_PROBE (wrlock_entry, 1, rwlock);
 
-  int result = __pthread_rwlock_wrlock_full (rwlock, NULL);
+  int result = __pthread_rwlock_wrlock_full (rwlock, CLOCK_REALTIME, NULL);
   LIBC_PROBE (wrlock_acquire_write, 1, rwlock);
   return result;
 }
diff --git a/nptl/tst-abstime.c b/nptl/tst-abstime.c
index 56fb8a5..c5040c5 100644
--- a/nptl/tst-abstime.c
+++ b/nptl/tst-abstime.c
@@ -38,6 +38,14 @@ th (void *arg)
   TEST_COMPARE (pthread_mutex_timedlock (&m1, &t), ETIMEDOUT);
   TEST_COMPARE (pthread_rwlock_timedrdlock (&rw1, &t), ETIMEDOUT);
   TEST_COMPARE (pthread_rwlock_timedwrlock (&rw2, &t), ETIMEDOUT);
+  TEST_COMPARE (pthread_rwlock_clockrdlock (&rw1, CLOCK_REALTIME, &t),
+                ETIMEDOUT);
+  TEST_COMPARE (pthread_rwlock_clockwrlock (&rw2, CLOCK_REALTIME, &t),
+                ETIMEDOUT);
+  TEST_COMPARE (pthread_rwlock_clockrdlock (&rw1, CLOCK_MONOTONIC, &t),
+                ETIMEDOUT);
+  TEST_COMPARE (pthread_rwlock_clockwrlock (&rw2, CLOCK_MONOTONIC, &t),
+                ETIMEDOUT);
   return NULL;
 }
 
diff --git a/nptl/tst-rwlock14.c b/nptl/tst-rwlock14.c
index af176b6..f4e1422 100644
--- a/nptl/tst-rwlock14.c
+++ b/nptl/tst-rwlock14.c
@@ -64,19 +64,31 @@ do_test (void)
   ts.tv_nsec = -1;
 
   TEST_COMPARE (pthread_rwlock_timedrdlock (&r, &ts), EINVAL);
+  TEST_COMPARE (pthread_rwlock_clockrdlock (&r, CLOCK_REALTIME, &ts), EINVAL);
+  TEST_COMPARE (pthread_rwlock_clockrdlock (&r, CLOCK_MONOTONIC, &ts), EINVAL);
   TEST_COMPARE (pthread_rwlock_timedwrlock (&r, &ts), EINVAL);
+  TEST_COMPARE (pthread_rwlock_clockwrlock (&r, CLOCK_REALTIME, &ts), EINVAL);
+  TEST_COMPARE (pthread_rwlock_clockwrlock (&r, CLOCK_MONOTONIC, &ts), EINVAL);
 
   ts.tv_nsec = 1000000000;
 
   TEST_COMPARE (pthread_rwlock_timedrdlock (&r, &ts), EINVAL);
+  TEST_COMPARE (pthread_rwlock_clockrdlock (&r, CLOCK_REALTIME, &ts), EINVAL);
+  TEST_COMPARE (pthread_rwlock_clockrdlock (&r, CLOCK_MONOTONIC, &ts), EINVAL);
   TEST_COMPARE (pthread_rwlock_timedwrlock (&r, &ts), EINVAL);
+  TEST_COMPARE (pthread_rwlock_clockwrlock (&r, CLOCK_REALTIME, &ts), EINVAL);
+  TEST_COMPARE (pthread_rwlock_clockwrlock (&r, CLOCK_MONOTONIC, &ts), EINVAL);
 
   ts.tv_nsec = (__typeof (ts.tv_nsec)) 0x100001000LL;
   if ((__typeof (ts.tv_nsec)) 0x100001000LL != 0x100001000LL)
     ts.tv_nsec = 2000000000;
 
   TEST_COMPARE (pthread_rwlock_timedrdlock (&r, &ts), EINVAL);
+  TEST_COMPARE (pthread_rwlock_clockrdlock (&r, CLOCK_REALTIME, &ts), EINVAL);
+  TEST_COMPARE (pthread_rwlock_clockrdlock (&r, CLOCK_MONOTONIC, &ts), EINVAL);
   TEST_COMPARE (pthread_rwlock_timedwrlock (&r, &ts), EINVAL);
+  TEST_COMPARE (pthread_rwlock_clockwrlock (&r, CLOCK_REALTIME, &ts), EINVAL);
+  TEST_COMPARE (pthread_rwlock_clockwrlock (&r, CLOCK_MONOTONIC, &ts), EINVAL);
 
   return 0;
 }
diff --git a/nptl/tst-rwlock6.c b/nptl/tst-rwlock6.c
index 5e73f50..fc24edc 100644
--- a/nptl/tst-rwlock6.c
+++ b/nptl/tst-rwlock6.c
@@ -23,11 +23,17 @@
 #include <string.h>
 #include <sys/time.h>
 #include <support/check.h>
+#include <support/test-driver.h>
 #include <support/timespec.h>
 #include <support/xthread.h>
 #include <support/xtime.h>
 
 
+/* A bogus clock value that tells run_test to use
+   pthread_rwlock_timedrdlock and pthread_rwlock_timedwrlock rather
+   than pthread_rwlock_clockrdlock and pthread_rwlock_clockwrlock. */
+#define CLOCK_USE_TIMEDLOCK (-1)
+
 static int kind[] =
   {
     PTHREAD_RWLOCK_PREFER_READER_NP,
@@ -35,43 +41,63 @@ static int kind[] =
     PTHREAD_RWLOCK_PREFER_WRITER_NP,
   };
 
+struct thread_args
+{
+  pthread_rwlock_t *rwlock;
+  clockid_t clockid;
+  const char *fnname;
+};
 
 static void *
 tf (void *arg)
 {
-  pthread_rwlock_t *r = arg;
+  struct thread_args *args = arg;
+  pthread_rwlock_t *r = args->rwlock;
+  const clockid_t clockid = args->clockid;
+  const clockid_t clockid_for_get =
+    (clockid == CLOCK_USE_TIMEDLOCK) ? CLOCK_REALTIME : clockid;
+  const char *fnname = args->fnname;
 
   /* Timeout: 0.3 secs.  */
   struct timespec ts_start;
-  xclock_gettime (CLOCK_REALTIME, &ts_start);
+  xclock_gettime (clockid_for_get, &ts_start);
 
   struct timespec ts_timeout = timespec_add (ts_start,
                                              make_timespec (0, 300000000));
 
-  puts ("child calling timedrdlock");
+  verbose_printf ("child calling %srdlock\n", fnname);
 
-  TEST_COMPARE (pthread_rwlock_timedrdlock (r, &ts_timeout), ETIMEDOUT);
+  if (clockid == CLOCK_USE_TIMEDLOCK)
+    TEST_COMPARE (pthread_rwlock_timedrdlock (r, &ts_timeout), ETIMEDOUT);
+  else
+    TEST_COMPARE (pthread_rwlock_clockrdlock (r, clockid, &ts_timeout),
+                  ETIMEDOUT);
 
-  puts ("1st child timedrdlock done");
+  verbose_printf ("1st child %srdlock done\n", fnname);
 
   TEST_TIMESPEC_NOW_OR_AFTER (CLOCK_REALTIME, ts_timeout);
 
-  xclock_gettime (CLOCK_REALTIME, &ts_timeout);
+  xclock_gettime (clockid_for_get, &ts_timeout);
   ts_timeout.tv_sec += 10;
   /* Note that the following operation makes ts invalid.  */
   ts_timeout.tv_nsec += 1000000000;
 
-  TEST_COMPARE (pthread_rwlock_timedrdlock (r, &ts_timeout), EINVAL);
+  if (clockid == CLOCK_USE_TIMEDLOCK)
+    TEST_COMPARE (pthread_rwlock_timedrdlock (r, &ts_timeout), EINVAL);
+  else
+    TEST_COMPARE (pthread_rwlock_clockrdlock (r, clockid, &ts_timeout), EINVAL);
 
-  puts ("2nd child timedrdlock done");
+  verbose_printf ("2nd child %srdlock done\n", fnname);
 
   return NULL;
 }
 
 
 static int
-do_test (void)
+do_test_clock (clockid_t clockid, const char *fnname)
 {
+  const clockid_t clockid_for_get =
+    (clockid == CLOCK_USE_TIMEDLOCK) ? CLOCK_REALTIME : clockid;
   size_t cnt;
   for (cnt = 0; cnt < sizeof (kind) / sizeof (kind[0]); ++cnt)
     {
@@ -91,39 +117,46 @@ do_test (void)
         FAIL_EXIT1 ("round %Zu: rwlockattr_destroy failed\n", cnt);
 
       struct timespec ts;
-      xclock_gettime (CLOCK_REALTIME, &ts);
+      xclock_gettime (clockid_for_get, &ts);
       ++ts.tv_sec;
 
       /* Get a write lock.  */
-      int e = pthread_rwlock_timedwrlock (&r, &ts);
+      int e = (clockid == CLOCK_USE_TIMEDLOCK)
+	? pthread_rwlock_timedwrlock (&r, &ts)
+	: pthread_rwlock_clockwrlock (&r, clockid, &ts);
       if (e != 0)
-        FAIL_EXIT1 ("round %Zu: rwlock_timedwrlock failed (%d)\n", cnt, e);
+        FAIL_EXIT1 ("round %Zu: %swrlock failed (%d)\n",
+                    cnt, fnname, e);
 
-      puts ("1st timedwrlock done");
+      verbose_printf ("1st %swrlock done\n", fnname);
 
-      xclock_gettime (CLOCK_REALTIME, &ts);
+      xclock_gettime (clockid_for_get, &ts);
       ++ts.tv_sec;
-      TEST_COMPARE (pthread_rwlock_timedrdlock (&r, &ts), EDEADLK);
+      if (clockid == CLOCK_USE_TIMEDLOCK)
+        TEST_COMPARE (pthread_rwlock_timedrdlock (&r, &ts), EDEADLK);
+      else
+        TEST_COMPARE (pthread_rwlock_clockrdlock (&r, clockid, &ts), EDEADLK);
 
-      puts ("1st timedrdlock done");
+      verbose_printf ("1st %srdlock done\n", fnname);
 
-      xclock_gettime (CLOCK_REALTIME, &ts);
+      xclock_gettime (clockid_for_get, &ts);
       ++ts.tv_sec;
-      TEST_COMPARE (pthread_rwlock_timedwrlock (&r, &ts), EDEADLK);
+      if (clockid == CLOCK_USE_TIMEDLOCK)
+        TEST_COMPARE (pthread_rwlock_timedwrlock (&r, &ts), EDEADLK);
+      else
+        TEST_COMPARE (pthread_rwlock_clockwrlock (&r, clockid, &ts), EDEADLK);
 
-      puts ("2nd timedwrlock done");
+      verbose_printf ("2nd %swrlock done\n", fnname);
 
-      pthread_t th;
-      if (pthread_create (&th, NULL, tf, &r) != 0)
-        FAIL_EXIT1 ("round %Zu: create failed\n", cnt);
+      struct thread_args args;
+      args.rwlock = &r;
+      args.clockid = clockid;
+      args.fnname = fnname;
+      pthread_t th = xpthread_create (NULL, tf, &args);
 
       puts ("started thread");
 
-      void *status;
-      if (pthread_join (th, &status) != 0)
-        FAIL_EXIT1 ("round %Zu: join failed\n", cnt);
-      if (status != NULL)
-        FAIL_EXIT1 ("failure in round %Zu\n", cnt);
+      (void) xpthread_join (th);
 
       puts ("joined thread");
 
@@ -134,4 +167,12 @@ do_test (void)
   return 0;
 }
 
+static int do_test (void)
+{
+  do_test_clock (CLOCK_USE_TIMEDLOCK, "timed");
+  do_test_clock (CLOCK_REALTIME, "clock(realtime)");
+  do_test_clock (CLOCK_MONOTONIC, "clock(monotonic)");
+  return 0;
+}
+
 #include <support/test-driver.c>
diff --git a/nptl/tst-rwlock7.c b/nptl/tst-rwlock7.c
index df50f0a..aa05f30 100644
--- a/nptl/tst-rwlock7.c
+++ b/nptl/tst-rwlock7.c
@@ -28,6 +28,11 @@
 #include <support/xtime.h>
 
 
+/* A bogus clock value that tells run_test to use
+   pthread_rwlock_timedrdlock and pthread_rwlock_timedwrlock rather
+   than pthread_rwlock_clockrdlock and pthread_rwlock_clockwrlock. */
+#define CLOCK_USE_TIMEDLOCK (-1)
+
 static int kind[] =
   {
     PTHREAD_RWLOCK_PREFER_READER_NP,
@@ -35,40 +40,60 @@ static int kind[] =
     PTHREAD_RWLOCK_PREFER_WRITER_NP,
   };
 
+struct thread_args
+{
+  pthread_rwlock_t *rwlock;
+  clockid_t clockid;
+  const char *fnname;
+};
 
 static void *
 tf (void *arg)
 {
-  pthread_rwlock_t *r = arg;
+  struct thread_args *args = arg;
+  pthread_rwlock_t *r = args->rwlock;
+  const clockid_t clockid = args->clockid;
+  const clockid_t clockid_for_get =
+    (clockid == CLOCK_USE_TIMEDLOCK) ? CLOCK_REALTIME : clockid;
+  const char *fnname = args->fnname;
 
   /* Timeout: 0.3 secs.  */
   struct timespec ts_start;
-  xclock_gettime (CLOCK_REALTIME, &ts_start);
+  xclock_gettime (clockid_for_get, &ts_start);
   const struct timespec ts_timeout = timespec_add (ts_start,
                                                    make_timespec (0, 300000000));
 
-  TEST_COMPARE (pthread_rwlock_timedwrlock (r, &ts_timeout), ETIMEDOUT);
-  puts ("child: timedwrlock failed with ETIMEDOUT");
+  if (clockid == CLOCK_USE_TIMEDLOCK)
+    TEST_COMPARE (pthread_rwlock_timedwrlock (r, &ts_timeout), ETIMEDOUT);
+  else
+    TEST_COMPARE (pthread_rwlock_clockwrlock (r, clockid, &ts_timeout),
+                  ETIMEDOUT);
+  printf ("child: %swrlock failed with ETIMEDOUT", fnname);
 
-  TEST_TIMESPEC_NOW_OR_AFTER (CLOCK_REALTIME, ts_timeout);
+  TEST_TIMESPEC_NOW_OR_AFTER (clockid_for_get, ts_timeout);
 
   struct timespec ts_invalid;
-  xclock_gettime (CLOCK_REALTIME, &ts_invalid);
+  xclock_gettime (clockid_for_get, &ts_invalid);
   ts_invalid.tv_sec += 10;
   /* Note that the following operation makes ts invalid.  */
   ts_invalid.tv_nsec += 1000000000;
 
-  TEST_COMPARE (pthread_rwlock_timedwrlock (r, &ts_invalid), EINVAL);
+  if (clockid == CLOCK_USE_TIMEDLOCK)
+    TEST_COMPARE (pthread_rwlock_timedwrlock (r, &ts_invalid), EINVAL);
+  else
+    TEST_COMPARE (pthread_rwlock_clockwrlock (r, clockid, &ts_invalid), EINVAL);
 
-  puts ("child: timedwrlock failed with EINVAL");
+  printf ("child: %swrlock failed with EINVAL", fnname);
 
   return NULL;
 }
 
 
 static int
-do_test (void)
+do_test_clock (clockid_t clockid, const char *fnname)
 {
+  const clockid_t clockid_for_get =
+    (clockid == CLOCK_USE_TIMEDLOCK) ? CLOCK_REALTIME : clockid;
   size_t cnt;
   for (cnt = 0; cnt < sizeof (kind) / sizeof (kind[0]); ++cnt)
     {
@@ -88,23 +113,27 @@ do_test (void)
         FAIL_EXIT1 ("round %Zu: rwlockattr_destroy failed\n", cnt);
 
       struct timespec ts;
-      xclock_gettime (CLOCK_REALTIME, &ts);
+      xclock_gettime (clockid_for_get, &ts);
 
       ++ts.tv_sec;
 
       /* Get a read lock.  */
-      if (pthread_rwlock_timedrdlock (&r, &ts) != 0)
-        FAIL_EXIT1 ("round %Zu: rwlock_timedrdlock failed\n", cnt);
-
-      printf ("%zu: got timedrdlock\n", cnt);
-
-      pthread_t th;
-      if (pthread_create (&th, NULL, tf, &r) != 0)
-        FAIL_EXIT1 ("round %Zu: create failed\n", cnt);
-
-      void *status;
-      if (pthread_join (th, &status) != 0)
-        FAIL_EXIT1 ("round %Zu: join failed\n", cnt);
+      if (clockid == CLOCK_USE_TIMEDLOCK) {
+        if (pthread_rwlock_timedrdlock (&r, &ts) != 0)
+          FAIL_EXIT1 ("round %Zu: rwlock_timedrdlock failed\n", cnt);
+      } else {
+        if (pthread_rwlock_clockrdlock (&r, clockid, &ts) != 0)
+          FAIL_EXIT1 ("round %Zu: rwlock_%srdlock failed\n", cnt, fnname);
+      }
+
+      printf ("%zu: got %srdlock\n", cnt, fnname);
+
+      struct thread_args args;
+      args.rwlock = &r;
+      args.clockid = clockid;
+      args.fnname = fnname;
+      pthread_t th = xpthread_create (NULL, tf, &args);
+      void *status = xpthread_join (th);
       if (status != NULL)
         FAIL_EXIT1 ("failure in round %Zu\n", cnt);
 
@@ -115,4 +144,14 @@ do_test (void)
   return 0;
 }
 
+static int
+do_test (void)
+{
+  do_test_clock (CLOCK_USE_TIMEDLOCK, "timed");
+  do_test_clock (CLOCK_MONOTONIC, "clock(monotonic)");
+  do_test_clock (CLOCK_REALTIME, "clock(realtime)");
+
+  return 0;
+}
+
 #include <support/test-driver.c>
diff --git a/nptl/tst-rwlock9.c b/nptl/tst-rwlock9.c
index e772247..e975554 100644
--- a/nptl/tst-rwlock9.c
+++ b/nptl/tst-rwlock9.c
@@ -26,6 +26,7 @@
 #include <sys/time.h>
 #include <support/check.h>
 #include <support/timespec.h>
+#include <support/xthread.h>
 
 
 #define NWRITERS 15
@@ -40,12 +41,30 @@ static const struct timespec delay = { 0, 1000000 };
 # define KIND PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
 #endif
 
+/* A bogus clock value that tells the tests to use
+   pthread_rwlock_timedrdlock and pthread_rwlock_timedwrlock rather
+   than pthread_rwlock_clockrdlock and pthread_rwlock_clockwrlock. */
+#define CLOCK_USE_TIMEDLOCK (-1)
+
 static pthread_rwlock_t lock;
 
+struct thread_args
+{
+  int nr;
+  clockid_t clockid;
+  const char *fnname;
+};
 
 static void *
-writer_thread (void *nr)
+writer_thread (void *arg)
 {
+  struct thread_args *args = arg;
+  const int nr = args->nr;
+  const clockid_t clockid = args->clockid;
+  const clockid_t clockid_for_get =
+    (clockid == CLOCK_USE_TIMEDLOCK) ? CLOCK_REALTIME : clockid;
+  const char *fnname = args->fnname;
+
   struct timespec ts;
   int n;
 
@@ -54,27 +73,29 @@ writer_thread (void *nr)
       int e;
       do
 	{
-	  xclock_gettime (CLOCK_REALTIME, &ts);
+	  xclock_gettime (clockid_for_get, &ts);
 
           ts = timespec_add (ts, timeout);
           ts = timespec_add (ts, timeout);
 
-	  printf ("writer thread %ld tries again\n", (long int) nr);
+	  printf ("writer thread %d tries again\n", nr);
 
-	  e = pthread_rwlock_timedwrlock (&lock, &ts);
+	  e = (clockid == CLOCK_USE_TIMEDLOCK)
+	    ? pthread_rwlock_timedwrlock (&lock, &ts)
+	    : pthread_rwlock_clockwrlock (&lock, clockid, &ts);
 	  if (e != 0 && e != ETIMEDOUT)
-            FAIL_EXIT1 ("timedwrlock failed");
+            FAIL_EXIT1 ("%swrlock failed", fnname);
 	}
       while (e == ETIMEDOUT);
 
-      printf ("writer thread %ld succeeded\n", (long int) nr);
+      printf ("writer thread %d succeeded\n", nr);
 
       nanosleep (&delay, NULL);
 
       if (pthread_rwlock_unlock (&lock) != 0)
         FAIL_EXIT1 ("unlock for writer failed");
 
-      printf ("writer thread %ld released\n", (long int) nr);
+      printf ("writer thread %d released\n", nr);
     }
 
   return NULL;
@@ -82,8 +103,15 @@ writer_thread (void *nr)
 
 
 static void *
-reader_thread (void *nr)
+reader_thread (void *arg)
 {
+  struct thread_args *args = arg;
+  const int nr = args->nr;
+  const clockid_t clockid = args->clockid;
+  const clockid_t clockid_for_get =
+    (clockid == CLOCK_USE_TIMEDLOCK) ? CLOCK_REALTIME : clockid;
+  const char *fnname = args->fnname;
+
   struct timespec ts;
   int n;
 
@@ -92,26 +120,29 @@ reader_thread (void *nr)
       int e;
       do
 	{
-	  xclock_gettime (CLOCK_REALTIME, &ts);
+	  xclock_gettime (clockid_for_get, &ts);
 
           ts = timespec_add (ts, timeout);
 
-	  printf ("reader thread %ld tries again\n", (long int) nr);
+	  printf ("reader thread %d tries again\n", nr);
 
-	  e = pthread_rwlock_timedrdlock (&lock, &ts);
+	  if (clockid == CLOCK_USE_TIMEDLOCK)
+	    e = pthread_rwlock_timedrdlock (&lock, &ts);
+          else
+	    e = pthread_rwlock_clockrdlock (&lock, clockid, &ts);
 	  if (e != 0 && e != ETIMEDOUT)
-            FAIL_EXIT1 ("timedrdlock failed");
+            FAIL_EXIT1 ("%srdlock failed", fnname);
 	}
       while (e == ETIMEDOUT);
 
-      printf ("reader thread %ld succeeded\n", (long int) nr);
+      printf ("reader thread %d succeeded\n", nr);
 
       nanosleep (&delay, NULL);
 
       if (pthread_rwlock_unlock (&lock) != 0)
         FAIL_EXIT1 ("unlock for reader failed");
 
-      printf ("reader thread %ld released\n", (long int) nr);
+      printf ("reader thread %d released\n", nr);
     }
 
   return NULL;
@@ -119,12 +150,11 @@ reader_thread (void *nr)
 
 
 static int
-do_test (void)
+do_test_clock (clockid_t clockid, const char *fnname)
 {
   pthread_t thwr[NWRITERS];
   pthread_t thrd[NREADERS];
   int n;
-  void *res;
   pthread_rwlockattr_t a;
 
   if (pthread_rwlockattr_init (&a) != 0)
@@ -142,23 +172,37 @@ do_test (void)
   /* Make sure we see all message, even those on stdout.  */
   setvbuf (stdout, NULL, _IONBF, 0);
 
-  for (n = 0; n < NWRITERS; ++n)
-    if (pthread_create (&thwr[n], NULL, writer_thread,
-			(void *) (long int) n) != 0)
-      FAIL_EXIT1 ("writer create failed");
-
-  for (n = 0; n < NREADERS; ++n)
-    if (pthread_create (&thrd[n], NULL, reader_thread,
-			(void *) (long int) n) != 0)
-      FAIL_EXIT1 ("reader create failed");
+  struct thread_args wargs[NWRITERS];
+  for (n = 0; n < NWRITERS; ++n) {
+    wargs[n].nr = n;
+    wargs[n].clockid = clockid;
+    wargs[n].fnname = fnname;
+    thwr[n] = xpthread_create (NULL, writer_thread, &wargs[n]);
+  }
+
+  struct thread_args rargs[NREADERS];
+  for (n = 0; n < NREADERS; ++n) {
+    rargs[n].nr = n;
+    rargs[n].clockid = clockid;
+    rargs[n].fnname = fnname;
+    thrd[n] = xpthread_create (NULL, reader_thread, &rargs[n]);
+  }
 
   /* Wait for all the threads.  */
   for (n = 0; n < NWRITERS; ++n)
-    if (pthread_join (thwr[n], &res) != 0)
-      FAIL_EXIT1 ("writer join failed");
+    xpthread_join (thwr[n]);
   for (n = 0; n < NREADERS; ++n)
-    if (pthread_join (thrd[n], &res) != 0)
-      FAIL_EXIT1 ("reader join failed");
+    xpthread_join (thrd[n]);
+
+  return 0;
+}
+
+static int
+do_test (void)
+{
+  do_test_clock (CLOCK_USE_TIMEDLOCK, "timed");
+  do_test_clock (CLOCK_REALTIME, "clock(realtime)");
+  do_test_clock (CLOCK_MONOTONIC, "clock(monotonic)");
 
   return 0;
 }
diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
index f000b1e..e78003e 100644
--- a/sysdeps/nptl/pthread.h
+++ b/sysdeps/nptl/pthread.h
@@ -909,6 +909,13 @@ extern int pthread_rwlock_timedrdlock (pthread_rwlock_t *__restrict __rwlock,
 				       __abstime) __THROWNL __nonnull ((1, 2));
 # endif
 
+# ifdef __USE_GNU
+extern int pthread_rwlock_clockrdlock (pthread_rwlock_t *__restrict __rwlock,
+				       clockid_t __clockid,
+				       const struct timespec *__restrict
+				       __abstime) __THROWNL __nonnull ((1, 3));
+# endif
+
 /* Acquire write lock for RWLOCK.  */
 extern int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock)
      __THROWNL __nonnull ((1));
@@ -924,6 +931,13 @@ extern int pthread_rwlock_timedwrlock (pthread_rwlock_t *__restrict __rwlock,
 				       __abstime) __THROWNL __nonnull ((1, 2));
 # endif
 
+# ifdef __USE_GNU
+extern int pthread_rwlock_clockwrlock (pthread_rwlock_t *__restrict __rwlock,
+				       clockid_t __clockid,
+				       const struct timespec *__restrict
+				       __abstime) __THROWNL __nonnull ((1, 3));
+# endif
+
 /* Unlock RWLOCK.  */
 extern int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock)
      __THROWNL __nonnull ((1));
diff --git a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
index 5af4b8a..9f65baf 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
@@ -244,4 +244,6 @@ GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
index a00adfb..0709855 100644
--- a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
@@ -228,6 +228,8 @@ GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.3.2 pthread_cond_broadcast F
 GLIBC_2.3.2 pthread_cond_destroy F
diff --git a/sysdeps/unix/sysv/linux/arm/libpthread.abilist b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
index 4aeee7b..a2be572 100644
--- a/sysdeps/unix/sysv/linux/arm/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
@@ -28,6 +28,8 @@ GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 _IO_flockfile F
 GLIBC_2.4 _IO_ftrylockfile F
diff --git a/sysdeps/unix/sysv/linux/csky/libpthread.abilist b/sysdeps/unix/sysv/linux/csky/libpthread.abilist
index 2c08b76..c3a1834 100644
--- a/sysdeps/unix/sysv/linux/csky/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libpthread.abilist
@@ -234,4 +234,6 @@ GLIBC_2.29 wait F
 GLIBC_2.29 waitpid F
 GLIBC_2.29 write F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
index dc0d4ad..2a00ebc 100644
--- a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
@@ -246,6 +246,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/i386/libpthread.abilist b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
index 1830e40..4479947 100644
--- a/sysdeps/unix/sysv/linux/i386/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
@@ -254,6 +254,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
index 0811d73..40a1faf 100644
--- a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
@@ -248,6 +248,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
index 4aeee7b..a2be572 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
@@ -28,6 +28,8 @@ GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 _IO_flockfile F
 GLIBC_2.4 _IO_ftrylockfile F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
index 1830e40..4479947 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
@@ -254,6 +254,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
index f2be6b4..254b708 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
@@ -244,4 +244,6 @@ GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
index 41527fe..29ffdd1 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
@@ -256,6 +256,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
index 41527fe..29ffdd1 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
@@ -256,6 +256,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
index 04fc3a6..3fae328 100644
--- a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
@@ -242,4 +242,6 @@ GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
index ebdab1a..a90010d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
@@ -256,6 +256,8 @@ GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.3.4 siglongjmp F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
index 8a1fb34..339eab8 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
@@ -247,6 +247,8 @@ GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.3.4 siglongjmp F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
index 5af4b8a..9f65baf 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
@@ -244,4 +244,6 @@ GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
index a1c8c2e..83082fb 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
@@ -236,4 +236,6 @@ GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
index 0feb3cf..54e937b 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
@@ -256,6 +256,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
index cc4f160..87f978b 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
@@ -248,6 +248,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/sh/libpthread.abilist b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
index dc0d4ad..2a00ebc 100644
--- a/sysdeps/unix/sysv/linux/sh/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
@@ -246,6 +246,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
index ed0574a..bc29a66 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
@@ -256,6 +256,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
index 0811d73..40a1faf 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
@@ -248,6 +248,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
index aaa1c3b..70f04cc 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
@@ -246,6 +246,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
 GLIBC_2.4 pthread_mutex_consistent_np F
 GLIBC_2.4 pthread_mutex_getprioceiling F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
index 5d02b03..92cd2f4 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
@@ -244,4 +244,6 @@ GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_rwlock_clockrdlock F
+GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v4 09/12] nptl: Rename lll_timedlock to lll_clocklock and add clockid parameter
  2019-06-18 16:33 [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions Mike Crowe
                   ` (7 preceding siblings ...)
  2019-06-18 16:33 ` [PATCH v4 08/12] nptl: Add POSIX-proposed pthread_rwlock_clockrdlock & pthread_rwlock_clockwrlock Mike Crowe
@ 2019-06-18 16:33 ` Mike Crowe
  2019-06-25 21:36   ` Adhemerval Zanella
  2019-06-18 16:33 ` [PATCH v4 10/12] nptl: Add POSIX-proposed pthread_mutex_clocklock Mike Crowe
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 32+ messages in thread
From: Mike Crowe @ 2019-06-18 16:33 UTC (permalink / raw
  To: libc-alpha; +Cc: Mike Crowe

Rename lll_timedlock to lll_clocklock and add clockid
parameter to indicate the clock that the abstime parameter should
be measured against in preparation for adding
pthread_mutex_clocklock.

The name change mirrors the naming for the exposed pthread functions:

 timed => absolute timeout measured against CLOCK_REALTIME (or clock
          specified by attribute in the case of pthread_cond_timedwait.)

 clock => absolute timeout measured against clock specified in preceding
          parameter.

* sysdeps/nptl/lowlevellock.h (lll_clocklock): Rename from lll_timedlock
  and add clockid parameter. (__lll_clocklock): Rename from __lll_timedlock
  and add clockid parameter.

* sysdeps/unix/sysv/linux/sparc/lowlevellock.h (lll_clocklock): Likewise.

* nptl/lll_timedlock_wait.c (__lll_clocklock_wait): Rename from
  __lll_timedlock_wait and add clockid parameter. Use __clock_gettime
  rather than __gettimeofday so that clockid can be used. This means that
  conversion from struct timeval is no longer required.

* sysdeps/sparc/sparc32/lowlevellock.c (lll_clocklock_wait): Likewise.

* sysdeps/sparc/sparc32/lll_timedlock_wait.c: Update comment to refer to
  __lll_clocklock_wait rather than __lll_timedlock_wait.

* nptl/pthread_mutex_timedlock.c (lll_clocklock_elision): Rename from
  lll_timedlock_elision, add clockid parameter and use meaningful names for
  other parameters. (__pthread_mutex_timedlock): Pass CLOCK_REALTIME where
  necessary to lll_clocklock and lll_clocklock_elision.

* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h (lll_clocklock_elision):
  Rename from lll_timedlock_elision and add clockid parameter.
  (__lll_clocklock_elision): Rename from __lll_timedlock_elision and add
  clockid parameter. * sysdeps/unix/sysv/linux/s390/lowlevellock.h:
  Likewise. * sysdeps/unix/sysv/linux/x86/lowlevellock.h: Likewise.

* sysdeps/unix/sysv/linux/powerpc/elision-timed.c (__lll_lock_elision):
  Call __lll_clocklock_elision rather than __lll_timedlock_elision.
  (EXTRAARG): Add clockid parameter. (LLL_LOCK): Likewise. *
  sysdeps/unix/sysv/linux/s390/elision-timed.c: Likewise. *
  sysdeps/unix/sysv/linux/x86/elision-timed.c: Likewise.
---
 ChangeLog                                       | 54 ++++++++++++++++++-
 nptl/lll_timedlock_wait.c                       | 15 +++--
 nptl/pthread_mutex_timedlock.c                  | 16 ++---
 sysdeps/nptl/lowlevellock.h                     | 16 ++---
 sysdeps/sparc/sparc32/lll_timedlock_wait.c      |  2 +-
 sysdeps/sparc/sparc32/lowlevellock.c            | 15 +++--
 sysdeps/unix/sysv/linux/powerpc/elision-timed.c |  6 +-
 sysdeps/unix/sysv/linux/powerpc/lowlevellock.h  |  9 +--
 sysdeps/unix/sysv/linux/s390/elision-timed.c    |  6 +-
 sysdeps/unix/sysv/linux/s390/lowlevellock.h     |  9 +--
 sysdeps/unix/sysv/linux/sparc/lowlevellock.h    | 11 ++--
 sysdeps/unix/sysv/linux/x86/elision-timed.c     |  6 +-
 sysdeps/unix/sysv/linux/x86/lowlevellock.h      | 11 ++--
 13 files changed, 122 insertions(+), 54 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index bd84ee4..713c677 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,57 @@
+2019-05-31  Mike Crowe  <mac@mcrowe.com>
+
+	nptl: Rename lll_timedlock to lll_clocklock and add clockid
+	parameter to indicate the clock that the abstime parameter should
+	be measured against in preparation for adding
+	pthread_mutex_clocklock.
+
+	The name change mirrors the naming for the exposed pthread functions:
+
+	 timed => absolute timeout measured against CLOCK_REALTIME (or
+		  clock specified by attribute in the case of
+		  pthread_cond_timedwait.)
+
+	 clock => absolute timeout measured against clock specified in preceding
+		  parameter.
+
+	* sysdeps/nptl/lowlevellock.h (lll_clocklock): Rename from
+	lll_timedlock and add clockid parameter. (__lll_clocklock): Rename
+	from __lll_timedlock and add clockid parameter.
+
+	* sysdeps/unix/sysv/linux/sparc/lowlevellock.h (lll_clocklock):
+	Likewise.
+
+	* nptl/lll_timedlock_wait.c (__lll_clocklock_wait): Rename from
+	__lll_timedlock_wait and add clockid parameter. Use __clock_gettime
+	rather than __gettimeofday so that clockid can be used. This means
+	that conversion from struct timeval is no longer required.
+
+	* sysdeps/sparc/sparc32/lowlevellock.c (lll_clocklock_wait):
+	Likewise.
+
+	* sysdeps/sparc/sparc32/lll_timedlock_wait.c: Update comment to
+	refer to __lll_clocklock_wait rather than __lll_timedlock_wait.
+
+	* nptl/pthread_mutex_timedlock.c (lll_clocklock_elision): Rename
+	from lll_timedlock_elision, add clockid parameter and use
+	meaningful names for other parameters. (__pthread_mutex_timedlock):
+	Pass CLOCK_REALTIME where necessary to lll_clocklock and
+	lll_clocklock_elision.
+
+	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
+	(lll_clocklock_elision): Rename from lll_timedlock_elision and add
+	clockid parameter. (__lll_clocklock_elision): Rename from
+	__lll_timedlock_elision and add clockid parameter.
+	* sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise.
+	* sysdeps/unix/sysv/linux/x86/lowlevellock.h: Likewise.
+
+	* sysdeps/unix/sysv/linux/powerpc/elision-timed.c
+	(__lll_lock_elision): Call __lll_clocklock_elision rather than
+	__lll_timedlock_elision. (EXTRAARG): Add clockid parameter.
+	(LLL_LOCK): Likewise.
+	* sysdeps/unix/sysv/linux/s390/elision-timed.c: Likewise.
+	* sysdeps/unix/sysv/linux/x86/elision-timed.c: Likewise.
+
 2019-05-27  Mike Crowe  <mac@mcrowe.com>
 
 	nptl: Add POSIX-proposed pthread_rwlock_clockrdlock &
diff --git a/nptl/lll_timedlock_wait.c b/nptl/lll_timedlock_wait.c
index 1f489ed..ad28724 100644
--- a/nptl/lll_timedlock_wait.c
+++ b/nptl/lll_timedlock_wait.c
@@ -24,7 +24,8 @@
 
 
 int
-__lll_timedlock_wait (int *futex, const struct timespec *abstime, int private)
+__lll_clocklock_wait (int *futex, clockid_t clockid,
+		      const struct timespec *abstime, int private)
 {
   /* Reject invalid timeouts.  */
   if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
@@ -33,15 +34,17 @@ __lll_timedlock_wait (int *futex, const struct timespec *abstime, int private)
   /* Try locking.  */
   while (atomic_exchange_acq (futex, 2) != 0)
     {
-      struct timeval tv;
+      struct timespec ts;
 
-      /* Get the current time.  */
-      (void) __gettimeofday (&tv, NULL);
+      /* Get the current time. This can only fail if clockid is not
+         valid. */
+      if (__glibc_unlikely (__clock_gettime (clockid, &ts) != 0))
+        return EINVAL;
 
       /* Compute relative timeout.  */
       struct timespec rt;
-      rt.tv_sec = abstime->tv_sec - tv.tv_sec;
-      rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+      rt.tv_sec = abstime->tv_sec - ts.tv_sec;
+      rt.tv_nsec = abstime->tv_nsec - ts.tv_nsec;
       if (rt.tv_nsec < 0)
         {
           rt.tv_nsec += 1000000000;
diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
index d4d11cc..10a9989 100644
--- a/nptl/pthread_mutex_timedlock.c
+++ b/nptl/pthread_mutex_timedlock.c
@@ -28,8 +28,9 @@
 
 #include <stap-probe.h>
 
-#ifndef lll_timedlock_elision
-#define lll_timedlock_elision(a,dummy,b,c) lll_timedlock(a, b, c)
+#ifndef lll_clocklock_elision
+#define lll_clocklock_elision(futex, adapt_count, clockid, abstime, private) \
+  lll_clocklock (futex, clockid, abstime, private)
 #endif
 
 #ifndef lll_trylock_elision
@@ -75,7 +76,7 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
 	}
 
       /* We have to get the mutex.  */
-      result = lll_timedlock (mutex->__data.__lock, abstime,
+      result = lll_clocklock (mutex->__data.__lock, CLOCK_REALTIME, abstime,
 			      PTHREAD_MUTEX_PSHARED (mutex));
 
       if (result != 0)
@@ -98,16 +99,16 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
       FORCE_ELISION (mutex, goto elision);
     simple:
       /* Normal mutex.  */
-      result = lll_timedlock (mutex->__data.__lock, abstime,
+      result = lll_clocklock (mutex->__data.__lock, CLOCK_REALTIME, abstime,
 			      PTHREAD_MUTEX_PSHARED (mutex));
       break;
 
     case PTHREAD_MUTEX_TIMED_ELISION_NP:
     elision: __attribute__((unused))
       /* Don't record ownership */
-      return lll_timedlock_elision (mutex->__data.__lock,
+      return lll_clocklock_elision (mutex->__data.__lock,
 				    mutex->__data.__spins,
-				    abstime,
+				    CLOCK_REALTIME, abstime,
 				    PTHREAD_MUTEX_PSHARED (mutex));
 
 
@@ -124,7 +125,8 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
 	    {
 	      if (cnt++ >= max_cnt)
 		{
-		  result = lll_timedlock (mutex->__data.__lock, abstime,
+		  result = lll_clocklock (mutex->__data.__lock,
+					  CLOCK_REALTIME, abstime,
 					  PTHREAD_MUTEX_PSHARED (mutex));
 		  break;
 		}
diff --git a/sysdeps/nptl/lowlevellock.h b/sysdeps/nptl/lowlevellock.h
index e905829..8ca50f4 100644
--- a/sysdeps/nptl/lowlevellock.h
+++ b/sysdeps/nptl/lowlevellock.h
@@ -121,24 +121,26 @@ extern void __lll_lock_wait (int *futex, int private) attribute_hidden;
 #define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private)
 
 
-extern int __lll_timedlock_wait (int *futex, const struct timespec *,
+extern int __lll_clocklock_wait (int *futex, clockid_t,
+				 const struct timespec *,
 				 int private) attribute_hidden;
 
 
-/* As __lll_lock, but with a timeout.  If the timeout occurs then return
-   ETIMEDOUT.  If ABSTIME is invalid, return EINVAL.  */
-#define __lll_timedlock(futex, abstime, private)                \
+/* As __lll_lock, but with an absolute timeout measured against the
+   clock specified in CLOCKID. If the timeout occurs then return
+   ETIMEDOUT. If ABSTIME is invalid, return EINVAL. */
+#define __lll_clocklock(futex, clockid, abstime, private)       \
   ({                                                            \
     int *__futex = (futex);                                     \
     int __val = 0;                                              \
                                                                 \
     if (__glibc_unlikely                                        \
         (atomic_compare_and_exchange_bool_acq (__futex, 1, 0))) \
-      __val = __lll_timedlock_wait (__futex, abstime, private); \
+      __val = __lll_clocklock_wait (__futex, clockid, abstime, private); \
     __val;                                                      \
   })
-#define lll_timedlock(futex, abstime, private)  \
-  __lll_timedlock (&(futex), abstime, private)
+#define lll_clocklock(futex, clockid, abstime, private)         \
+  __lll_clocklock (&(futex), clockid, abstime, private)
 
 
 /* This is an expression rather than a statement even though its value is
diff --git a/sysdeps/sparc/sparc32/lll_timedlock_wait.c b/sysdeps/sparc/sparc32/lll_timedlock_wait.c
index c2c93fa..bd639a7 100644
--- a/sysdeps/sparc/sparc32/lll_timedlock_wait.c
+++ b/sysdeps/sparc/sparc32/lll_timedlock_wait.c
@@ -1 +1 @@
-/* __lll_timedlock_wait is in lowlevellock.c.  */
+/* __lll_clocklock_wait is in lowlevellock.c.  */
diff --git a/sysdeps/sparc/sparc32/lowlevellock.c b/sysdeps/sparc/sparc32/lowlevellock.c
index 1a0b7bb..b0c5a6d 100644
--- a/sysdeps/sparc/sparc32/lowlevellock.c
+++ b/sysdeps/sparc/sparc32/lowlevellock.c
@@ -52,7 +52,8 @@ __lll_lock_wait (int *futex, int private)
 
 
 int
-__lll_timedlock_wait (int *futex, const struct timespec *abstime, int private)
+__lll_clocklock_wait (int *futex, clockid_t clockid,
+                      const struct timespec *abstime, int private)
 {
   /* Reject invalid timeouts.  */
   if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
@@ -60,15 +61,17 @@ __lll_timedlock_wait (int *futex, const struct timespec *abstime, int private)
 
   do
     {
-      struct timeval tv;
+      struct timespec ts;
       struct timespec rt;
 
-      /* Get the current time.  */
-      (void) __gettimeofday (&tv, NULL);
+      /* Get the current time. This can only fail if clockid is not
+         valid. */
+      if (__glibc_unlikely (__clock_gettime (clockid, &ts) != 0))
+        return EINVAL;
 
       /* Compute relative timeout.  */
-      rt.tv_sec = abstime->tv_sec - tv.tv_sec;
-      rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
+      rt.tv_sec = abstime->tv_sec - ts.tv_sec;
+      rt.tv_nsec = abstime->tv_nsec - ts.tv_nsec;
       if (rt.tv_nsec < 0)
 	{
 	  rt.tv_nsec += 1000000000;
diff --git a/sysdeps/unix/sysv/linux/powerpc/elision-timed.c b/sysdeps/unix/sysv/linux/powerpc/elision-timed.c
index f65818b..739cb6e 100644
--- a/sysdeps/unix/sysv/linux/powerpc/elision-timed.c
+++ b/sysdeps/unix/sysv/linux/powerpc/elision-timed.c
@@ -20,9 +20,9 @@
 #include <elision-conf.h>
 #include "lowlevellock.h"
 
-#define __lll_lock_elision __lll_timedlock_elision
-#define EXTRAARG const struct timespec *t,
+#define __lll_lock_elision __lll_clocklock_elision
+#define EXTRAARG clockid_t clockid, const struct timespec *t,
 #undef LLL_LOCK
-#define LLL_LOCK(a, b) lll_timedlock(a, t, b)
+#define LLL_LOCK(a, b) lll_clocklock(a, clockid, t, b)
 
 #include "elision-lock.c"
diff --git a/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h b/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
index 77235d7..4686c49 100644
--- a/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
+++ b/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
@@ -22,12 +22,13 @@
 #include <sysdeps/nptl/lowlevellock.h>
 
 /* Transactional lock elision definitions.  */
-extern int __lll_timedlock_elision
-  (int *futex, short *adapt_count, const struct timespec *timeout, int private)
+extern int __lll_clocklock_elision
+  (int *futex, short *adapt_count,
+   clockid_t clockid, const struct timespec *timeout, int private)
   attribute_hidden;
 
-#define lll_timedlock_elision(futex, adapt_count, timeout, private)	      \
-  __lll_timedlock_elision(&(futex), &(adapt_count), timeout, private)
+#define lll_clocklock_elision(futex, adapt_count, clockid, timeout, private) \
+  __lll_clocklock_elision (&(futex), &(adapt_count), clockid, timeout, private)
 
 extern int __lll_lock_elision (int *futex, short *adapt_count, int private)
   attribute_hidden;
diff --git a/sysdeps/unix/sysv/linux/s390/elision-timed.c b/sysdeps/unix/sysv/linux/s390/elision-timed.c
index f7a90fa..2563176 100644
--- a/sysdeps/unix/sysv/linux/s390/elision-timed.c
+++ b/sysdeps/unix/sysv/linux/s390/elision-timed.c
@@ -19,8 +19,8 @@
 #include <time.h>
 #include <elision-conf.h>
 #include <lowlevellock.h>
-#define __lll_lock_elision __lll_timedlock_elision
-#define EXTRAARG const struct timespec *t,
+#define __lll_lock_elision __lll_clocklock_elision
+#define EXTRAARG clockid_t clockid, const struct timespec *t,
 #undef LLL_LOCK
-#define LLL_LOCK(a, b) lll_timedlock(a, t, b)
+#define LLL_LOCK(a, b) lll_clocklock(a, clockid, t, b)
 #include "elision-lock.c"
diff --git a/sysdeps/unix/sysv/linux/s390/lowlevellock.h b/sysdeps/unix/sysv/linux/s390/lowlevellock.h
index 77e7580..2388bf2 100644
--- a/sysdeps/unix/sysv/linux/s390/lowlevellock.h
+++ b/sysdeps/unix/sysv/linux/s390/lowlevellock.h
@@ -22,12 +22,13 @@
 #include <sysdeps/nptl/lowlevellock.h>
 
 /* Transactional lock elision definitions.  */
-extern int __lll_timedlock_elision
-  (int *futex, short *adapt_count, const struct timespec *timeout, int private)
+extern int __lll_clocklock_elision
+  (int *futex, short *adapt_count,
+   clockid_t clockid, const struct timespec *timeout, int private)
   attribute_hidden;
 
-#  define lll_timedlock_elision(futex, adapt_count, timeout, private)	\
-  __lll_timedlock_elision(&(futex), &(adapt_count), timeout, private)
+#  define lll_clocklock_elision(futex, adapt_count, clockid, timeout, private) \
+  __lll_clocklock_elision (&(futex), &(adapt_count), clockid, timeout, private)
 
 extern int __lll_lock_elision (int *futex, short *adapt_count, int private)
   attribute_hidden;
diff --git a/sysdeps/unix/sysv/linux/sparc/lowlevellock.h b/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
index c778f42..c79a947 100644
--- a/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
+++ b/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
@@ -75,22 +75,23 @@ __lll_cond_lock (int *futex, int private)
 #define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private)
 
 
-extern int __lll_timedlock_wait (int *futex, const struct timespec *,
+extern int __lll_clocklock_wait (int *futex, clockid_t, const struct timespec *,
 				 int private) attribute_hidden;
 
 static inline int
 __attribute__ ((always_inline))
-__lll_timedlock (int *futex, const struct timespec *abstime, int private)
+__lll_clocklock (int *futex, clockid_t clockid,
+                 const struct timespec *abstime, int private)
 {
   int val = atomic_compare_and_exchange_val_24_acq (futex, 1, 0);
   int result = 0;
 
   if (__glibc_unlikely (val != 0))
-    result = __lll_timedlock_wait (futex, abstime, private);
+    result = __lll_clocklock_wait (futex, clockid, abstime, private);
   return result;
 }
-#define lll_timedlock(futex, abstime, private) \
-  __lll_timedlock (&(futex), abstime, private)
+#define lll_clocklock(futex, clockid, abstime, private)  \
+  __lll_clocklock (&(futex), clockid, abstime, private)
 
 #define lll_unlock(lock, private) \
   ((void) ({								      \
diff --git a/sysdeps/unix/sysv/linux/x86/elision-timed.c b/sysdeps/unix/sysv/linux/x86/elision-timed.c
index 9abc6ec..2c5073b 100644
--- a/sysdeps/unix/sysv/linux/x86/elision-timed.c
+++ b/sysdeps/unix/sysv/linux/x86/elision-timed.c
@@ -19,8 +19,8 @@
 #include <time.h>
 #include <elision-conf.h>
 #include "lowlevellock.h"
-#define __lll_lock_elision __lll_timedlock_elision
-#define EXTRAARG const struct timespec *t,
+#define __lll_lock_elision __lll_clocklock_elision
+#define EXTRAARG clockid_t clockid, const struct timespec *t,
 #undef LLL_LOCK
-#define LLL_LOCK(a, b) lll_timedlock(a, t, b)
+#define LLL_LOCK(a, b) lll_clocklock (a, clockid, t, b)
 #include "elision-lock.c"
diff --git a/sysdeps/unix/sysv/linux/x86/lowlevellock.h b/sysdeps/unix/sysv/linux/x86/lowlevellock.h
index 8a78dcf..e6c59ea 100644
--- a/sysdeps/unix/sysv/linux/x86/lowlevellock.h
+++ b/sysdeps/unix/sysv/linux/x86/lowlevellock.h
@@ -82,12 +82,13 @@ __lll_cas_lock (int *futex)
        __lll_unlock (&(lock), private);					     \
    }))
 
-extern int __lll_timedlock_elision (int *futex, short *adapt_count,
-					 const struct timespec *timeout,
-					 int private) attribute_hidden;
+extern int __lll_clocklock_elision (int *futex, short *adapt_count,
+                                    clockid_t clockid,
+				    const struct timespec *timeout,
+				    int private) attribute_hidden;
 
-#define lll_timedlock_elision(futex, adapt_count, timeout, private)	\
-  __lll_timedlock_elision(&(futex), &(adapt_count), timeout, private)
+#define lll_clocklock_elision(futex, adapt_count, clockid, timeout, private) \
+  __lll_clocklock_elision (&(futex), &(adapt_count), clockid, timeout, private)
 
 extern int __lll_lock_elision (int *futex, short *adapt_count, int private)
   attribute_hidden;
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v4 10/12] nptl: Add POSIX-proposed pthread_mutex_clocklock
  2019-06-18 16:33 [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions Mike Crowe
                   ` (8 preceding siblings ...)
  2019-06-18 16:33 ` [PATCH v4 09/12] nptl: Rename lll_timedlock to lll_clocklock and add clockid parameter Mike Crowe
@ 2019-06-18 16:33 ` Mike Crowe
  2019-06-25 21:59   ` Adhemerval Zanella
  2019-06-18 16:33 ` [PATCH v4 11/12] Update NEWS for new _clockwait and _clocklock functions Mike Crowe
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 32+ messages in thread
From: Mike Crowe @ 2019-06-18 16:33 UTC (permalink / raw
  To: libc-alpha; +Cc: Mike Crowe

nptl: Add POSIX-proposed pthread_mutex_clocklock function that works like
pthread_mutex_timedlock but takes a clockid parameter to measure the
abstime parameter against.

* sysdeps/nptl/pthread.h: Add pthread_mutex_clocklock.

* nptl/DESIGN-systemtap-probes.txt: Likewise.

* nptl/pthread_mutex_timedlock.c (__pthread_mutex_clocklock_common): Rename
  from __pthread_mutex_timedlock and add clockid parameter. Pass this
  parameter to lll_clocklock and lll_clocklock_elision in place of
  CLOCK_REALTIME. (__pthread_mutex_clocklock): New function to add
  LIBC_PROBE and validate clockid parameter before calling
  __pthread_mutex_clocklock_common. (__pthread_mutex_timedlock): New
  implementation to add LIBC_PROBE and calls
  __pthread_mutex_clocklock_common passing CLOCK_REALTIME as the clockid.

* nptl/Makefile: Add tst-mutex11.c.

* nptl/tst-abstime.c (th): Add tests for pthread_mutex_clocklock.

* nptl/tst-mutex11.c: New tests for passing invalid and unsupported clockid
  parameters to pthread_mutex_clocklock.

* nptl/tst-mutex5.c (do_test_clock): Rename from do_test and take clockid
  parameter to indicate which clock to be used. Call
  pthread_mutex_timedlock or pthread_mutex_clocklock as appropriate.
  (do_test): Call do_test_clock to separately test pthread_mutex_timedlock,
  pthread_mutex_clocklock(CLOCK_REALTIME) and
  pthread_mutex_clocklock(CLOCK_MONOTONIC).

* nptl/tst-mutex9.c: Likewise.

* nptl/Versions (GLIBC_2.30): Add pthread_mutex_clocklock.

* sysdeps/unix/sysv/linux/aarch64/libpthread.abilist (GLIBC_2.30):
  Likewise.

* sysdeps/unix/sysv/linux/alpha/libpthread.abilist (GLIBC_2.30):
  Likewise.

* sysdeps/unix/sysv/linux/arm/libpthread.abilist (GLIBC_2.30):
  Likewise.

* sysdeps/unix/sysv/linux/csky/libpthread.abilist (GLIBC_2.30):
  Likewise.

* sysdeps/unix/sysv/linux/hppa/libpthread.abilist (GLIBC_2.30):
  Likewise.

* sysdeps/unix/sysv/linux/i386/libpthread.abilist (GLIBC_2.30):
  Likewise.

* sysdeps/unix/sysv/linux/ia64/libpthread.abilist (GLIBC_2.30):
  Likewise.

* sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist (GLIBC_2.30):
  Likewise.

* sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist (GLIBC_2.30):
  Likewise.

* sysdeps/unix/sysv/linux/microblaze/libpthread.abilist (GLIBC_2.30):
  Likewise.

* sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist (GLIBC_2.30):
  Likewise.

* sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist (GLIBC_2.30):
  Likewise.

* sysdeps/unix/sysv/linux/nios2/libpthread.abilist (GLIBC_2.30):
  Likewise.

* sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
  (GLIBC_2.30): Likewise.

* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
  (GLIBC_2.30): Likewise.

* sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
  (GLIBC_2.30): Likewise.

* sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist (GLIBC_2.30):
  Likewise.

* sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist (GLIBC_2.30):
  Likewise.

* sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist (GLIBC_2.30):
  Likewise.

* sysdeps/unix/sysv/linux/sh/libpthread.abilist (GLIBC_2.30):
  Likewise.

* sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist (GLIBC_2.30):
  Likewise.

* sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist (GLIBC_2.30):
  Likewise.

* sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist (GLIBC_2.30):
  Likewise.

* sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist (GLIBC_2.30):
  Likewise.
---
 ChangeLog                                                       | 81 +++++++-
 nptl/DESIGN-systemtap-probes.txt                                |  3 +-
 nptl/Makefile                                                   |  2 +-
 nptl/Versions                                                   |  1 +-
 nptl/pthread_mutex_timedlock.c                                  | 40 ++-
 nptl/tst-abstime.c                                              |  2 +-
 nptl/tst-mutex11.c                                              | 69 ++++++-
 nptl/tst-mutex5.c                                               | 36 ++-
 nptl/tst-mutex9.c                                               | 24 +-
 sysdeps/nptl/pthread.h                                          |  7 +-
 sysdeps/unix/sysv/linux/aarch64/libpthread.abilist              |  1 +-
 sysdeps/unix/sysv/linux/alpha/libpthread.abilist                |  1 +-
 sysdeps/unix/sysv/linux/arm/libpthread.abilist                  |  1 +-
 sysdeps/unix/sysv/linux/csky/libpthread.abilist                 |  1 +-
 sysdeps/unix/sysv/linux/hppa/libpthread.abilist                 |  1 +-
 sysdeps/unix/sysv/linux/i386/libpthread.abilist                 |  1 +-
 sysdeps/unix/sysv/linux/ia64/libpthread.abilist                 |  1 +-
 sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist        |  1 +-
 sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist          |  1 +-
 sysdeps/unix/sysv/linux/microblaze/libpthread.abilist           |  1 +-
 sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist          |  1 +-
 sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist          |  1 +-
 sysdeps/unix/sysv/linux/nios2/libpthread.abilist                |  1 +-
 sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist    |  1 +-
 sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist |  1 +-
 sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist |  1 +-
 sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist           |  1 +-
 sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist         |  1 +-
 sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist         |  1 +-
 sysdeps/unix/sysv/linux/sh/libpthread.abilist                   |  1 +-
 sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist        |  1 +-
 sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist        |  1 +-
 sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist            |  1 +-
 sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist           |  1 +-
 34 files changed, 267 insertions(+), 22 deletions(-)
 create mode 100644 nptl/tst-mutex11.c

diff --git a/ChangeLog b/ChangeLog
index 713c677..a213eb1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,86 @@
 2019-05-31  Mike Crowe  <mac@mcrowe.com>
 
+	nptl: Add POSIX-proposed pthread_mutex_clocklock function that
+	works like pthread_mutex_timedlock but takes a clockid parameter to
+	measure the abstime parameter against.
+
+	* sysdeps/nptl/pthread.h: Add pthread_mutex_clocklock.
+	* nptl/DESIGN-systemtap-probes.txt: Likewise.
+	* nptl/pthread_mutex_timedlock.c
+	(__pthread_mutex_clocklock_common): Rename from
+	__pthread_mutex_timedlock and add clockid parameter. Pass this
+	parameter to lll_clocklock and lll_clocklock_elision in place of
+	CLOCK_REALTIME. (__pthread_mutex_clocklock): New function to add
+	LIBC_PROBE and validate clockid parameter before calling
+	__pthread_mutex_clocklock_common. (__pthread_mutex_timedlock): New
+	implementation to add LIBC_PROBE and calls
+	__pthread_mutex_clocklock_common passing CLOCK_REALTIME as the
+	clockid.
+
+	* nptl/Makefile: Add tst-mutex11.c.
+	* nptl/tst-abstime.c (th): Add tests for pthread_mutex_clocklock.
+	* nptl/tst-mutex11.c: New tests for passing invalid and unsupported
+	clockid parameters to pthread_mutex_clocklock.
+	* nptl/tst-mutex5.c (do_test_clock): Rename from do_test and take
+	clockid parameter to indicate which clock to be used. Call
+	pthread_mutex_timedlock or pthread_mutex_clocklock as appropriate.
+	(do_test): Call do_test_clock to separately test
+	pthread_mutex_timedlock, pthread_mutex_clocklock(CLOCK_REALTIME)
+	and pthread_mutex_clocklock(CLOCK_MONOTONIC).
+	* nptl/tst-mutex9.c: Likewise.
+
+	* nptl/Versions (GLIBC_2.30): Add pthread_mutex_clocklock.
+	* sysdeps/unix/sysv/linux/aarch64/libpthread.abilist (GLIBC_2.30):
+	Likewise.
+	* sysdeps/unix/sysv/linux/alpha/libpthread.abilist (GLIBC_2.30):
+	Likewise.
+	* sysdeps/unix/sysv/linux/arm/libpthread.abilist (GLIBC_2.30):
+	Likewise.
+	* sysdeps/unix/sysv/linux/csky/libpthread.abilist (GLIBC_2.30):
+	Likewise.
+	* sysdeps/unix/sysv/linux/hppa/libpthread.abilist (GLIBC_2.30):
+	Likewise.
+	* sysdeps/unix/sysv/linux/i386/libpthread.abilist (GLIBC_2.30):
+	Likewise.
+	* sysdeps/unix/sysv/linux/ia64/libpthread.abilist (GLIBC_2.30):
+	Likewise.
+	* sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/nios2/libpthread.abilist (GLIBC_2.30):
+	Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/sh/libpthread.abilist (GLIBC_2.30):
+	Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
+	(GLIBC_2.30): Likewise.
+
+2019-05-31  Mike Crowe  <mac@mcrowe.com>
+
 	nptl: Rename lll_timedlock to lll_clocklock and add clockid
 	parameter to indicate the clock that the abstime parameter should
 	be measured against in preparation for adding
diff --git a/nptl/DESIGN-systemtap-probes.txt b/nptl/DESIGN-systemtap-probes.txt
index ac972a9..6a62e25 100644
--- a/nptl/DESIGN-systemtap-probes.txt
+++ b/nptl/DESIGN-systemtap-probes.txt
@@ -32,6 +32,9 @@ mutex_entry   - probe for entry to the pthread_mutex_lock function
               arg1 = address of mutex lock
 mutex_timedlock_entry - probe for entry to the pthread_mutex_timedlock function
                       arg1 = address of mutex lock, arg2 = address of timespec
+mutex_clocklock_entry - probe for entry to the pthread_mutex_clocklock function
+                      arg1 = address of mutex lock, arg2 = clockid,
+		      arg3 = address of timespec
 mutex_release - probe for pthread_mutex_unlock after the successful release of a
                 mutex lock
               arg1 = address of mutex lock
diff --git a/nptl/Makefile b/nptl/Makefile
index d86513a..a2d25fb 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -243,7 +243,7 @@ LDLIBS-tst-minstack-throw = -lstdc++
 
 tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
 	tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \
-	tst-mutex7 tst-mutex9 tst-mutex10 tst-mutex5a tst-mutex7a \
+	tst-mutex7 tst-mutex9 tst-mutex10 tst-mutex11 tst-mutex5a tst-mutex7a \
 	tst-mutex7robust tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 \
 	tst-mutexpi5 tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a \
 	tst-mutexpi9 \
diff --git a/nptl/Versions b/nptl/Versions
index ce79959..e903b84 100644
--- a/nptl/Versions
+++ b/nptl/Versions
@@ -280,6 +280,7 @@ libpthread {
   GLIBC_2.30 {
     sem_clockwait; pthread_cond_clockwait;
     pthread_rwlock_clockrdlock; pthread_rwlock_clockwrlock;
+    pthread_mutex_clocklock;
   }
 
   GLIBC_PRIVATE {
diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
index 10a9989..52c258e 100644
--- a/nptl/pthread_mutex_timedlock.c
+++ b/nptl/pthread_mutex_timedlock.c
@@ -42,15 +42,14 @@
 #endif
 
 int
-__pthread_mutex_timedlock (pthread_mutex_t *mutex,
-			   const struct timespec *abstime)
+__pthread_mutex_clocklock_common (pthread_mutex_t *mutex,
+				  clockid_t clockid,
+				  const struct timespec *abstime)
 {
   int oldval;
   pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
   int result = 0;
 
-  LIBC_PROBE (mutex_timedlock_entry, 2, mutex, abstime);
-
   /* We must not check ABSTIME here.  If the thread does not block
      abstime must not be checked for a valid value.  */
 
@@ -76,7 +75,7 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
 	}
 
       /* We have to get the mutex.  */
-      result = lll_clocklock (mutex->__data.__lock, CLOCK_REALTIME, abstime,
+      result = lll_clocklock (mutex->__data.__lock, clockid, abstime,
 			      PTHREAD_MUTEX_PSHARED (mutex));
 
       if (result != 0)
@@ -99,7 +98,7 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
       FORCE_ELISION (mutex, goto elision);
     simple:
       /* Normal mutex.  */
-      result = lll_clocklock (mutex->__data.__lock, CLOCK_REALTIME, abstime,
+      result = lll_clocklock (mutex->__data.__lock, clockid, abstime,
 			      PTHREAD_MUTEX_PSHARED (mutex));
       break;
 
@@ -108,7 +107,7 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
       /* Don't record ownership */
       return lll_clocklock_elision (mutex->__data.__lock,
 				    mutex->__data.__spins,
-				    CLOCK_REALTIME, abstime,
+				    clockid, abstime,
 				    PTHREAD_MUTEX_PSHARED (mutex));
 
 
@@ -126,7 +125,7 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
 	      if (cnt++ >= max_cnt)
 		{
 		  result = lll_clocklock (mutex->__data.__lock,
-					  CLOCK_REALTIME, abstime,
+					  clockid, abstime,
 					  PTHREAD_MUTEX_PSHARED (mutex));
 		  break;
 		}
@@ -269,7 +268,7 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
 
 	  /* Block using the futex.  */
 	  int err = lll_futex_clock_wait_bitset (&mutex->__data.__lock,
-	      oldval, CLOCK_REALTIME, abstime,
+	      oldval, clockid, abstime,
 	      PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
 	  /* The futex call timed out.  */
 	  if (err == -ETIMEDOUT)
@@ -405,7 +404,7 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
 		    struct timespec reltime;
 		    struct timespec now;
 
-		    INTERNAL_SYSCALL (clock_gettime, __err, 2, CLOCK_REALTIME,
+		    INTERNAL_SYSCALL (clock_gettime, __err, 2, clockid,
 				      &now);
 		    reltime.tv_sec = abstime->tv_sec - now.tv_sec;
 		    reltime.tv_nsec = abstime->tv_nsec - now.tv_nsec;
@@ -623,4 +622,25 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
  out:
   return result;
 }
+
+int
+__pthread_mutex_clocklock (pthread_mutex_t *mutex,
+			   clockid_t clockid,
+			   const struct timespec *abstime)
+{
+  if (__glibc_unlikely (!lll_futex_supported_clockid (clockid)))
+    return EINVAL;
+
+  LIBC_PROBE (mutex_clocklock_entry, 3, mutex, clockid, abstime);
+  return __pthread_mutex_clocklock_common (mutex, clockid, abstime);
+}
+weak_alias (__pthread_mutex_clocklock, pthread_mutex_clocklock)
+
+int
+__pthread_mutex_timedlock (pthread_mutex_t *mutex,
+			   const struct timespec *abstime)
+{
+  LIBC_PROBE (mutex_timedlock_entry, 2, mutex, abstime);
+  return __pthread_mutex_clocklock_common (mutex, CLOCK_REALTIME, abstime);
+}
 weak_alias (__pthread_mutex_timedlock, pthread_mutex_timedlock)
diff --git a/nptl/tst-abstime.c b/nptl/tst-abstime.c
index c5040c5..30dea4d 100644
--- a/nptl/tst-abstime.c
+++ b/nptl/tst-abstime.c
@@ -36,6 +36,8 @@ th (void *arg)
   struct timespec t = { -2, 0 };
 
   TEST_COMPARE (pthread_mutex_timedlock (&m1, &t), ETIMEDOUT);
+  TEST_COMPARE (pthread_mutex_clocklock (&m1, CLOCK_REALTIME, &t), ETIMEDOUT);
+  TEST_COMPARE (pthread_mutex_clocklock (&m1, CLOCK_MONOTONIC, &t), ETIMEDOUT);
   TEST_COMPARE (pthread_rwlock_timedrdlock (&rw1, &t), ETIMEDOUT);
   TEST_COMPARE (pthread_rwlock_timedwrlock (&rw2, &t), ETIMEDOUT);
   TEST_COMPARE (pthread_rwlock_clockrdlock (&rw1, CLOCK_REALTIME, &t),
diff --git a/nptl/tst-mutex11.c b/nptl/tst-mutex11.c
new file mode 100644
index 0000000..91f4281
--- /dev/null
+++ b/nptl/tst-mutex11.c
@@ -0,0 +1,69 @@
+/* Test unsupported/bad clocks passed to pthread_mutex_clocklock.
+
+   Copyright (C) 2019 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <support/check.h>
+
+static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
+
+static void test_bad_clockid (clockid_t clockid)
+{
+  const struct timespec ts = {0,0};
+  TEST_COMPARE (pthread_mutex_clocklock (&mut, clockid, &ts), EINVAL);
+}
+
+#define NOT_A_VALID_CLOCK 123456
+
+static int
+do_test (void)
+{
+  /* These clocks are meaningless to pthread_mutex_clocklock. */
+#if defined(CLOCK_PROCESS_CPUTIME_ID)
+  test_bad_clockid (CLOCK_PROCESS_CPUTIME_ID);
+#endif
+#if defined(CLOCK_THREAD_CPUTIME_ID)
+  test_bad_clockid (CLOCK_PROCESS_CPUTIME_ID);
+#endif
+
+  /* These clocks might be meaningful, but are currently unsupported
+     by pthread_mutex_clocklock. */
+#if defined(CLOCK_REALTIME_COARSE)
+  test_bad_clockid (CLOCK_REALTIME_COARSE);
+#endif
+#if defined(CLOCK_MONOTONIC_RAW)
+  test_bad_clockid (CLOCK_MONOTONIC_RAW);
+#endif
+#if defined(CLOCK_MONOTONIC_COARSE)
+  test_bad_clockid (CLOCK_MONOTONIC_COARSE);
+#endif
+#if defined(CLOCK_BOOTTIME)
+  test_bad_clockid (CLOCK_BOOTTIME);
+#endif
+
+  /* This is a completely invalid clock. */
+  test_bad_clockid (NOT_A_VALID_CLOCK);
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/nptl/tst-mutex5.c b/nptl/tst-mutex5.c
index fb27152..838ef7f 100644
--- a/nptl/tst-mutex5.c
+++ b/nptl/tst-mutex5.c
@@ -32,12 +32,17 @@
 # define TYPE PTHREAD_MUTEX_NORMAL
 #endif
 
+/* A bogus clock value that tells run_test to use
+   pthread_mutex_timedlock rather than pthread_mutex_clocklock. */
+#define CLOCK_USE_TIMEDLOCK (-1)
 
 static int
-do_test (void)
+do_test_clock (clockid_t clockid, const char *fnname)
 {
   pthread_mutex_t m;
   pthread_mutexattr_t a;
+  const clockid_t clockid_for_get =
+    (clockid == CLOCK_USE_TIMEDLOCK) ? CLOCK_REALTIME : clockid;
 
   TEST_COMPARE (pthread_mutexattr_init (&a), 0);
   TEST_COMPARE (pthread_mutexattr_settype (&a, TYPE), 0);
@@ -62,16 +67,22 @@ do_test (void)
     FAIL_EXIT1 ("mutex_trylock succeeded");
 
   /* Wait 2 seconds.  */
-  struct timespec ts_timeout = timespec_add (xclock_now (CLOCK_REALTIME),
+  struct timespec ts_timeout = timespec_add (xclock_now (clockid_for_get),
                                              make_timespec (2, 0));
 
-  TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), ETIMEDOUT);
-  TEST_TIMESPEC_BEFORE_NOW (ts_timeout, CLOCK_REALTIME);
+  if (clockid == CLOCK_USE_TIMEDLOCK)
+    TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), ETIMEDOUT);
+  else
+    TEST_COMPARE (pthread_mutex_clocklock (&m, clockid, &ts_timeout), ETIMEDOUT);
+  TEST_TIMESPEC_BEFORE_NOW (ts_timeout, clockid_for_get);
 
   /* The following makes the ts value invalid.  */
   ts_timeout.tv_nsec += 1000000000;
 
-  TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), EINVAL);
+  if (clockid == CLOCK_USE_TIMEDLOCK)
+    TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), EINVAL);
+  else
+    TEST_COMPARE (pthread_mutex_clocklock (&m, clockid, &ts_timeout), EINVAL);
   TEST_COMPARE (pthread_mutex_unlock (&m), 0);
 
   const struct timespec ts_start = xclock_now (CLOCK_REALTIME);
@@ -79,9 +90,12 @@ do_test (void)
   /* Wait 2 seconds.  */
   ts_timeout = timespec_add (ts_start, make_timespec (2, 0));
 
-  TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), 0);
+  if (clockid == CLOCK_USE_TIMEDLOCK)
+    TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), 0);
+  else
+    TEST_COMPARE (pthread_mutex_clocklock (&m, clockid, &ts_timeout), 0);
 
-  const struct timespec ts_end = xclock_now (CLOCK_REALTIME);
+  const struct timespec ts_end = xclock_now (clockid_for_get);
 
   /* Check that timedlock didn't delay.  We use a limit of 0.1 secs.  */
   TEST_TIMESPEC_BEFORE (ts_end,
@@ -93,4 +107,12 @@ do_test (void)
   return 0;
 }
 
+static int do_test (void)
+{
+  do_test_clock (CLOCK_USE_TIMEDLOCK, "timedlock");
+  do_test_clock (CLOCK_REALTIME, "clocklock(realtime)");
+  do_test_clock (CLOCK_MONOTONIC, "clocklock(monotonic)");
+  return 0;
+}
+
 #include <support/test-driver.c>
diff --git a/nptl/tst-mutex9.c b/nptl/tst-mutex9.c
index e9fd8e2..c058d20 100644
--- a/nptl/tst-mutex9.c
+++ b/nptl/tst-mutex9.c
@@ -31,9 +31,15 @@
 #include <support/xunistd.h>
 
 
-static int
-do_test (void)
+/* A bogus clock value that tells run_test to use
+   pthread_mutex_timedlock rather than pthread_mutex_clocklock. */
+#define CLOCK_USE_TIMEDLOCK (-1)
+
+static void
+do_test_clock (clockid_t clockid)
 {
+  const clockid_t clockid_for_get =
+    (clockid == CLOCK_USE_TIMEDLOCK) ? CLOCK_REALTIME : clockid;
   size_t ps = sysconf (_SC_PAGESIZE);
   char tmpfname[] = "/tmp/tst-mutex9.XXXXXX";
   char data[ps];
@@ -95,10 +101,13 @@ do_test (void)
       if (pthread_mutex_unlock (m) == 0)
         FAIL_EXIT1 ("child: mutex_unlock succeeded");
 
-      const struct timespec ts = timespec_add (xclock_now (CLOCK_REALTIME),
+      const struct timespec ts = timespec_add (xclock_now (clockid_for_get),
                                                make_timespec (0, 500000000));
 
-      TEST_COMPARE (pthread_mutex_timedlock (m, &ts), ETIMEDOUT);
+      if (clockid == CLOCK_USE_TIMEDLOCK)
+        TEST_COMPARE (pthread_mutex_timedlock (m, &ts), ETIMEDOUT);
+      else
+        TEST_COMPARE (pthread_mutex_clocklock (m, clockid, &ts), ETIMEDOUT);
 
       alarm (1);
 
@@ -117,7 +126,14 @@ do_test (void)
   if (! WIFSIGNALED (status))
     FAIL_EXIT1 ("child not killed by signal");
   TEST_COMPARE (WTERMSIG (status), SIGALRM);
+}
 
+static int
+do_test (void)
+{
+  do_test_clock (CLOCK_USE_TIMEDLOCK);
+  do_test_clock (CLOCK_REALTIME);
+  do_test_clock (CLOCK_MONOTONIC);
   return 0;
 }
 
diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
index e78003e..a767d6f 100644
--- a/sysdeps/nptl/pthread.h
+++ b/sysdeps/nptl/pthread.h
@@ -770,6 +770,13 @@ extern int pthread_mutex_timedlock (pthread_mutex_t *__restrict __mutex,
 				    __abstime) __THROWNL __nonnull ((1, 2));
 #endif
 
+#ifdef __USE_GNU
+extern int pthread_mutex_clocklock (pthread_mutex_t *__restrict __mutex,
+				    clockid_t __clockid,
+				    const struct timespec *__restrict
+				    __abstime) __THROWNL __nonnull ((1, 3));
+#endif
+
 /* Unlock a mutex.  */
 extern int pthread_mutex_unlock (pthread_mutex_t *__mutex)
      __THROWNL __nonnull ((1));
diff --git a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
index 9f65baf..69f48bf 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
@@ -244,6 +244,7 @@ GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
index 0709855..d1d53cf 100644
--- a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
@@ -228,6 +228,7 @@ GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/arm/libpthread.abilist b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
index a2be572..3d2287b 100644
--- a/sysdeps/unix/sysv/linux/arm/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
@@ -28,6 +28,7 @@ GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/csky/libpthread.abilist b/sysdeps/unix/sysv/linux/csky/libpthread.abilist
index c3a1834..52373fc 100644
--- a/sysdeps/unix/sysv/linux/csky/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libpthread.abilist
@@ -234,6 +234,7 @@ GLIBC_2.29 wait F
 GLIBC_2.29 waitpid F
 GLIBC_2.29 write F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
index 2a00ebc..d11e150 100644
--- a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
@@ -246,6 +246,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/i386/libpthread.abilist b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
index 4479947..1b385ca 100644
--- a/sysdeps/unix/sysv/linux/i386/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
@@ -254,6 +254,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
index 40a1faf..bde9948 100644
--- a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
@@ -248,6 +248,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
index a2be572..3d2287b 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
@@ -28,6 +28,7 @@ GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
index 4479947..1b385ca 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
@@ -254,6 +254,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
index 254b708..f0365f3 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
@@ -244,6 +244,7 @@ GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
index 29ffdd1..b1dff8e 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
@@ -256,6 +256,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
index 29ffdd1..b1dff8e 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
@@ -256,6 +256,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
index 3fae328..0150ea3 100644
--- a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
@@ -242,6 +242,7 @@ GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
index a90010d..9e71e17 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
@@ -256,6 +256,7 @@ GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.3.4 siglongjmp F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
index 339eab8..393ec87 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
@@ -247,6 +247,7 @@ GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.3.4 siglongjmp F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
index 9f65baf..69f48bf 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
@@ -244,6 +244,7 @@ GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
index 83082fb..7dab4e5 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
@@ -236,6 +236,7 @@ GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
index 54e937b..7db2a0c 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
@@ -256,6 +256,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
index 87f978b..7c10bb2 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
@@ -248,6 +248,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/sh/libpthread.abilist b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
index 2a00ebc..d11e150 100644
--- a/sysdeps/unix/sysv/linux/sh/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
@@ -246,6 +246,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
index bc29a66..7aa6416 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
@@ -256,6 +256,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
index 40a1faf..bde9948 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
@@ -248,6 +248,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
index 70f04cc..c5ecb12 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
@@ -246,6 +246,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
 GLIBC_2.3.4 pthread_setaffinity_np F
 GLIBC_2.3.4 pthread_setschedprio F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
index 92cd2f4..a7ff3fb 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
@@ -244,6 +244,7 @@ GLIBC_2.28 tss_delete F
 GLIBC_2.28 tss_get F
 GLIBC_2.28 tss_set F
 GLIBC_2.30 pthread_cond_clockwait F
+GLIBC_2.30 pthread_mutex_clocklock F
 GLIBC_2.30 pthread_rwlock_clockrdlock F
 GLIBC_2.30 pthread_rwlock_clockwrlock F
 GLIBC_2.30 sem_clockwait F
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v4 11/12] Update NEWS for new _clockwait and _clocklock functions
  2019-06-18 16:33 [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions Mike Crowe
                   ` (9 preceding siblings ...)
  2019-06-18 16:33 ` [PATCH v4 10/12] nptl: Add POSIX-proposed pthread_mutex_clocklock Mike Crowe
@ 2019-06-18 16:33 ` Mike Crowe
  2019-06-25 22:01   ` Adhemerval Zanella
  2019-06-18 16:33 ` [PATCH v4 12/12] nptl: Remove futex_supports_exact_relative_timeouts Mike Crowe
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 32+ messages in thread
From: Mike Crowe @ 2019-06-18 16:33 UTC (permalink / raw
  To: libc-alpha; +Cc: Mike Crowe

* NEWS: Mention recently-added pthread_cond_clockwait,
	pthread_mutex_clocklock, pthread_rwlock_clockrdlock,
	pthread_rwlock_clockwrlock and sem_clockwait functions.
---
 ChangeLog |  6 ++++++
 NEWS      |  9 +++++++++
 2 files changed, 15 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index a213eb1..984275c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2019-05-27  Mike Crowe  <mac@mcrowe.com>
+
+	* NEWS: Mention recently-added pthread_cond_clockwait,
+	pthread_rwlock_clockrdlock, pthread_rwlock_clockwrlock and
+	sem_clockwait functions.
+
 2019-05-31  Mike Crowe  <mac@mcrowe.com>
 
 	nptl: Add POSIX-proposed pthread_mutex_clocklock function that
diff --git a/NEWS b/NEWS
index 8a2fece..653a69d 100644
--- a/NEWS
+++ b/NEWS
@@ -34,6 +34,15 @@ Major new features:
   pointer subtraction within the allocated object, where results might
   overflow the ptrdiff_t type.
 
+* Add new POSIX-proposed pthread_cond_clockwait, pthread_mutex_clocklock,
+  pthread_rwlock_clockrdlock, pthread_rwlock_clockwrlock and sem_clockwait
+  functions. These behave similarly to their "timed" equivalents, but also
+  accept a clockid_t parameter to determine which clock their timeout should
+  be measured against. All functions allow waiting against CLOCK_MONOTONIC
+  and CLOCK_REALTIME. The decision of which clock to be used is made at the
+  time of the wait (unlike with pthread_condattr_setclock, which requires
+  the clock choice at initialization time.)
+
 Deprecated and removed features, and other changes affecting compatibility:
 
 * The functions clock_gettime, clock_getres, clock_settime,
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH v4 12/12] nptl: Remove futex_supports_exact_relative_timeouts
  2019-06-18 16:33 [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions Mike Crowe
                   ` (10 preceding siblings ...)
  2019-06-18 16:33 ` [PATCH v4 11/12] Update NEWS for new _clockwait and _clocklock functions Mike Crowe
@ 2019-06-18 16:33 ` Mike Crowe
  2019-06-25 22:09   ` Adhemerval Zanella
  2019-06-19 19:33 ` [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions Adhemerval Zanella
  2019-06-25 22:13 ` Adhemerval Zanella
  13 siblings, 1 reply; 32+ messages in thread
From: Mike Crowe @ 2019-06-18 16:33 UTC (permalink / raw
  To: libc-alpha; +Cc: Mike Crowe

The only implementation of futex_supports_exact_relative_timeouts always
returns true. Let's remove it and all its callers.

* nptl/pthread_cond_wait.c: (__pthread_cond_clockwait): Remove code that is
  only useful if futex_supports_exact_relative_timeouts () returns false.

* nptl/pthread_condattr_setclock.c: (pthread_condattr_setclock): Likewise.

* sysdeps/nptl/futex-internal.h: Remove comment about relative timeouts
  potentially being imprecise since it's no longer true. Remove declaration
  of futex_supports_exact_relative_timeouts.

* sysdeps/unix/sysv/linux/futex-internal.h: Remove implementation of
  futex_supports_exact_relative_timeouts.
---
 ChangeLog                                | 13 +++++++++++++
 nptl/pthread_cond_wait.c                 |  5 -----
 nptl/pthread_condattr_setclock.c         |  5 -----
 sysdeps/nptl/futex-internal.h            |  9 +--------
 sysdeps/unix/sysv/linux/futex-internal.h |  8 --------
 5 files changed, 14 insertions(+), 26 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 984275c..cf07e4d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2019-06-18  Mike Crowe  <mac@mcrowe.com>
+
+	* nptl/pthread_cond_wait.c: (__pthread_cond_clockwait): Remove code
+	that is only useful if futex_supports_exact_relative_timeouts ()
+	returns false.
+	* nptl/pthread_condattr_setclock.c: (pthread_condattr_setclock):
+	Likewise.
+	* sysdeps/nptl/futex-internal.h: Remove comment about relative
+	timeouts potentially being imprecise since it's no longer true.
+	Remove declaration of futex_supports_exact_relative_timeouts.
+	* sysdeps/unix/sysv/linux/futex-internal.h: Remove implementation
+	of futex_supports_exact_relative_timeouts.
+
 2019-05-27  Mike Crowe  <mac@mcrowe.com>
 
 	* NEWS: Mention recently-added pthread_cond_clockwait,
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
index 558f930..cd98f50 100644
--- a/nptl/pthread_cond_wait.c
+++ b/nptl/pthread_cond_wait.c
@@ -670,11 +670,6 @@ __pthread_cond_clockwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
   if (!futex_abstimed_supported_clockid (clockid))
     return EINVAL;
 
-  /* If we do not support waiting using CLOCK_MONOTONIC, return an error.  */
-  if (clockid == CLOCK_MONOTONIC
-      && !futex_supports_exact_relative_timeouts ())
-    return EINVAL;
-
   return __pthread_cond_wait_common (cond, mutex, clockid, abstime);
 }
 
diff --git a/nptl/pthread_condattr_setclock.c b/nptl/pthread_condattr_setclock.c
index 641a041..ac91923 100644
--- a/nptl/pthread_condattr_setclock.c
+++ b/nptl/pthread_condattr_setclock.c
@@ -33,11 +33,6 @@ pthread_condattr_setclock (pthread_condattr_t *attr, clockid_t clock_id)
        in the pthread_cond_t structure needs to be adjusted.  */
     return EINVAL;
 
-  /* If we do not support waiting using CLOCK_MONOTONIC, return an error.  */
-  if (clock_id == CLOCK_MONOTONIC
-      && !futex_supports_exact_relative_timeouts())
-    return ENOTSUP;
-
   /* Make sure the value fits in the bits we reserved.  */
   assert (clock_id < (1 << COND_CLOCK_BITS));
 
diff --git a/sysdeps/nptl/futex-internal.h b/sysdeps/nptl/futex-internal.h
index bc29bdb..9baae38 100644
--- a/sysdeps/nptl/futex-internal.h
+++ b/sysdeps/nptl/futex-internal.h
@@ -51,8 +51,7 @@
    Both absolute and relative timeouts can be used.  An absolute timeout
    expires when the given specific point in time on the specified clock
    passes, or when it already has passed.  A relative timeout expires when
-   the given duration of time on the CLOCK_MONOTONIC clock passes.  Relative
-   timeouts may be imprecise (see futex_supports_exact_relative_timeouts).
+   the given duration of time on the CLOCK_MONOTONIC clock passes.
 
    Due to POSIX requirements on when synchronization data structures such
    as mutexes or semaphores can be destroyed and due to the futex design
@@ -81,12 +80,6 @@
 static __always_inline int
 futex_supports_pshared (int pshared);
 
-/* Returns true if relative timeouts are robust to concurrent changes to the
-   system clock.  If this returns false, relative timeouts can still be used
-   but might be effectively longer or shorter than requested.  */
-static __always_inline bool
-futex_supports_exact_relative_timeouts (void);
-
 /* Atomically wrt other futex operations on the same futex, this blocks iff
    the value *FUTEX_WORD matches the expected value.  This is
    semantically equivalent to:
diff --git a/sysdeps/unix/sysv/linux/futex-internal.h b/sysdeps/unix/sysv/linux/futex-internal.h
index 03312d6..30707e7 100644
--- a/sysdeps/unix/sysv/linux/futex-internal.h
+++ b/sysdeps/unix/sysv/linux/futex-internal.h
@@ -46,14 +46,6 @@ futex_supports_pshared (int pshared)
     return EINVAL;
 }
 
-/* The Linux kernel supports relative timeouts measured against the
-   CLOCK_MONOTONIC clock.  */
-static __always_inline bool
-futex_supports_exact_relative_timeouts (void)
-{
-  return true;
-}
-
 /* See sysdeps/nptl/futex-internal.h for details.  */
 static __always_inline int
 futex_wait (unsigned int *futex_word, unsigned int expected, int private)
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions
  2019-06-18 16:33 [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions Mike Crowe
                   ` (11 preceding siblings ...)
  2019-06-18 16:33 ` [PATCH v4 12/12] nptl: Remove futex_supports_exact_relative_timeouts Mike Crowe
@ 2019-06-19 19:33 ` Adhemerval Zanella
  2019-06-22 21:11   ` Mike Crowe
  2019-06-25 22:13 ` Adhemerval Zanella
  13 siblings, 1 reply; 32+ messages in thread
From: Adhemerval Zanella @ 2019-06-19 19:33 UTC (permalink / raw
  To: libc-alpha



On 18/06/2019 13:33, Mike Crowe wrote:
> The changes have been tested with "make check" and "make check-abi" on
> x86, x86_64, arm and arm64. I've attempted to update the abilists for
> all architectures, but cannot test all of them.

You can build compiler and glibcs using build-many-glibcs.py for all current
supported targets and update automatically using the update-abi make rule
inside the build directory. This can be run in cross-compile build.

> 
> I've compile-tested the powerpc and s390-specific implementations of
> lll_clockwait. Although I've updated the sparc32-specific
> implementation, I have been unable to test it since it appears that
> even Debian hasn't supported sparc32 for nearly twenty years! I was
> able to compile-test sparc64 though.

The gcc farm provides sparc64 machines with Debian 10 installed where
you can test 32-bit build against it. The kernel will run in compat
mode, similar to what i686 run in a x86_64 kernel. 

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v4 01/12] support: Add xclock_now helper function.
  2019-06-18 16:33 ` [PATCH v4 01/12] support: Add xclock_now helper function Mike Crowe
@ 2019-06-19 20:01   ` Adhemerval Zanella
  0 siblings, 0 replies; 32+ messages in thread
From: Adhemerval Zanella @ 2019-06-19 20:01 UTC (permalink / raw
  To: libc-alpha



On 18/06/2019 13:33, Mike Crowe wrote:
> It's easier to read and write tests with:
> 
>  const struct timespec ts = xclock_now(CLOCK_REALTIME);
> 
> than
> 
>  struct timespec ts;
>  xclock_gettime(CLOCK_REALTIME, &ts);
> 
> * support/xtime.h: Add xclock_now() helper function.

LGTM, I will commit for you.

> ---
>  ChangeLog       |  4 ++++
>  support/xtime.h | 10 ++++++++++
>  2 files changed, 14 insertions(+)
> 
> diff --git a/ChangeLog b/ChangeLog
> index 7401f9f..17fd6ac 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,3 +1,7 @@
> +2019-05-30  Mike Crowe  <mac@mcrowe.com>
> +
> +	* support/xtime.h: Add xclock_now() helper function.
> +
>  2019-06-17  Rafal Luzynski  <digitalfreak@lingonborough.com>
>  
>  	[BZ #24614]
> diff --git a/support/xtime.h b/support/xtime.h
> index 68af1a5..6e19ce1 100644
> --- a/support/xtime.h
> +++ b/support/xtime.h
> @@ -28,6 +28,16 @@ __BEGIN_DECLS
>  
>  void xclock_gettime (clockid_t clock, struct timespec *ts);
>  
> +/* This helper can often simplify tests by avoiding an explicit
> +   variable declaration or allowing that declaration to be const. */
> +
> +static inline struct timespec xclock_now (clockid_t clock)
> +{
> +  struct timespec ts;
> +  xclock_gettime (clock, &ts);
> +  return ts;
> +}
> +
>  __END_DECLS
>  
>  #endif /* SUPPORT_TIME_H */
> 

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v4 02/12] support: Invent verbose_printf macro
  2019-06-18 16:33 ` [PATCH v4 02/12] support: Invent verbose_printf macro Mike Crowe
@ 2019-06-19 20:15   ` Adhemerval Zanella
  0 siblings, 0 replies; 32+ messages in thread
From: Adhemerval Zanella @ 2019-06-19 20:15 UTC (permalink / raw
  To: libc-alpha



On 18/06/2019 13:33, Mike Crowe wrote:
> Make it easier for tests to emit progress messages only when --verbose is
> specified.
> 
> * support/test-driver.h: Add verbose_printf macro.

LGTM, I will commit for you.

> ---
>  ChangeLog             | 4 ++++
>  support/test-driver.h | 8 ++++++++
>  2 files changed, 12 insertions(+)
> 
> diff --git a/ChangeLog b/ChangeLog
> index 17fd6ac..6943d5e 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,3 +1,7 @@
> +2019-06-18  Mike Crowe <mac@mcrowe.com>
> +
> +	* support/test-driver.h: Add verbose_printf macro.
> +
>  2019-05-30  Mike Crowe  <mac@mcrowe.com>
>  
>  	* support/xtime.h: Add xclock_now() helper function.
> diff --git a/support/test-driver.h b/support/test-driver.h
> index a9710af..55f355f 100644
> --- a/support/test-driver.h
> +++ b/support/test-driver.h
> @@ -69,6 +69,14 @@ extern const char *test_dir;
>     tests.  */
>  extern unsigned int test_verbose;
>  
> +/* Output that is only emitted if at least one --verbose argument was
> +   specified. */
> +#define verbose_printf(...)                      \
> +  do {                                           \
> +    if (test_verbose > 0)                        \
> +      printf (__VA_ARGS__);                      \
> +  } while (0);
> +
>  int support_test_main (int argc, char **argv, const struct test_config *);
>  
>  __END_DECLS
> 

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v4 03/12] nptl: Convert various tests to use libsupport
  2019-06-18 16:33 ` [PATCH v4 03/12] nptl: Convert various tests to use libsupport Mike Crowe
@ 2019-06-19 20:33   ` Adhemerval Zanella
  0 siblings, 0 replies; 32+ messages in thread
From: Adhemerval Zanella @ 2019-06-19 20:33 UTC (permalink / raw
  To: libc-alpha



On 18/06/2019 13:33, Mike Crowe wrote:
> * nptl/eintr.c: Use libsupport.
> * nptl/tst-eintr1.c: Use libsupport.
> * nptl/tst-eintr2.c: Use libsupport.
> * nptl/tst-eintr3.c: Use libsupport.
> * nptl/tst-eintr4.c: Use libsupport.
> * nptl/tst-eintr5.c: Use libsupport.
> * nptl/tst-mutex-errorcheck.c: Use libsupport.
> * nptl/tst-mutex5.c: Use libsupport.

LGTM, I will commit it for you.

> ---
>  ChangeLog                   |  12 +++-
>  nptl/eintr.c                |  12 +--
>  nptl/tst-eintr1.c           |  52 +-----------
>  nptl/tst-eintr2.c           |  60 +++-----------
>  nptl/tst-eintr3.c           |  23 +----
>  nptl/tst-eintr4.c           |  15 +--
>  nptl/tst-eintr5.c           |  40 ++-------
>  nptl/tst-mutex-errorcheck.c |  29 ++-----
>  nptl/tst-mutex5.c           | 164 ++++++-------------------------------
>  nptl/tst-mutex9.c           | 131 ++++++------------------------
>  10 files changed, 129 insertions(+), 409 deletions(-)
> 
> diff --git a/ChangeLog b/ChangeLog
> index 6943d5e..e6b36b5 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,3 +1,15 @@
> +2019-05-30  Mike Crowe  <mac@mcrowe.com>
> +
> +	* nptl/eintr.c: Use libsupport.
> +	* nptl/tst-eintr1.c: Use libsupport.
> +	* nptl/tst-eintr2.c: Use libsupport.
> +	* nptl/tst-eintr3.c: Use libsupport.
> +	* nptl/tst-eintr4.c: Use libsupport.
> +	* nptl/tst-eintr5.c: Use libsupport.
> +	* nptl/tst-mutex-errorcheck.c: Use libsupport.
> +	* nptl/tst-mutex5.c: Use libsupport.
> +	* nptl/tst-mutex9.c: Use libsupport.
> +
>  2019-06-18  Mike Crowe <mac@mcrowe.com>
>  
>  	* support/test-driver.h: Add verbose_printf macro.
> diff --git a/nptl/eintr.c b/nptl/eintr.c
> index 4fc4d1c..6e644d2 100644
> --- a/nptl/eintr.c
> +++ b/nptl/eintr.c
> @@ -19,6 +19,9 @@
>  #include <pthread.h>
>  #include <signal.h>
>  #include <unistd.h>
> +#include <support/xthread.h>
> +#include <support/xsignal.h>
> +#include <support/xthread.h>
>  
>  
>  static int the_sig;
> @@ -46,7 +49,7 @@ eintr_source (void *arg)
>        sigset_t ss;
>        sigemptyset (&ss);
>        sigaddset (&ss, the_sig);
> -      pthread_sigmask (SIG_BLOCK, &ss, NULL);
> +      xpthread_sigmask (SIG_BLOCK, &ss, NULL);
>      }
>  
>    while (1)

Ok.

> @@ -79,10 +82,5 @@ setup_eintr (int sig, pthread_t *thp)
>    the_sig = sig;
>  
>    /* Create the thread which will fire off the signals.  */
> -  pthread_t th;
> -  if (pthread_create (&th, NULL, eintr_source, thp) != 0)
> -    {
> -      puts ("setup_eintr: pthread_create failed");
> -      exit (1);
> -    }
> +  xpthread_create (NULL, eintr_source, thp);
>  }

Ok.

> diff --git a/nptl/tst-eintr1.c b/nptl/tst-eintr1.c
> index 8134f0a..b60b796 100644
> --- a/nptl/tst-eintr1.c
> +++ b/nptl/tst-eintr1.c
> @@ -22,11 +22,8 @@
>  #include <stdio.h>
>  #include <stdlib.h>
>  #include <string.h>
> -
> -static int do_test (void);
> -
> -#define TEST_FUNCTION do_test ()
> -#include "../test-skeleton.c"
> +#include <support/check.h>
> +#include <support/xthread.h>
>  
>  #include "eintr.c"
>  
> @@ -43,37 +40,8 @@ tf1 (void *arg)
>  {
>    while (1)
>      {
> -      pthread_t th;
> -
> -      int e = pthread_create (&th, NULL, tf2, NULL);
> -      if (e != 0)
> -	{
> -	  if (e == EINTR)
> -	    {
> -	      puts ("pthread_create returned EINTR");
> -	      exit (1);
> -	    }
> -
> -	  char buf[100];
> -	  printf ("tf1: pthread_create failed: %s\n",
> -		  strerror_r (e, buf, sizeof (buf)));
> -	  exit (1);
> -	}
> -
> -      e = pthread_join (th, NULL);
> -      if (e != 0)
> -	{
> -	  if (e == EINTR)
> -	    {
> -	      puts ("pthread_join returned EINTR");
> -	      exit (1);
> -	    }
> -
> -	  char buf[100];
> -	  printf ("tf1: pthread_join failed: %s\n",
> -		  strerror_r (e, buf, sizeof (buf)));
> -	  exit (1);
> -	}
> +      pthread_t th = xpthread_create (NULL, tf2, NULL);
> +      xpthread_join (th);
>      }
>  }
>  

Ok, the %m from xpthread_check_return should give enough information to debug it. 

> @@ -86,15 +54,7 @@ do_test (void)
>    int i;
>    for (i = 0; i < 10; ++i)
>      {
> -      pthread_t th;
> -      int e = pthread_create (&th, NULL, tf1, NULL);
> -      if (e != 0)
> -	{
> -	  char buf[100];
> -	  printf ("main: pthread_create failed: %s\n",
> -		  strerror_r (e, buf, sizeof (buf)));
> -	  exit (1);
> -	}
> +      pthread_t th = xpthread_create (NULL, tf1, NULL);
>      }
>  
>    delayed_exit (3);
> @@ -102,3 +62,5 @@ do_test (void)
>    (void) tf1 (NULL);
>    return 1;
>  }
> +
> +#include <support/test-driver.c>

Ok.

> diff --git a/nptl/tst-eintr2.c b/nptl/tst-eintr2.c
> index 12e2715..c78c19a 100644
> --- a/nptl/tst-eintr2.c
> +++ b/nptl/tst-eintr2.c
> @@ -23,11 +23,9 @@
>  #include <stdlib.h>
>  #include <string.h>
>  #include <sys/time.h>
> -
> -static int do_test (void);
> -
> -#define TEST_FUNCTION do_test ()
> -#include "../test-skeleton.c"
> +#include <support/check.h>
> +#include <support/timespec.h>
> +#include <support/xtime.h>
>  
>  #include "eintr.c"
>  

Ok.

> @@ -39,12 +37,8 @@ static pthread_mutex_t m2 = PTHREAD_MUTEX_INITIALIZER;
>  static void *
>  tf1 (void *arg)
>  {
> -  struct timespec ts;
> -  struct timeval tv;
> -
> -  gettimeofday (&tv, NULL);
> -  TIMEVAL_TO_TIMESPEC (&tv, &ts);
> -  ts.tv_sec += 10000;
> +  struct timespec ts = timespec_add (xclock_now (CLOCK_REALTIME),
> +                                     make_timespec (10000, 0));
>  
>    /* This call must never return.  */
>    int e = pthread_mutex_timedlock (&m1, &ts);

Ok.

> @@ -61,58 +55,34 @@ tf2 (void *arg)
>  {
>    while (1)
>      {
> -      int e = pthread_mutex_lock (&m2);
> -      if (e != 0)
> -	{
> -	  puts ("tf2: mutex_lock failed");
> -	  exit (1);
> -	}
> -      e = pthread_mutex_unlock (&m2);
> -      if (e != 0)
> -	{
> -	  puts ("tf2: mutex_unlock failed");
> -	  exit (1);
> -	}
> +      TEST_COMPARE (pthread_mutex_lock (&m2), 0);
> +      TEST_COMPARE (pthread_mutex_unlock (&m2), 0);
> +
>        struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 };
>        nanosleep (&ts, NULL);
>      }
> +  return NULL;
>  }
>  
>  

Ok.

>  static int
>  do_test (void)
>  {
> -  if (pthread_mutex_lock (&m1) != 0)
> -    {
> -      puts ("mutex_lock failed");
> -      exit (1);
> -    }
> +  TEST_COMPARE (pthread_mutex_lock (&m1), 0);
>  
>    setup_eintr (SIGUSR1, NULL);
>  
> -  pthread_t th;
>    char buf[100];
> -  int e = pthread_create (&th, NULL, tf1, NULL);
> -  if (e != 0)
> -    {
> -      printf ("main: 1st pthread_create failed: %s\n",
> -	      strerror_r (e, buf, sizeof (buf)));
> -      exit (1);
> -    }
> -
> -  e = pthread_create (&th, NULL, tf2, NULL);
> -  if (e != 0)
> -    {
> -      printf ("main: 2nd pthread_create failed: %s\n",
> -	      strerror_r (e, buf, sizeof (buf)));
> -      exit (1);
> -    }
> +  xpthread_create (NULL, tf1, NULL);
> +  xpthread_create (NULL, tf2, NULL);
>  
>    delayed_exit (3);
>    /* This call must never return.  */
> -  e = pthread_mutex_lock (&m1);
> +  int e = pthread_mutex_lock (&m1);
>    printf ("main: mutex_lock returned: %s\n",
>  	  strerror_r (e, buf, sizeof (buf)));
>  
>    return 1;
>  }
> +
> +#include <support/test-driver.c>

Ok.

> diff --git a/nptl/tst-eintr3.c b/nptl/tst-eintr3.c
> index d6c4e2b..0562eba 100644
> --- a/nptl/tst-eintr3.c
> +++ b/nptl/tst-eintr3.c
> @@ -22,11 +22,8 @@
>  #include <stdio.h>
>  #include <stdlib.h>
>  #include <string.h>
> -
> -static int do_test (void);
> -
> -#define TEST_FUNCTION do_test ()
> -#include "../test-skeleton.c"
> +#include <support/check.h>
> +#include <support/xthread.h>
>  
>  #include "eintr.c"
>  

Ok.

> @@ -35,9 +32,9 @@ static void *
>  tf (void *arg)
>  {
>    pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
> -  pthread_mutex_lock (&m);
> +  xpthread_mutex_lock (&m);
>    /* This call must not return.  */
> -  pthread_mutex_lock (&m);
> +  xpthread_mutex_lock (&m);
>  
>    puts ("tf: mutex_lock returned");
>    exit (1);

Ok.

> @@ -51,15 +48,7 @@ do_test (void)
>  
>    setup_eintr (SIGUSR1, &self);
>  
> -  pthread_t th;
> -  char buf[100];
> -  int e = pthread_create (&th, NULL, tf, NULL);
> -  if (e != 0)
> -    {
> -      printf ("main: pthread_create failed: %s\n",
> -	      strerror_r (e, buf, sizeof (buf)));
> -      exit (1);
> -    }
> +  pthread_t th = xpthread_create (NULL, tf, NULL);
>  
>    delayed_exit (1);
>    /* This call must never return.  */
> @@ -67,3 +56,5 @@ do_test (void)
>    puts ("error: pthread_join returned");
>    return 1;
>  }
> +
> +#include <support/test-driver.c>

Ok.

> diff --git a/nptl/tst-eintr4.c b/nptl/tst-eintr4.c
> index 2d9b299..1f4b711 100644
> --- a/nptl/tst-eintr4.c
> +++ b/nptl/tst-eintr4.c
> @@ -22,11 +22,8 @@
>  #include <stdio.h>
>  #include <stdlib.h>
>  #include <string.h>
> -
> -static int do_test (void);
> -
> -#define TEST_FUNCTION do_test ()
> -#include "../test-skeleton.c"
> +#include <support/check.h>
> +#include <support/xthread.h>
>  
>  #include "eintr.c"
>  

Ok.

> @@ -39,11 +36,7 @@ do_test (void)
>    setup_eintr (SIGUSR1, &self);
>  
>    pthread_barrier_t b;
> -  if (pthread_barrier_init (&b, NULL, 2) != 0)
> -    {
> -      puts ("barrier_init failed");
> -      exit (1);
> -    }
> +  xpthread_barrier_init (&b, NULL, 2);
>  
>    delayed_exit (1);
>    /* This call must never return.  */
> @@ -51,3 +44,5 @@ do_test (void)
>    puts ("error: pthread_barrier_wait returned");
>    return 1;
>  }
> +
> +#include <support/test-driver.c>

Ok.

> diff --git a/nptl/tst-eintr5.c b/nptl/tst-eintr5.c
> index 6eee2a1..da049c4 100644
> --- a/nptl/tst-eintr5.c
> +++ b/nptl/tst-eintr5.c
> @@ -23,11 +23,10 @@
>  #include <stdlib.h>
>  #include <string.h>
>  #include <sys/time.h>
> -
> -static int do_test (void);
> -
> -#define TEST_FUNCTION do_test ()
> -#include "../test-skeleton.c"
> +#include <support/check.h>
> +#include <support/timespec.h>
> +#include <support/xthread.h>
> +#include <support/xtime.h>
>  
>  #include "eintr.c"
>  

Ok.

> @@ -39,20 +38,12 @@ static pthread_cond_t c = PTHREAD_COND_INITIALIZER;
>  static void *
>  tf (void *arg)
>  {
> -  struct timespec ts;
> -  struct timeval tv;
> -
> -  gettimeofday (&tv, NULL);
> -  TIMEVAL_TO_TIMESPEC (&tv, &ts);
> -  ts.tv_sec += 10000;
> +  struct timespec ts = timespec_add (xclock_now (CLOCK_REALTIME),
> +                                     make_timespec (10000, 0));
>  
>    /* This call must never return.  */
> -  int e = pthread_cond_timedwait (&c, &m, &ts);
> -  char buf[100];
> -  printf ("tf: cond_timedwait returned: %s\n",
> -	  strerror_r (e, buf, sizeof (buf)));
> -
> -  exit (1);
> +  TEST_COMPARE (pthread_cond_timedwait (&c, &m, &ts), 0);
> +  FAIL_EXIT1 ("pthread_cond_timedwait returned unexpectedly\n");
>  }
>  

Ok.

>  
> @@ -61,19 +52,12 @@ do_test (void)
>  {
>    setup_eintr (SIGUSR1, NULL);
>  
> -  pthread_t th;
> -  char buf[100];
> -  int e = pthread_create (&th, NULL, tf, NULL);
> -  if (e != 0)
> -    {
> -      printf ("main: pthread_create failed: %s\n",
> -	      strerror_r (e, buf, sizeof (buf)));
> -      exit (1);
> -    }
> +  xpthread_create (NULL, tf, NULL);
>  
>    delayed_exit (3);
>    /* This call must never return.  */
>    xpthread_cond_wait (&c, &m);
> -  puts ("error: pthread_cond_wait returned");
> -  return 1;
> +  FAIL_RET ("error: pthread_cond_wait returned");
>  }
> +
> +#include <support/test-driver.c>

Ok.

> diff --git a/nptl/tst-mutex-errorcheck.c b/nptl/tst-mutex-errorcheck.c
> index 30ff7ea..afc27e7 100644
> --- a/nptl/tst-mutex-errorcheck.c
> +++ b/nptl/tst-mutex-errorcheck.c
> @@ -20,6 +20,7 @@
>  #include <errno.h>
>  #include <time.h>
>  #include <pthread.h>
> +#include <support/check.h>
>  
>  static int
>  do_test (void)
> @@ -29,33 +30,23 @@ do_test (void)
>    pthread_mutexattr_t mutexattr;
>    int ret = 0;
>  
> -  if (pthread_mutexattr_init (&mutexattr) != 0)
> -    return 1;
> -  if (pthread_mutexattr_settype (&mutexattr, PTHREAD_MUTEX_ERRORCHECK) != 0)
> -    return 1;
> +  TEST_COMPARE (pthread_mutexattr_init (&mutexattr), 0);
> +  TEST_COMPARE (pthread_mutexattr_settype (&mutexattr,
> +                                           PTHREAD_MUTEX_ERRORCHECK), 0);
>  
> -  if (pthread_mutex_init (&mutex, &mutexattr) != 0)
> -    return 1;
> -  if (pthread_mutexattr_destroy (&mutexattr) != 0)
> -    return 1;
> +  TEST_COMPARE (pthread_mutex_init (&mutex, &mutexattr), 0);
> +  TEST_COMPARE (pthread_mutexattr_destroy (&mutexattr), 0);
>  
>    /* The call to pthread_mutex_timedlock erroneously enabled lock elision
>       on the mutex, which then triggered an assertion failure in
>       pthread_mutex_unlock.  It would also defeat the error checking nature
>       of the mutex.  */
> -  if (pthread_mutex_timedlock (&mutex, &tms) != 0)
> -    return 1;
> -  if (pthread_mutex_timedlock (&mutex, &tms) != EDEADLK)
> -    {
> -      printf ("Failed error checking on locked mutex\n");
> -      ret = 1;
> -    }
> +  TEST_COMPARE (pthread_mutex_timedlock (&mutex, &tms), 0);
> +  TEST_COMPARE (pthread_mutex_timedlock (&mutex, &tms), EDEADLK);
>  
> -  if (pthread_mutex_unlock (&mutex) != 0)
> -    ret = 1;
> +  TEST_COMPARE (pthread_mutex_unlock (&mutex), 0);
>  
>    return ret;
>  }
>  
> -#define TEST_FUNCTION do_test ()
> -#include "../test-skeleton.c"
> +#include <support/test-driver.c>

Ok.

> diff --git a/nptl/tst-mutex5.c b/nptl/tst-mutex5.c
> index 4e1d93b..fb27152 100644
> --- a/nptl/tst-mutex5.c
> +++ b/nptl/tst-mutex5.c
> @@ -24,6 +24,8 @@
>  #include <sys/time.h>
>  #include <stdint.h>
>  #include <config.h>
> +#include <support/check.h>
> +#include <support/timespec.h>
>  
>  
>  #ifndef TYPE
> @@ -35,168 +37,60 @@ static int
>  do_test (void)
>  {
>    pthread_mutex_t m;
> -  struct timespec ts;
> -  struct timeval tv;
> -  struct timeval tv2;
> -  int err;
>    pthread_mutexattr_t a;
>  
> -  if (pthread_mutexattr_init (&a) != 0)
> -    {
> -      puts ("mutexattr_init failed");
> -      return 1;
> -    }
> -
> -  if (pthread_mutexattr_settype (&a, TYPE) != 0)
> -    {
> -      puts ("mutexattr_settype failed");
> -      return 1;
> -    }
> +  TEST_COMPARE (pthread_mutexattr_init (&a), 0);
> +  TEST_COMPARE (pthread_mutexattr_settype (&a, TYPE), 0);
>  
>  #ifdef ENABLE_PI
> -  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
> -    {
> -      puts ("pthread_mutexattr_setprotocol failed");
> -      return 1;
> -    }
> +  TEST_COMPARE (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT), 0);
>  #endif
>  

Ok.

> -  err = pthread_mutex_init (&m, &a);
> +  int err = pthread_mutex_init (&m, &a);
>    if (err != 0)
>      {
>  #ifdef ENABLE_PI
>        if (err == ENOTSUP)
> -	{
> -	  puts ("PI mutexes unsupported");
> -	  return 0;
> -	}
> +        FAIL_UNSUPPORTED ("PI mutexes unsupported");
>  #endif
> -      puts ("mutex_init failed");
> -      return 1;
> -    }
> -
> -  if (pthread_mutexattr_destroy (&a) != 0)
> -    {
> -      puts ("mutexattr_destroy failed");
> -      return 1;
> -    }
> -
> -  if (pthread_mutex_lock (&m) != 0)
> -    {
> -      puts ("mutex_lock failed");
> -      return 1;
> +      FAIL_EXIT1 ("mutex_init failed");
>      }
>  
> +  TEST_COMPARE (pthread_mutexattr_destroy (&a), 0);
> +  TEST_COMPARE (pthread_mutex_lock (&m), 0);
>    if (pthread_mutex_trylock (&m) == 0)
> -    {
> -      puts ("mutex_trylock succeeded");
> -      return 1;
> -    }
> +    FAIL_EXIT1 ("mutex_trylock succeeded");
>  

Ok.

> -  gettimeofday (&tv, NULL);
> -  TIMEVAL_TO_TIMESPEC (&tv, &ts);
> -
> -  ts.tv_sec += 2;	/* Wait 2 seconds.  */
> -
> -  err = pthread_mutex_timedlock (&m, &ts);
> -  if (err == 0)
> -    {
> -      puts ("timedlock succeeded");
> -      return 1;
> -    }
> -  else if (err != ETIMEDOUT)
> -    {
> -      printf ("timedlock error != ETIMEDOUT: %d\n", err);
> -      return 1;
> -    }
> -  else
> -    {
> -      int clk_tck = sysconf (_SC_CLK_TCK);
> -
> -      gettimeofday (&tv2, NULL);
> -
> -      tv2.tv_sec -= tv.tv_sec;
> -      tv2.tv_usec -= tv.tv_usec;
> -      if (tv2.tv_usec < 0)
> -	{
> -	  tv2.tv_usec += 1000000;
> -	  tv2.tv_sec -= 1;
> -	}
> -
> -      /* Be a bit tolerant, add one CLK_TCK.  */
> -      tv2.tv_usec += 1000000 / clk_tck;
> -      if (tv2.tv_usec >= 1000000)
> -	{
> -	  tv2.tv_usec -= 1000000;
> -	  ++tv2.tv_sec;
> -	}
> -
> -      if (tv2.tv_sec < 2)
> -	{
> -	  printf ("premature timeout: %jd.%06jd difference\n",
> -		  (intmax_t) tv2.tv_sec, (intmax_t) tv2.tv_usec);
> -	  return 1;
> -	}
> -    }
> +  /* Wait 2 seconds.  */
> +  struct timespec ts_timeout = timespec_add (xclock_now (CLOCK_REALTIME),
> +                                             make_timespec (2, 0));
>  

Ok.

> -  (void) gettimeofday (&tv, NULL);
> -  TIMEVAL_TO_TIMESPEC (&tv, &ts);
> +  TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), ETIMEDOUT);
> +  TEST_TIMESPEC_BEFORE_NOW (ts_timeout, CLOCK_REALTIME);
>  
> -  ts.tv_sec += 2;	/* Wait 2 seconds.  */
>    /* The following makes the ts value invalid.  */
> -  ts.tv_nsec += 1000000000;
> +  ts_timeout.tv_nsec += 1000000000;
>  
> -  err = pthread_mutex_timedlock (&m, &ts);
> -  if (err == 0)
> -    {
> -      puts ("2nd timedlock succeeded");
> -      return 1;
> -    }
> -  else if (err != EINVAL)
> -    {
> -      printf ("2nd timedlock error != EINVAL: %d\n", err);
> -      return 1;
> -    }
> +  TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), EINVAL);
> +  TEST_COMPARE (pthread_mutex_unlock (&m), 0);
>  
> -  if (pthread_mutex_unlock (&m) != 0)
> -    {
> -      puts ("mutex_unlock failed");
> -      return 1;
> -    }

Ok.

> +  const struct timespec ts_start = xclock_now (CLOCK_REALTIME);
>  
> -  (void) gettimeofday (&tv, NULL);
> -  TIMEVAL_TO_TIMESPEC (&tv, &ts);
> +  /* Wait 2 seconds.  */
> +  ts_timeout = timespec_add (ts_start, make_timespec (2, 0));
>  
> -  ts.tv_sec += 2;	/* Wait 2 seconds.  */
> -  if (pthread_mutex_timedlock (&m, &ts) != 0)
> -    {
> -      puts ("3rd timedlock failed");
> -    }
> +  TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), 0);
>  
> -  (void) gettimeofday (&tv2, NULL);
> +  const struct timespec ts_end = xclock_now (CLOCK_REALTIME);
>  
>    /* Check that timedlock didn't delay.  We use a limit of 0.1 secs.  */
> -  timersub (&tv2, &tv, &tv2);
> -  if (tv2.tv_sec > 0 || tv2.tv_usec > 100000)
> -    {
> -      puts ("3rd timedlock didn't return right away");
> -      return 1;
> -    }
> +  TEST_TIMESPEC_BEFORE (ts_end,
> +                        timespec_add (ts_start, make_timespec (0, 100000000)));
>  
> -  if (pthread_mutex_unlock (&m) != 0)
> -    {
> -      puts ("final mutex_unlock failed");
> -      return 1;
> -    }
> -
> -  if (pthread_mutex_destroy (&m) != 0)
> -    {
> -      puts ("mutex_destroy failed");
> -      return 1;
> -    }
> +  TEST_COMPARE (pthread_mutex_unlock (&m), 0);
> +  TEST_COMPARE (pthread_mutex_destroy (&m), 0);
>  
>    return 0;
>  }
>  
> -#define TEST_FUNCTION do_test ()
> -#include "../test-skeleton.c"
> +#include <support/test-driver.c>

Ok.

> diff --git a/nptl/tst-mutex9.c b/nptl/tst-mutex9.c
> index 917276e..e9fd8e2 100644
> --- a/nptl/tst-mutex9.c
> +++ b/nptl/tst-mutex9.c
> @@ -26,6 +26,9 @@
>  #include <sys/mman.h>
>  #include <sys/time.h>
>  #include <sys/wait.h>
> +#include <support/check.h>
> +#include <support/timespec.h>
> +#include <support/xunistd.h>
>  
>  
>  static int
> @@ -42,10 +45,7 @@ do_test (void)
>  
>    fd = mkstemp (tmpfname);
>    if (fd == -1)
> -    {
> -      printf ("cannot open temporary file: %m\n");
> -      return 1;
> -    }
> +      FAIL_EXIT1 ("cannot open temporary file: %m\n");
>  
>    /* Make sure it is always removed.  */
>    unlink (tmpfname);

Ok.

> @@ -54,46 +54,21 @@ do_test (void)
>    memset (data, '\0', ps);
>  
>    /* Write the data to the file.  */
> -  if (write (fd, data, ps) != (ssize_t) ps)
> -    {
> -      puts ("short write");
> -      return 1;
> -    }
> +  xwrite (fd, data, ps);
>  
> -  mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
> -  if (mem == MAP_FAILED)
> -    {
> -      printf ("mmap failed: %m\n");
> -      return 1;
> -    }
> +  mem = xmmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd);

Ok.

>  
>    m = (pthread_mutex_t *) (((uintptr_t) mem + __alignof (pthread_mutex_t))
>  			   & ~(__alignof (pthread_mutex_t) - 1));
>  
> -  if (pthread_mutexattr_init (&a) != 0)
> -    {
> -      puts ("mutexattr_init failed");
> -      return 1;
> -    }
> +  TEST_COMPARE (pthread_mutexattr_init (&a), 0);
>  
> -  if (pthread_mutexattr_setpshared (&a, PTHREAD_PROCESS_SHARED) != 0)
> -    {
> -      puts ("mutexattr_setpshared failed");
> -      return 1;
> -    }
> +  TEST_COMPARE (pthread_mutexattr_setpshared (&a, PTHREAD_PROCESS_SHARED), 0);
>  
> -  if (pthread_mutexattr_settype (&a, PTHREAD_MUTEX_RECURSIVE) != 0)
> -    {
> -      puts ("mutexattr_settype failed");
> -      return 1;
> -    }
> +  TEST_COMPARE (pthread_mutexattr_settype (&a, PTHREAD_MUTEX_RECURSIVE), 0);
>  
>  #ifdef ENABLE_PI
> -  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
> -    {
> -      puts ("pthread_mutexattr_setprotocol failed");
> -      return 1;
> -    }
> +  TEST_COMPARE (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT), 0);
>  #endif
>  
>    int e;

Ok.

> @@ -101,70 +76,29 @@ do_test (void)
>      {
>  #ifdef ENABLE_PI
>        if (e == ENOTSUP)
> -	{
> -	  puts ("PI mutexes unsupported");
> -	  return 0;
> -	}
> +        FAIL_UNSUPPORTED ("PI mutexes unsupported");
>  #endif
> -      puts ("mutex_init failed");
> -      return 1;
> +      FAIL_EXIT1 ("mutex_init failed");
>      }
>  
> -  if (pthread_mutex_lock (m) != 0)
> -    {
> -      puts ("mutex_lock failed");
> -      return 1;
> -    }
> +  TEST_COMPARE (pthread_mutex_lock (m), 0);
>  
> -  if (pthread_mutexattr_destroy (&a) != 0)
> -    {
> -      puts ("mutexattr_destroy failed");
> -      return 1;
> -    }
> +  TEST_COMPARE (pthread_mutexattr_destroy (&a), 0);

Ok.

>  
>    puts ("going to fork now");
> -  pid = fork ();
> -  if (pid == -1)
> -    {
> -      puts ("fork failed");
> -      return 1;
> -    }
> -  else if (pid == 0)
> +  pid = xfork ();
> +  if (pid == 0)
>      {
>        if (pthread_mutex_trylock (m) == 0)
> -	{
> -	  puts ("child: mutex_trylock succeeded");
> -	  exit (1);
> -	}
> +        FAIL_EXIT1 ("child: mutex_trylock succeeded");
>  

Ok.

>        if (pthread_mutex_unlock (m) == 0)
> -	{
> -	  puts ("child: mutex_unlock succeeded");
> -	  exit (1);
> -	}
> -
> -      struct timeval tv;
> -      gettimeofday (&tv, NULL);
> -      struct timespec ts;
> -      TIMEVAL_TO_TIMESPEC (&tv, &ts);
> -      ts.tv_nsec += 500000000;
> -      if (ts.tv_nsec >= 1000000000)
> -	{
> -	  ++ts.tv_sec;
> -	  ts.tv_nsec -= 1000000000;
> -	}
> -
> -      e = pthread_mutex_timedlock (m, &ts);
> -      if (e == 0)
> -	{
> -	  puts ("child: mutex_timedlock succeeded");
> -	  exit (1);
> -	}
> -      if (e != ETIMEDOUT)
> -	{
> -	  puts ("child: mutex_timedlock didn't time out");
> -	  exit (1);
> -	}
> +        FAIL_EXIT1 ("child: mutex_unlock succeeded");
> +
> +      const struct timespec ts = timespec_add (xclock_now (CLOCK_REALTIME),
> +                                               make_timespec (0, 500000000));
> +
> +      TEST_COMPARE (pthread_mutex_timedlock (m, &ts), ETIMEDOUT);
>  
>        alarm (1);
>  

Ok.

> @@ -179,23 +113,12 @@ do_test (void)
>  
>    int status;
>    if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
> -    {
> -      puts ("waitpid failed");
> -      return 1;
> -    }
> +    FAIL_EXIT1 ("waitpid failed");
>    if (! WIFSIGNALED (status))
> -    {
> -      puts ("child not killed by signal");
> -      return 1;
> -    }
> -  if (WTERMSIG (status) != SIGALRM)
> -    {
> -      puts ("child not killed by SIGALRM");
> -      return 1;
> -    }
> +    FAIL_EXIT1 ("child not killed by signal");
> +  TEST_COMPARE (WTERMSIG (status), SIGALRM);
>  
>    return 0;
>  }
>  
> -#define TEST_FUNCTION do_test ()
> -#include "../test-skeleton.c"
> +#include <support/test-driver.c>
> 

Ok.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v4 04/12] nptl: Add clockid parameter to futex timed wait calls
  2019-06-18 16:33 ` [PATCH v4 04/12] nptl: Add clockid parameter to futex timed wait calls Mike Crowe
@ 2019-06-21 14:51   ` Adhemerval Zanella
  0 siblings, 0 replies; 32+ messages in thread
From: Adhemerval Zanella @ 2019-06-21 14:51 UTC (permalink / raw
  To: libc-alpha



On 18/06/2019 13:33, Mike Crowe wrote:
> In preparation for adding POSIX clockwait variants of timedwait functions,
> add a clockid_t parameter to futex_abstimed_wait functions and pass
> CLOCK_REALTIME from all callers for the time being.
> 
> Replace lll_futex_timed_wait_bitset with lll_futex_clock_wait_bitset which
> takes a clockid_t parameter rather than the magic clockbit.
> 
> * sysdeps/nptl/lowlevellock-futex.h,
>   sysdeps/unix/sysv/linux/lowlevellock-futex.h: Replace
>   lll_futex_timed_wait_bitset with lll_futex_clock_wait_bitset that takes a
>   clockid rather than a special clockbit.
> 
> * sysdeps/nptl/lowlevellock-futex.h: Add lll_futex_supported_clockid so
>   that client functions can check whether their clockid parameter is valid
>   even if they don't ultimately end up calling lll_futex_clock_wait_bitset.
> 
> * sysdeps/nptl/futex-internal.h, sysdeps/unix/sysv/linux/futex-internal.h
>   (futex_abstimed_wait, futex_abstimed_wait_cancelable): Add clockid_t
>   parameter to indicate which clock the absolute time passed should be
>   measured against. Pass that clockid onto lll_futex_clock_wait_bitset.
>   Add invalid clock as reason for returning -EINVAL.
> 
> * sysdeps/nptl/futex-internal.h, sysdeps/unix/sysv/linux/futex-internal.h:
>   Introduce futex_abstimed_supported_clockid so that client functions can
>   check whether their clockid parameter is valid even if they don't
>   ultimately end up calling futex_abstimed_wait.
> 
> * nptl/pthread_cond_wait.c (__pthread_cond_wait_common): Remove code to
>   calculate relative timeout for __PTHREAD_COND_CLOCK_MONOTONIC_MASK and
>   just pass CLOCK_MONOTONIC or CLOCK_REALTIME as required to
>   futex_abstimed_wait_cancelable.
> 
> * nptl/pthread_rwlock_common (__pthread_rwlock_rdlock_full,
>   __pthread_wrlock_full), nptl/sem_waitcommon (do_futex_wait): Pass
>   additional CLOCK_REALTIME to futex_abstimed_wait_cancelable.
> 
> * nptl/pthread_mutex_timedlock.c (__pthread_mutex_timedlock): Switch to
>   lll_futex_clock_wait_bitset and pass CLOCK_REALTIME

LGTM, I will commit this for you.

> ---
>  ChangeLog                                    | 40 +++++++++++++++++++++-
>  nptl/pthread_cond_wait.c                     | 32 +++--------------
>  nptl/pthread_mutex_timedlock.c               |  4 +-
>  nptl/pthread_rwlock_common.c                 |  8 ++--
>  nptl/sem_waitcommon.c                        |  6 ++-
>  sysdeps/nptl/futex-internal.h                |  9 ++++-
>  sysdeps/nptl/lowlevellock-futex.h            | 13 ++++---
>  sysdeps/unix/sysv/linux/futex-internal.h     | 26 ++++++++++----
>  sysdeps/unix/sysv/linux/lowlevellock-futex.h | 33 +++++++++++++----
>  9 files changed, 119 insertions(+), 52 deletions(-)
> 
> diff --git a/ChangeLog b/ChangeLog
> index e6b36b5..dc84553 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,3 +1,43 @@
> +2019-05-27  Mike Crowe  <mac@mcrowe.com>
> +
> +	nptl: Add clockid parameter to futex timed wait calls
> +
> +	* sysdeps/nptl/lowlevellock-futex.h,
> +	sysdeps/unix/sysv/linux/lowlevellock-futex.h: Replace
> +	lll_futex_timed_wait_bitset with lll_futex_clock_wait_bitset that
> +	takes a clockid rather than a special clockbit.
> +
> +	* sysdeps/nptl/lowlevellock-futex.h: Add
> +	lll_futex_supported_clockid so that client functions can check
> +	whether their clockid parameter is valid even if they don't
> +	ultimately end up calling lll_futex_clock_wait_bitset.
> +
> +	* sysdeps/nptl/futex-internal.h,
> +	sysdeps/unix/sysv/linux/futex-internal.h
> +	(futex_abstimed_wait, futex_abstimed_wait_cancelable): Add
> +	clockid_t parameter to indicate which clock the absolute time
> +	passed should be measured against. Pass that clockid onto
> +	lll_futex_clock_wait_bitset. Add invalid clock as reason for
> +	returning -EINVAL.
> +
> +	* sysdeps/nptl/futex-internal.h,
> +	sysdeps/unix/sysv/linux/futex-internal.h: Introduce
> +	futex_abstimed_supported_clockid so that client functions can check
> +	whether their clockid parameter is valid even if they don't
> +	ultimately end up calling futex_abstimed_wait.
> +
> +	* nptl/pthread_cond_wait.c (__pthread_cond_wait_common): Remove
> +	code to calculate relative timeout for
> +	__PTHREAD_COND_CLOCK_MONOTONIC_MASK and just pass CLOCK_MONOTONIC
> +	or CLOCK_REALTIME as required to futex_abstimed_wait_cancelable.
> +
> +	* nptl/pthread_rwlock_common (__pthread_rwlock_rdlock_full)
> +	(__pthread_wrlock_full), nptl/sem_waitcommon (do_futex_wait): Pass
> +	additional CLOCK_REALTIME to futex_abstimed_wait_cancelable.
> +
> +	* nptl/pthread_mutex_timedlock.c (__pthread_mutex_timedlock):
> +	Switch to lll_futex_clock_wait_bitset and pass CLOCK_REALTIME
> +
>  2019-05-30  Mike Crowe  <mac@mcrowe.com>
>  
>  	* nptl/eintr.c: Use libsupport.
> diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
> index 9a0f29e..7385562 100644
> --- a/nptl/pthread_cond_wait.c
> +++ b/nptl/pthread_cond_wait.c
> @@ -509,35 +509,15 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
>  		 values despite them being valid.  */
>  	      if (__glibc_unlikely (abstime->tv_sec < 0))
>  	        err = ETIMEDOUT;
> -
> -	      else if ((flags & __PTHREAD_COND_CLOCK_MONOTONIC_MASK) != 0)
> -		{
> -		  /* CLOCK_MONOTONIC is requested.  */
> -		  struct timespec rt;
> -		  if (__clock_gettime (CLOCK_MONOTONIC, &rt) != 0)
> -		    __libc_fatal ("clock_gettime does not support "
> -				  "CLOCK_MONOTONIC\n");
> -		  /* Convert the absolute timeout value to a relative
> -		     timeout.  */
> -		  rt.tv_sec = abstime->tv_sec - rt.tv_sec;
> -		  rt.tv_nsec = abstime->tv_nsec - rt.tv_nsec;
> -		  if (rt.tv_nsec < 0)
> -		    {
> -		      rt.tv_nsec += 1000000000;
> -		      --rt.tv_sec;
> -		    }
> -		  /* Did we already time out?  */
> -		  if (__glibc_unlikely (rt.tv_sec < 0))
> -		    err = ETIMEDOUT;
> -		  else
> -		    err = futex_reltimed_wait_cancelable
> -			(cond->__data.__g_signals + g, 0, &rt, private);
> -		}
>  	      else
>  		{
> -		  /* Use CLOCK_REALTIME.  */
> +		  const clockid_t clockid =
> +		    ((flags & __PTHREAD_COND_CLOCK_MONOTONIC_MASK) != 0) ?
> +		    CLOCK_MONOTONIC : CLOCK_REALTIME;
> +
>  		  err = futex_abstimed_wait_cancelable
> -		      (cond->__data.__g_signals + g, 0, abstime, private);
> +                    (cond->__data.__g_signals + g, 0, clockid, abstime,
> +                     private);
>  		}
>  	    }
>  
> diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
> index 270b072..d4d11cc 100644
> --- a/nptl/pthread_mutex_timedlock.c
> +++ b/nptl/pthread_mutex_timedlock.c
> @@ -266,8 +266,8 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
>  	  assume_other_futex_waiters |= FUTEX_WAITERS;
>  
>  	  /* Block using the futex.  */
> -	  int err = lll_futex_timed_wait_bitset (&mutex->__data.__lock,
> -	      oldval, abstime, FUTEX_CLOCK_REALTIME,
> +	  int err = lll_futex_clock_wait_bitset (&mutex->__data.__lock,
> +	      oldval, CLOCK_REALTIME, abstime,
>  	      PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
>  	  /* The futex call timed out.  */
>  	  if (err == -ETIMEDOUT)
> diff --git a/nptl/pthread_rwlock_common.c b/nptl/pthread_rwlock_common.c
> index 2560734..89ba21a 100644
> --- a/nptl/pthread_rwlock_common.c
> +++ b/nptl/pthread_rwlock_common.c
> @@ -319,7 +319,7 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
>  		{
>  		  int private = __pthread_rwlock_get_private (rwlock);
>  		  int err = futex_abstimed_wait (&rwlock->__data.__readers,
> -						 r, abstime, private);
> +						 r, CLOCK_REALTIME, 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)
> @@ -447,7 +447,7 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
>  	    continue;
>  	  int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
>  					 1 | PTHREAD_RWLOCK_FUTEX_USED,
> -					 abstime, private);
> +					 CLOCK_REALTIME, abstime, private);
>  	  if (err == ETIMEDOUT)
>  	    {
>  	      /* If we timed out, we need to unregister.  If no read phase
> @@ -707,7 +707,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
>  	  may_share_futex_used_flag = true;
>  	  int err = futex_abstimed_wait (&rwlock->__data.__writers_futex,
>  					 1 | PTHREAD_RWLOCK_FUTEX_USED,
> -					 abstime, private);
> +					 CLOCK_REALTIME, abstime, private);
>  	  if (err == ETIMEDOUT)
>  	    {
>  	      if (prefer_writer)
> @@ -806,7 +806,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
>  	    continue;
>  	  int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
>  					 PTHREAD_RWLOCK_FUTEX_USED,
> -					 abstime, private);
> +					 CLOCK_REALTIME, abstime, private);
>  	  if (err == ETIMEDOUT)
>  	    {
>  	      if (rwlock->__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP)
> diff --git a/nptl/sem_waitcommon.c b/nptl/sem_waitcommon.c
> index 5646bea..425d040 100644
> --- a/nptl/sem_waitcommon.c
> +++ b/nptl/sem_waitcommon.c
> @@ -109,11 +109,13 @@ do_futex_wait (struct new_sem *sem, const struct timespec *abstime)
>  
>  #if __HAVE_64B_ATOMICS
>    err = futex_abstimed_wait_cancelable (
> -      (unsigned int *) &sem->data + SEM_VALUE_OFFSET, 0, abstime,
> +      (unsigned int *) &sem->data + SEM_VALUE_OFFSET, 0,
> +      CLOCK_REALTIME, abstime,
>        sem->private);
>  #else
>    err = futex_abstimed_wait_cancelable (&sem->value, SEM_NWAITERS_MASK,
> -					abstime, sem->private);
> +					CLOCK_REALTIME, abstime,
> +					sem->private);
>  #endif
>  
>    return err;
> diff --git a/sysdeps/nptl/futex-internal.h b/sysdeps/nptl/futex-internal.h
> index 86a0818..bc29bdb 100644
> --- a/sysdeps/nptl/futex-internal.h
> +++ b/sysdeps/nptl/futex-internal.h
> @@ -49,7 +49,7 @@
>     futex word.
>  
>     Both absolute and relative timeouts can be used.  An absolute timeout
> -   expires when the given specific point in time on the CLOCK_REALTIME clock
> +   expires when the given specific point in time on the specified clock
>     passes, or when it already has passed.  A relative timeout expires when
>     the given duration of time on the CLOCK_MONOTONIC clock passes.  Relative
>     timeouts may be imprecise (see futex_supports_exact_relative_timeouts).
> @@ -159,16 +159,23 @@ futex_reltimed_wait_cancelable (unsigned int* futex_word,
>  				unsigned int expected,
>  			        const struct timespec* reltime, int private);
>  
> +/* Check whether the specified clockid is supported by
> +   futex_abstimed_wait and futex_abstimed_wait_cancelable. */
> +static __always_inline int
> +futex_abstimed_supported_clockid (clockid_t clockid);
> +
>  /* Like futex_reltimed_wait, but the provided timeout (ABSTIME) is an
>     absolute point in time; a call will time out after this point in time.  */
>  static __always_inline int
>  futex_abstimed_wait (unsigned int* futex_word, unsigned int expected,
> +		     clockid_t clockid,
>  		     const struct timespec* abstime, int private);
>  
>  /* Like futex_reltimed_wait but is a POSIX cancellation point.  */
>  static __always_inline int
>  futex_abstimed_wait_cancelable (unsigned int* futex_word,
>  				unsigned int expected,
> +				clockid_t clockid,
>  			        const struct timespec* abstime, int private);
>  
>  /* Atomically wrt other futex operations on the same futex, this unblocks the
> diff --git a/sysdeps/nptl/lowlevellock-futex.h b/sysdeps/nptl/lowlevellock-futex.h
> index 63d917d..35fcfbb 100644
> --- a/sysdeps/nptl/lowlevellock-futex.h
> +++ b/sysdeps/nptl/lowlevellock-futex.h
> @@ -43,10 +43,15 @@
>  #define lll_futex_timed_wait(futexp, val, timeout, private)             \
>    -ENOSYS
>  
> -/* If CLOCKBIT is zero, this is identical to lll_futex_timed_wait.
> -   If CLOCKBIT has FUTEX_CLOCK_REALTIME set, then it's the same but
> -   TIMEOUT is counted by CLOCK_REALTIME rather than CLOCK_MONOTONIC.  */
> -#define lll_futex_timed_wait_bitset(futexp, val, timeout, clockbit, private) \
> +/* Verify whether the supplied clockid is supported by
> +   lll_futex_clock_wait_bitset */
> +#define lll_futex_supported_clockid(clockid)				\
> +  (0)
> +
> +/* Wait until a lll_futex_wake call on FUTEXP, or the absolute TIMEOUT
> +   measured against CLOCKID elapses. CLOCKID may be CLOCK_REALTIME or
> +   CLOCK_MONOTONIC. */
> +#define lll_futex_clock_wait_bitset(futexp, val, clockid, timeout, private) \
>    -ENOSYS
>  
>  /* Wake up up to NR waiters on FUTEXP.  */
> diff --git a/sysdeps/unix/sysv/linux/futex-internal.h b/sysdeps/unix/sysv/linux/futex-internal.h
> index 501f993..03312d6 100644
> --- a/sysdeps/unix/sysv/linux/futex-internal.h
> +++ b/sysdeps/unix/sysv/linux/futex-internal.h
> @@ -162,15 +162,24 @@ futex_reltimed_wait_cancelable (unsigned int *futex_word,
>  
>  /* See sysdeps/nptl/futex-internal.h for details.  */
>  static __always_inline int
> +futex_abstimed_supported_clockid (clockid_t clockid)
> +{
> +  return lll_futex_supported_clockid (clockid);
> +}
> +
> +/* See sysdeps/nptl/futex-internal.h for details.  */
> +static __always_inline int
>  futex_abstimed_wait (unsigned int *futex_word, unsigned int expected,
> +		     clockid_t clockid,
>  		     const struct timespec *abstime, int private)
>  {
>    /* Work around the fact that the kernel rejects negative timeout values
>       despite them being valid.  */
>    if (__glibc_unlikely ((abstime != NULL) && (abstime->tv_sec < 0)))
>      return ETIMEDOUT;
> -  int err = lll_futex_timed_wait_bitset (futex_word, expected, abstime,
> -					 FUTEX_CLOCK_REALTIME, private);
> +  int err = lll_futex_clock_wait_bitset (futex_word, expected,
> +					 clockid, abstime,
> +					 private);
>    switch (err)
>      {
>      case 0:
> @@ -180,9 +189,10 @@ futex_abstimed_wait (unsigned int *futex_word, unsigned int expected,
>        return -err;
>  
>      case -EFAULT: /* Must have been caused by a glibc or application bug.  */
> -    case -EINVAL: /* Either due to wrong alignment or due to the timeout not
> -		     being normalized.  Must have been caused by a glibc or
> -		     application bug.  */
> +    case -EINVAL: /* Either due to wrong alignment, unsupported
> +		     clockid or due to the timeout not being
> +		     normalized. Must have been caused by a glibc or
> +		     application bug. */
>      case -ENOSYS: /* Must have been caused by a glibc bug.  */
>      /* No other errors are documented at this time.  */
>      default:
> @@ -194,6 +204,7 @@ futex_abstimed_wait (unsigned int *futex_word, unsigned int expected,
>  static __always_inline int
>  futex_abstimed_wait_cancelable (unsigned int *futex_word,
>  				unsigned int expected,
> +				clockid_t clockid,
>  			        const struct timespec *abstime, int private)
>  {
>    /* Work around the fact that the kernel rejects negative timeout values
> @@ -202,8 +213,9 @@ futex_abstimed_wait_cancelable (unsigned int *futex_word,
>      return ETIMEDOUT;
>    int oldtype;
>    oldtype = __pthread_enable_asynccancel ();
> -  int err = lll_futex_timed_wait_bitset (futex_word, expected, abstime,
> -					 FUTEX_CLOCK_REALTIME, private);
> +  int err = lll_futex_clock_wait_bitset (futex_word, expected,
> +					clockid, abstime,
> +					private);
>    __pthread_disable_asynccancel (oldtype);
>    switch (err)
>      {
> diff --git a/sysdeps/unix/sysv/linux/lowlevellock-futex.h b/sysdeps/unix/sysv/linux/lowlevellock-futex.h
> index 030a14b..ba01197 100644
> --- a/sysdeps/unix/sysv/linux/lowlevellock-futex.h
> +++ b/sysdeps/unix/sysv/linux/lowlevellock-futex.h
> @@ -82,12 +82,33 @@
>  		     __lll_private_flag (FUTEX_WAIT, private),  \
>  		     val, timeout)
>  
> -#define lll_futex_timed_wait_bitset(futexp, val, timeout, clockbit, private) \
> -  lll_futex_syscall (6, futexp,                                         \
> -		     __lll_private_flag (FUTEX_WAIT_BITSET | (clockbit), \
> -					 private),                      \
> -		     val, timeout, NULL /* Unused.  */,                 \
> -		     FUTEX_BITSET_MATCH_ANY)
> +/* Verify whether the supplied clockid is supported by
> +   lll_futex_clock_wait_bitset */
> +#define lll_futex_supported_clockid(clockid)			\
> +  ((clockid) == CLOCK_REALTIME || (clockid) == CLOCK_MONOTONIC)
> +
> +/* The kernel currently only supports CLOCK_MONOTONIC or
> + * CLOCK_REALTIME timeouts for FUTEX_WAIT_BITSET. We could attempt to
> + * convert others here but currently do not.
> + */
> +#define lll_futex_clock_wait_bitset(futexp, val, clockid, timeout, private) \
> +  ({									\
> +    long int __ret;							\
> +    if (lll_futex_supported_clockid (clockid))                          \
> +      {                                                                 \
> +        const unsigned int clockbit =                                   \
> +          (clockid == CLOCK_REALTIME) ? FUTEX_CLOCK_REALTIME : 0;       \
> +        const int op =                                                  \
> +          __lll_private_flag (FUTEX_WAIT_BITSET | clockbit, private);   \
> +                                                                        \
> +        __ret = lll_futex_syscall (6, futexp, op, val,                  \
> +                                   timeout, NULL /* Unused.  */,	\
> +                                   FUTEX_BITSET_MATCH_ANY);		\
> +      }                                                                 \
> +    else                                                                \
> +      __ret = -EINVAL;							\
> +    __ret;								\
> +  })
>  
>  #define lll_futex_wake(futexp, nr, private)                             \
>    lll_futex_syscall (4, futexp,                                         \
> 

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v4 05/12] nptl: Add POSIX-proposed sem_clockwait
  2019-06-18 16:33 ` [PATCH v4 05/12] nptl: Add POSIX-proposed sem_clockwait Mike Crowe
@ 2019-06-21 16:02   ` Adhemerval Zanella
  2019-06-22 20:44     ` Mike Crowe
  0 siblings, 1 reply; 32+ messages in thread
From: Adhemerval Zanella @ 2019-06-21 16:02 UTC (permalink / raw
  To: libc-alpha



On 18/06/2019 13:33, Mike Crowe wrote:
> Add:
> 
>  int sem_clockwait (sem_t *sem, clockid_t clock, const struct timespec *abstime)
> 
> which behaves just like sem_timedwait, but measures abstime against the
> specified clock. Currently supports CLOCK_REALTIME and CLOCK_MONOTONIC and
> sets errno == EINVAL if any other clock is specified.
> 
> * nptl/sem_waitcommon.c (do_futex_wait, __new_sem_wait_slow): Add clockid
>   parameters to indicate the clock which abstime should be measured
>   against.
> 
> * nptl/sem_timedwait.c (sem_timedwait), nptl/sem_wait.c (__new_sem_wait):
>   Pass CLOCK_REALTIME as clockid to __new_sem_wait_slow.
> 
> * nptl/sem_clockwait.c: New file to implement sem_clockwait based on
>   sem_timedwait.c.
> 
> * nptl/Makefile: Add sem_clockwait.c source file. Add CFLAGS for
>   sem_clockwait.c to match those used for sem_timedwait.c.
> 
> * sysdeps/pthread/semaphore.h: Add sem_clockwait.
> 
> * nptl/Versions (GLIBC_2.30): Likewise.
> 
> * sysdeps/unix/sysv/linux/aarch64/libpthread.abilist (GLIBC_2.30): Likewise.
> * sysdeps/unix/sysv/linux/alpha/libpthread.abilist (GLIBC_2.30): Likewise.
> * sysdeps/unix/sysv/linux/arm/libpthread.abilist (GLIBC_2.30): Likewise.
> * sysdeps/unix/sysv/linux/csky/libpthread.abilist (GLIBC_2.30): Likewise.
> * sysdeps/unix/sysv/linux/hppa/libpthread.abilist (GLIBC_2.30): Likewise.
> * sysdeps/unix/sysv/linux/i386/libpthread.abilist (GLIBC_2.30): Likewise.
> * sysdeps/unix/sysv/linux/ia64/libpthread.abilist (GLIBC_2.30): Likewise.
> * sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> * sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> * sysdeps/unix/sysv/linux/microblaze/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> * sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> * sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> * sysdeps/unix/sysv/linux/nios2/libpthread.abilist (GLIBC_2.30): Likewise.
> * sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
>   (GLIBC_2.30): Likewise.
> * sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
>   (GLIBC_2.30): Likewise.
> * sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
>   (GLIBC_2.30): Likewise.
> * sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist	(GLIBC_2.30):
>   Likewise.
> * sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> * sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> * sysdeps/unix/sysv/linux/sh/libpthread.abilist (GLIBC_2.30): Likewise.
> * sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> * sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> * sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> * sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * nptl/tst-sem17.c: Add new test for passing invalid clock to
>   sem_clockwait.
> 
> * nptl/tst-sem13.c, nptl/tst-sem5.c: Modify existing sem_timedwait tests to
>   also test sem_clockwait.
> 
> * manual/threads.texi: Document sem_clockwait.

LGTM with just one nit below regarding alpha abilist (I will fix it prior
push).  The change seems to align with proposed Android addition [1].

[1] https://android-review.googlesource.com/c/platform/bionic/+/958058

> ---
>  ChangeLog                                                       | 71 +++++++-
>  manual/threads.texi                                             | 10 +-
>  nptl/Makefile                                                   |  5 +-
>  nptl/Versions                                                   |  4 +-
>  nptl/sem_clockwait.c                                            | 45 ++++-
>  nptl/sem_timedwait.c                                            |  3 +-
>  nptl/sem_wait.c                                                 |  3 +-
>  nptl/sem_waitcommon.c                                           | 15 +-
>  nptl/tst-sem13.c                                                | 39 +++-
>  nptl/tst-sem17.c                                                | 76 +++++++-
>  nptl/tst-sem5.c                                                 | 23 +-
>  sysdeps/pthread/semaphore.h                                     |  7 +-
>  sysdeps/unix/sysv/linux/aarch64/libpthread.abilist              |  1 +-
>  sysdeps/unix/sysv/linux/alpha/libpthread.abilist                |  1 +-
>  sysdeps/unix/sysv/linux/arm/libpthread.abilist                  |  1 +-
>  sysdeps/unix/sysv/linux/csky/libpthread.abilist                 |  1 +-
>  sysdeps/unix/sysv/linux/hppa/libpthread.abilist                 |  1 +-
>  sysdeps/unix/sysv/linux/i386/libpthread.abilist                 |  1 +-
>  sysdeps/unix/sysv/linux/ia64/libpthread.abilist                 |  1 +-
>  sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist        |  1 +-
>  sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist          |  1 +-
>  sysdeps/unix/sysv/linux/microblaze/libpthread.abilist           |  1 +-
>  sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist          |  1 +-
>  sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist          |  1 +-
>  sysdeps/unix/sysv/linux/nios2/libpthread.abilist                |  1 +-
>  sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist    |  1 +-
>  sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist |  1 +-
>  sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist |  1 +-
>  sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist           |  1 +-
>  sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist         |  1 +-
>  sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist         |  1 +-
>  sysdeps/unix/sysv/linux/sh/libpthread.abilist                   |  1 +-
>  sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist        |  1 +-
>  sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist        |  1 +-
>  sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist            |  1 +-
>  sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist           |  1 +-
>  36 files changed, 305 insertions(+), 20 deletions(-)
>  create mode 100644 nptl/sem_clockwait.c
>  create mode 100644 nptl/tst-sem17.c
> 
> diff --git a/ChangeLog b/ChangeLog
> index dc84553..33502da 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,5 +1,76 @@
>  2019-05-27  Mike Crowe  <mac@mcrowe.com>
>  
> +	nptl: Add POSIX-proposed sem_clockwait which behaves just like
> +	sem_timedwait, but measures abstime against the specified clock.
> +
> +	* nptl/sem_waitcommon.c (do_futex_wait, __new_sem_wait_slow): Add
> +	clockid parameters to indicate the clock which abstime should be
> +	measured against.
> +
> +	* nptl/sem_timedwait.c (sem_timedwait), nptl/sem_wait.c
> +	(__new_sem_wait): Pass CLOCK_REALTIME as clockid to
> +	__new_sem_wait_slow.
> +
> +	* nptl/sem_clockwait.c: New file to implement sem_clockwait based
> +	on sem_timedwait.c.
> +
> +	* nptl/Makefile: Add sem_clockwait.c source file. Add CFLAGS for
> +	sem_clockwait.c to match those used for sem_timedwait.c.
> +
> +	* sysdeps/pthread/semaphore.h: Add sem_clockwait.
> +
> +	* nptl/Versions (GLIBC_2.30): Likewise.
> +
> +	* sysdeps/unix/sysv/linux/aarch64/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/alpha/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/arm/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/csky/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/hppa/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/i386/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/ia64/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/nios2/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/sh/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +
> +	* nptl/tst-sem17.c: Add new test for passing invalid clock to
> +	sem_clockwait.
> +
> +	* nptl/tst-sem13.c, nptl/tst-sem5.c: Modify existing sem_timedwait
> +	tests to also test sem_clockwait.
> +
> +	* manual/threads.texi: Document sem_clockwait.
> +
> +2019-05-27  Mike Crowe  <mac@mcrowe.com>
> +
>  	nptl: Add clockid parameter to futex timed wait calls
>  
>  	* sysdeps/nptl/lowlevellock-futex.h,
> diff --git a/manual/threads.texi b/manual/threads.texi
> index 87fda7d..674267c 100644
> --- a/manual/threads.texi
> +++ b/manual/threads.texi
> @@ -669,6 +669,16 @@ The system does not have sufficient memory.
>  @end table
>  @end deftypefun
>  
> +@comment semaphore.h
> +@comment POSIX-proposed
> +@deftypefun int sem_clockwait (sem_t *@var{sem}, clockid_t @var{clockid},
> +                               const struct timespec *@var{abstime})
> +Behaves like @code{sem_timedwait} except the time @var{abstime} is measured
> +against the clock specified by @var{clockid} rather than
> +@code{CLOCK_REALTIME}. Currently, @var{clockid} must be either
> +@code{CLOCK_MONOTONIC} or @code{CLOCK_REALTIME}.
> +@end deftypefun
> +
>  @c FIXME these are undocumented:
>  @c pthread_atfork
>  @c pthread_attr_destroy
> diff --git a/nptl/Makefile b/nptl/Makefile
> index de312b3..43a99dc 100644
> --- a/nptl/Makefile
> +++ b/nptl/Makefile
> @@ -113,7 +113,7 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \
>  		      sem_init sem_destroy \
>  		      sem_open sem_close sem_unlink \
>  		      sem_getvalue \
> -		      sem_wait sem_timedwait sem_post \
> +		      sem_wait sem_timedwait sem_clockwait sem_post \
>  		      cleanup cleanup_defer cleanup_compat \
>  		      cleanup_defer_compat unwind \
>  		      pt-longjmp pt-cleanup\
> @@ -193,6 +193,7 @@ CFLAGS-pthread_once.c += $(uses-callbacks) -fexceptions \
>  CFLAGS-pthread_cond_wait.c += -fexceptions -fasynchronous-unwind-tables
>  CFLAGS-sem_wait.c += -fexceptions -fasynchronous-unwind-tables
>  CFLAGS-sem_timedwait.c += -fexceptions -fasynchronous-unwind-tables
> +CFLAGS-sem_clockwait.c = -fexceptions -fasynchronous-unwind-tables
>  
>  # These are the function wrappers we have to duplicate here.
>  CFLAGS-fcntl.c += -fexceptions -fasynchronous-unwind-tables
> @@ -262,7 +263,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
>  	tst-key1 tst-key2 tst-key3 tst-key4 \
>  	tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem5 tst-sem6 tst-sem7 \
>  	tst-sem8 tst-sem9 tst-sem10 tst-sem14 \
> -	tst-sem15 tst-sem16 \
> +	tst-sem15 tst-sem16 tst-sem17 \
>  	tst-barrier1 tst-barrier2 tst-barrier3 tst-barrier4 \
>  	tst-align tst-align3 \
>  	tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \
> diff --git a/nptl/Versions b/nptl/Versions
> index e7f691d..cd1806c 100644
> --- a/nptl/Versions
> +++ b/nptl/Versions
> @@ -277,6 +277,10 @@ libpthread {
>      cnd_timedwait; cnd_wait; tss_create; tss_delete; tss_get; tss_set;
>    }
>  
> +  GLIBC_2.30 {
> +    sem_clockwait;
> +  }
> +
>    GLIBC_PRIVATE {
>      __pthread_initialize_minimal;
>      __pthread_clock_gettime; __pthread_clock_settime;
> diff --git a/nptl/sem_clockwait.c b/nptl/sem_clockwait.c
> new file mode 100644
> index 0000000..c0cd667
> --- /dev/null
> +++ b/nptl/sem_clockwait.c
> @@ -0,0 +1,45 @@
> +/* sem_clockwait -- wait on a semaphore with timeout using
> +   the specified clock.
> +
> +   Copyright (C) 2003-2019 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
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include "sem_waitcommon.c"
> +
> +int
> +sem_clockwait (sem_t *sem, clockid_t clockid,
> +	       const struct timespec *abstime)
> +{
> +  /* Check that supplied clockid is one we support, even if we don't
> +     end up waiting. */
> +  if (!futex_abstimed_supported_clockid (clockid))
> +    {
> +      __set_errno (EINVAL);
> +      return -1;
> +    }
> +
> +  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
> +    {
> +      __set_errno (EINVAL);
> +      return -1;
> +    }



> +
> +  if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0)
> +    return 0;
> +  else
> +    return __new_sem_wait_slow ((struct new_sem *) sem, clockid, abstime);
> +}
> diff --git a/nptl/sem_timedwait.c b/nptl/sem_timedwait.c
> index 3dd71ab..0918d8b 100644
> --- a/nptl/sem_timedwait.c
> +++ b/nptl/sem_timedwait.c
> @@ -36,5 +36,6 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime)
>    if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0)
>      return 0;
>    else
> -    return __new_sem_wait_slow((struct new_sem *) sem, abstime);
> +    return __new_sem_wait_slow ((struct new_sem *) sem,
> +				CLOCK_REALTIME, abstime);
>  }
> diff --git a/nptl/sem_wait.c b/nptl/sem_wait.c
> index 6a2d26b..20a8b9d 100644
> --- a/nptl/sem_wait.c
> +++ b/nptl/sem_wait.c
> @@ -39,7 +39,8 @@ __new_sem_wait (sem_t *sem)
>    if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0)
>      return 0;
>    else
> -    return __new_sem_wait_slow((struct new_sem *) sem, NULL);
> +    return __new_sem_wait_slow ((struct new_sem *) sem,
> +				CLOCK_REALTIME, NULL);
>  }
>  versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1);
>  
> diff --git a/nptl/sem_waitcommon.c b/nptl/sem_waitcommon.c
> index 425d040..cad56e9 100644
> --- a/nptl/sem_waitcommon.c
> +++ b/nptl/sem_waitcommon.c
> @@ -103,19 +103,19 @@ __sem_wait_cleanup (void *arg)
>     users don't seem to need it.  */
>  static int
>  __attribute__ ((noinline))
> -do_futex_wait (struct new_sem *sem, const struct timespec *abstime)
> +do_futex_wait (struct new_sem *sem, clockid_t clockid,
> +	       const struct timespec *abstime)
>  {
>    int err;
>  
>  #if __HAVE_64B_ATOMICS
>    err = futex_abstimed_wait_cancelable (
>        (unsigned int *) &sem->data + SEM_VALUE_OFFSET, 0,
> -      CLOCK_REALTIME, abstime,
> +      clockid, abstime,
>        sem->private);
>  #else
>    err = futex_abstimed_wait_cancelable (&sem->value, SEM_NWAITERS_MASK,
> -					CLOCK_REALTIME, abstime,
> -					sem->private);
> +					clockid, abstime, sem->private);
>  #endif
>  
>    return err;
> @@ -162,7 +162,8 @@ __new_sem_wait_fast (struct new_sem *sem, int definitive_result)
>  /* Slow path that blocks.  */
>  static int
>  __attribute__ ((noinline))
> -__new_sem_wait_slow (struct new_sem *sem, const struct timespec *abstime)
> +__new_sem_wait_slow (struct new_sem *sem, clockid_t clockid,
> +		     const struct timespec *abstime)
>  {
>    int err = 0;
>  
> @@ -180,7 +181,7 @@ __new_sem_wait_slow (struct new_sem *sem, const struct timespec *abstime)
>        /* If there is no token available, sleep until there is.  */
>        if ((d & SEM_VALUE_MASK) == 0)
>  	{
> -	  err = do_futex_wait (sem, abstime);
> +	  err = do_futex_wait (sem, clockid, abstime);
>  	  /* A futex return value of 0 or EAGAIN is due to a real or spurious
>  	     wake-up, or due to a change in the number of tokens.  We retry in
>  	     these cases.
> @@ -281,7 +282,7 @@ __new_sem_wait_slow (struct new_sem *sem, const struct timespec *abstime)
>  	  if ((v >> SEM_VALUE_SHIFT) == 0)
>  	    {
>  	      /* See __HAVE_64B_ATOMICS variant.  */
> -	      err = do_futex_wait(sem, abstime);
> +	      err = do_futex_wait (sem, clockid, abstime);
>  	      if (err == ETIMEDOUT || err == EINTR)
>  		{
>  		  __set_errno (err);
> diff --git a/nptl/tst-sem13.c b/nptl/tst-sem13.c
> index 28d37ed..21c3b7e 100644
> --- a/nptl/tst-sem13.c
> +++ b/nptl/tst-sem13.c
> @@ -6,9 +6,14 @@
>  #include <internaltypes.h>
>  #include <support/check.h>
>  
> +/* A bogus clock value that tells run_test to use
> +   sem_timedwait rather than sem_clockwait */
> +#define CLOCK_USE_TIMEDWAIT (-1)
>  
> -static int
> -do_test (void)
> +typedef int (*waitfn_t)(sem_t *, struct timespec *);
> +
> +static void
> +do_test_wait (waitfn_t waitfn, const char *fnname)
>  {
>    union
>    {
> @@ -16,11 +21,13 @@ do_test (void)
>      struct new_sem ns;
>    } u;
>  
> +  printf ("do_test_wait: %s\n", fnname);
> +
>    TEST_COMPARE (sem_init (&u.s, 0, 0), 0);
>  
>    struct timespec ts = { 0, 1000000001 };	/* Invalid.  */
>    errno = 0;
> -  TEST_VERIFY_EXIT (sem_timedwait (&u.s, &ts) < 0);
> +  TEST_VERIFY_EXIT (waitfn (&u.s, &ts) < 0);
>    TEST_COMPARE (errno, EINVAL);
>  
>  #if __HAVE_64B_ATOMICS
> @@ -33,7 +40,7 @@ do_test (void)
>    ts.tv_sec = /* Invalid.  */ -2;
>    ts.tv_nsec = 0;
>    errno = 0;
> -  TEST_VERIFY_EXIT (sem_timedwait (&u.s, &ts) < 0);
> +  TEST_VERIFY_EXIT (waitfn (&u.s, &ts) < 0);
>    TEST_COMPARE (errno, ETIMEDOUT);
>  #if __HAVE_64B_ATOMICS
>    nwaiters = (u.ns.data >> SEM_NWAITERS_SHIFT);
> @@ -41,7 +48,31 @@ do_test (void)
>    nwaiters = u.ns.nwaiters;
>  #endif
>    TEST_COMPARE (nwaiters, 0);
> +}
>  
> +int test_sem_timedwait (sem_t *sem, struct timespec *ts)
> +{
> +  return sem_timedwait (sem, ts);
> +}
> +
> +int test_sem_clockwait_monotonic (sem_t *sem, struct timespec *ts)
> +{
> +  return sem_clockwait (sem, CLOCK_MONOTONIC, ts);
> +}
> +
> +int test_sem_clockwait_realtime (sem_t *sem, struct timespec *ts)
> +{
> +  return sem_clockwait (sem, CLOCK_REALTIME, ts);
> +}
> +
> +static int do_test (void)
> +{
> +  do_test_wait (&test_sem_timedwait,
> +                "sem_timedwait");
> +  do_test_wait (&test_sem_clockwait_monotonic,
> +                "sem_clockwait(monotonic)");
> +  do_test_wait (&test_sem_clockwait_realtime,
> +                "sem_clockwait(realtime)");
>    return 0;
>  }
>  
> diff --git a/nptl/tst-sem17.c b/nptl/tst-sem17.c
> new file mode 100644
> index 0000000..78c52c8
> --- /dev/null
> +++ b/nptl/tst-sem17.c
> @@ -0,0 +1,76 @@
> +/* Test unsupported/bad clocks passed to sem_clockwait.
> +
> +   Copyright (C) 2019 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
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <errno.h>
> +#include <semaphore.h>
> +#include <stdio.h>
> +#include <time.h>
> +#include <unistd.h>
> +#include <sys/time.h>
> +#include <support/check.h>
> +#include <support/timespec.h>
> +
> +
> +#define NOT_A_VALID_CLOCK 123456
> +
> +static int
> +do_test (void)
> +{
> +  sem_t s;
> +  TEST_COMPARE (sem_init (&s, 0, 1), 0);
> +
> +  const struct timespec ts = make_timespec (0, 0);
> +
> +  /* These clocks are meaningless to sem_clockwait. */
> +#if defined(CLOCK_PROCESS_CPUTIME_ID)
> +  TEST_COMPARE (sem_clockwait (&s, CLOCK_PROCESS_CPUTIME_ID, &ts), -1);
> +  TEST_COMPARE (errno, EINVAL);
> +#endif
> +#if defined(CLOCK_THREAD_CPUTIME_ID)
> +  TEST_COMPARE (sem_clockwait (&s, CLOCK_THREAD_CPUTIME_ID, &ts), -1);
> +  TEST_COMPARE (errno, EINVAL);
> +#endif
> +
> +  /* These clocks might be meaningful, but are currently unsupported
> +     by pthread_cond_clockwait. */
> +#if defined(CLOCK_REALTIME_COARSE)
> +  TEST_COMPARE (sem_clockwait (&s, CLOCK_REALTIME_COARSE, &ts), -1);
> +  TEST_COMPARE (errno, EINVAL);
> +#endif
> +#if defined(CLOCK_MONOTONIC_RAW)
> +  TEST_COMPARE (sem_clockwait (&s, CLOCK_MONOTONIC_RAW, &ts), -1);
> +  TEST_COMPARE (errno, EINVAL);
> +#endif
> +#if defined(CLOCK_MONOTONIC_COARSE)
> +  TEST_COMPARE (sem_clockwait (&s, CLOCK_MONOTONIC_COARSE, &ts), -1);
> +  TEST_COMPARE (errno, EINVAL);
> +#endif
> +#if defined(CLOCK_BOOTTIME)
> +  TEST_COMPARE (sem_clockwait (&s, CLOCK_BOOTTIME, &ts), -1);
> +  TEST_COMPARE (errno, EINVAL);
> +#endif
> +
> +  /* This is a completely invalid clock */
> +  TEST_COMPARE (sem_clockwait (&s, NOT_A_VALID_CLOCK, &ts), -1);
> +  TEST_COMPARE (errno, EINVAL);
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/nptl/tst-sem5.c b/nptl/tst-sem5.c
> index 396222b..843839b 100644
> --- a/nptl/tst-sem5.c
> +++ b/nptl/tst-sem5.c
> @@ -25,10 +25,15 @@
>  #include <support/timespec.h>
>  #include <support/xtime.h>
>  
> +/* A bogus clock value that tells run_test to use
> +   sem_timedwait rather than sem_clockwait */
> +#define CLOCK_USE_TIMEDWAIT (-1)
>  
> -static int
> -do_test (void)
> +static void
> +do_test_clock (clockid_t clockid)
>  {
> +  const clockid_t clockid_for_get =
> +    clockid == CLOCK_USE_TIMEDWAIT ? CLOCK_REALTIME : clockid;
>    sem_t s;
>    struct timespec ts;
>  
> @@ -36,14 +41,22 @@ do_test (void)
>    TEST_COMPARE (TEMP_FAILURE_RETRY (sem_wait (&s)), 0);
>  
>    /* We wait for half a second.  */
> -  xclock_gettime (CLOCK_REALTIME, &ts);
> +  xclock_gettime (clockid_for_get, &ts);
>    ts = timespec_add (ts, make_timespec (0, TIMESPEC_HZ/2));
>  
>    errno = 0;
> -  TEST_COMPARE (TEMP_FAILURE_RETRY (sem_timedwait (&s, &ts)), -1);
> +  TEST_COMPARE (TEMP_FAILURE_RETRY ((clockid == CLOCK_USE_TIMEDWAIT)
> +                                    ? sem_timedwait (&s, &ts)
> +                                    : sem_clockwait (&s, clockid, &ts)), -1);
>    TEST_COMPARE (errno, ETIMEDOUT);
> -  TEST_TIMESPEC_NOW_OR_AFTER (CLOCK_REALTIME, ts);
> +  TEST_TIMESPEC_NOW_OR_AFTER (clockid_for_get, ts);
> +}
>  
> +static int do_test (void)
> +{
> +  do_test_clock (CLOCK_USE_TIMEDWAIT);
> +  do_test_clock (CLOCK_REALTIME);
> +  do_test_clock (CLOCK_MONOTONIC);
>    return 0;
>  }
>  
> diff --git a/sysdeps/pthread/semaphore.h b/sysdeps/pthread/semaphore.h
> index 87c0543..6e74aa3 100644
> --- a/sysdeps/pthread/semaphore.h
> +++ b/sysdeps/pthread/semaphore.h
> @@ -64,6 +64,13 @@ extern int sem_timedwait (sem_t *__restrict __sem,
>    __nonnull ((1, 2));
>  #endif
>  
> +#ifdef __USE_GNU
> +extern int sem_clockwait (sem_t *__restrict __sem,
> +			  clockid_t clock,
> +			  const struct timespec *__restrict __abstime)
> +  __nonnull ((1, 3));
> +#endif
> +
>  /* Test whether SEM is posted.  */
>  extern int sem_trywait (sem_t *__sem) __THROWNL __nonnull ((1));
>  
> diff --git a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
> index 9a9e4ce..0294cb3 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
> @@ -243,3 +243,4 @@ GLIBC_2.28 tss_create F
>  GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
> +GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
> index b413007..1f63759 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
> @@ -227,6 +227,7 @@ GLIBC_2.28 tss_create F
>  GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
> +GLIBC_2.30 sem_clockwait F
>  GLIBC_2.3.2 pthread_cond_broadcast F
>  GLIBC_2.3.2 pthread_cond_destroy F
>  GLIBC_2.3.2 pthread_cond_init F

This is not in correct position, it should should be after GLIBC_2.3.2 entries.

> diff --git a/sysdeps/unix/sysv/linux/arm/libpthread.abilist b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
> index af82a4c..905392e 100644
> --- a/sysdeps/unix/sysv/linux/arm/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
> @@ -27,6 +27,7 @@ GLIBC_2.28 tss_create F
>  GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
> +GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 _IO_flockfile F
>  GLIBC_2.4 _IO_ftrylockfile F
>  GLIBC_2.4 _IO_funlockfile F
> diff --git a/sysdeps/unix/sysv/linux/csky/libpthread.abilist b/sysdeps/unix/sysv/linux/csky/libpthread.abilist
> index ea4b79a..fdf577c 100644
> --- a/sysdeps/unix/sysv/linux/csky/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/csky/libpthread.abilist
> @@ -233,3 +233,4 @@ GLIBC_2.29 tss_set F
>  GLIBC_2.29 wait F
>  GLIBC_2.29 waitpid F
>  GLIBC_2.29 write F
> +GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
> index bcba07f..fa02154 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
> @@ -245,6 +245,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
>  GLIBC_2.4 pthread_mutex_setprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/i386/libpthread.abilist b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
> index bece86d..86eb656 100644
> --- a/sysdeps/unix/sysv/linux/i386/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
> @@ -253,6 +253,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
>  GLIBC_2.4 pthread_mutex_setprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
> index ccc9449..406da6f 100644
> --- a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
> @@ -247,6 +247,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
>  GLIBC_2.4 pthread_mutex_setprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
> index af82a4c..905392e 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
> @@ -27,6 +27,7 @@ GLIBC_2.28 tss_create F
>  GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
> +GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 _IO_flockfile F
>  GLIBC_2.4 _IO_ftrylockfile F
>  GLIBC_2.4 _IO_funlockfile F
> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
> index bece86d..86eb656 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
> @@ -253,6 +253,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
>  GLIBC_2.4 pthread_mutex_setprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
> index 5067375..bd9455d 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
> @@ -243,3 +243,4 @@ GLIBC_2.28 tss_create F
>  GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
> +GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
> index 0214496..c1792c5 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
> @@ -255,6 +255,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
>  GLIBC_2.4 pthread_mutex_setprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
> index 0214496..c1792c5 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
> @@ -255,6 +255,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
>  GLIBC_2.4 pthread_mutex_setprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
> index 78cac2a..8eca3c2 100644
> --- a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
> @@ -241,3 +241,4 @@ GLIBC_2.28 tss_create F
>  GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
> +GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
> index 09e8447..ca68bd7 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
> @@ -255,6 +255,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.3.4 siglongjmp F
> +GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
>  GLIBC_2.4 pthread_mutex_setprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
> index 8300958..9e0500d 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
> @@ -246,6 +246,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.3.4 siglongjmp F
> +GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
>  GLIBC_2.4 pthread_mutex_setprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
> index 9a9e4ce..0294cb3 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
> @@ -243,3 +243,4 @@ GLIBC_2.28 tss_create F
>  GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
> +GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> index c370fda..c6bddf9 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> @@ -235,3 +235,4 @@ GLIBC_2.28 tss_create F
>  GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
> +GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
> index d05468f..581e3be 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
> @@ -255,6 +255,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
>  GLIBC_2.4 pthread_mutex_setprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
> index e8161aa..ed422c3 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
> @@ -247,6 +247,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
>  GLIBC_2.4 pthread_mutex_setprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/sh/libpthread.abilist b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
> index bcba07f..fa02154 100644
> --- a/sysdeps/unix/sysv/linux/sh/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
> @@ -245,6 +245,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
>  GLIBC_2.4 pthread_mutex_setprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
> index b413007..e31e905 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
> @@ -255,6 +255,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
>  GLIBC_2.4 pthread_mutex_setprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
> index ccc9449..406da6f 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
> @@ -247,6 +247,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
>  GLIBC_2.4 pthread_mutex_setprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> index 931c827..454d340 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> @@ -245,6 +245,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
>  GLIBC_2.4 pthread_mutex_setprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
> index c09c9b0..db565a1 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
> @@ -243,3 +243,4 @@ GLIBC_2.28 tss_create F
>  GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
> +GLIBC_2.30 sem_clockwait F
> 

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v4 05/12] nptl: Add POSIX-proposed sem_clockwait
  2019-06-21 16:02   ` Adhemerval Zanella
@ 2019-06-22 20:44     ` Mike Crowe
  0 siblings, 0 replies; 32+ messages in thread
From: Mike Crowe @ 2019-06-22 20:44 UTC (permalink / raw
  To: libc-alpha

On Friday 21 June 2019 at 13:02:42 -0300, Adhemerval Zanella wrote:
> 
> 
> On 18/06/2019 13:33, Mike Crowe wrote:
> > Add:
> > 
> >  int sem_clockwait (sem_t *sem, clockid_t clock, const struct timespec *abstime)
> > 
> > which behaves just like sem_timedwait, but measures abstime against the
> > specified clock. Currently supports CLOCK_REALTIME and CLOCK_MONOTONIC and
> > sets errno == EINVAL if any other clock is specified.
> > 
> > * nptl/sem_waitcommon.c (do_futex_wait, __new_sem_wait_slow): Add clockid
> >   parameters to indicate the clock which abstime should be measured
> >   against.
> > 
> > * nptl/sem_timedwait.c (sem_timedwait), nptl/sem_wait.c (__new_sem_wait):
> >   Pass CLOCK_REALTIME as clockid to __new_sem_wait_slow.
> > 
> > * nptl/sem_clockwait.c: New file to implement sem_clockwait based on
> >   sem_timedwait.c.
> > 
> > * nptl/Makefile: Add sem_clockwait.c source file. Add CFLAGS for
> >   sem_clockwait.c to match those used for sem_timedwait.c.
> > 
> > * sysdeps/pthread/semaphore.h: Add sem_clockwait.
> > 
> > * nptl/Versions (GLIBC_2.30): Likewise.
> > 
> > * sysdeps/unix/sysv/linux/aarch64/libpthread.abilist (GLIBC_2.30): Likewise.
> > * sysdeps/unix/sysv/linux/alpha/libpthread.abilist (GLIBC_2.30): Likewise.
> > * sysdeps/unix/sysv/linux/arm/libpthread.abilist (GLIBC_2.30): Likewise.
> > * sysdeps/unix/sysv/linux/csky/libpthread.abilist (GLIBC_2.30): Likewise.
> > * sysdeps/unix/sysv/linux/hppa/libpthread.abilist (GLIBC_2.30): Likewise.
> > * sysdeps/unix/sysv/linux/i386/libpthread.abilist (GLIBC_2.30): Likewise.
> > * sysdeps/unix/sysv/linux/ia64/libpthread.abilist (GLIBC_2.30): Likewise.
> > * sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist (GLIBC_2.30):
> >   Likewise.
> > * sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist (GLIBC_2.30):
> >   Likewise.
> > * sysdeps/unix/sysv/linux/microblaze/libpthread.abilist (GLIBC_2.30):
> >   Likewise.
> > * sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist (GLIBC_2.30):
> >   Likewise.
> > * sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist (GLIBC_2.30):
> >   Likewise.
> > * sysdeps/unix/sysv/linux/nios2/libpthread.abilist (GLIBC_2.30): Likewise.
> > * sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
> >   (GLIBC_2.30): Likewise.
> > * sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
> >   (GLIBC_2.30): Likewise.
> > * sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
> >   (GLIBC_2.30): Likewise.
> > * sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist	(GLIBC_2.30):
> >   Likewise.
> > * sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist (GLIBC_2.30):
> >   Likewise.
> > * sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist (GLIBC_2.30):
> >   Likewise.
> > * sysdeps/unix/sysv/linux/sh/libpthread.abilist (GLIBC_2.30): Likewise.
> > * sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist (GLIBC_2.30):
> >   Likewise.
> > * sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist (GLIBC_2.30):
> >   Likewise.
> > * sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist (GLIBC_2.30):
> >   Likewise.
> > * sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist (GLIBC_2.30):
> >   Likewise.
> > 
> > * nptl/tst-sem17.c: Add new test for passing invalid clock to
> >   sem_clockwait.
> > 
> > * nptl/tst-sem13.c, nptl/tst-sem5.c: Modify existing sem_timedwait tests to
> >   also test sem_clockwait.
> > 
> > * manual/threads.texi: Document sem_clockwait.
> 
> LGTM with just one nit below regarding alpha abilist (I will fix it prior
> push).

Thanks. I must have done alpha by hand a long time ago. I still need to
investigate the automated way to add these that you mentioned recently.

> The change seems to align with proposed Android addition [1].
>
> [1] https://android-review.googlesource.com/c/platform/bionic/+/958058

Yes. I've been coordinating with Tom. He's very keen to get these new
functions in too.

Mike.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions
  2019-06-19 19:33 ` [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions Adhemerval Zanella
@ 2019-06-22 21:11   ` Mike Crowe
  0 siblings, 0 replies; 32+ messages in thread
From: Mike Crowe @ 2019-06-22 21:11 UTC (permalink / raw
  To: libc-alpha

On Wednesday 19 June 2019 at 16:33:22 -0300, Adhemerval Zanella wrote:
> On 18/06/2019 13:33, Mike Crowe wrote:
> > The changes have been tested with "make check" and "make check-abi" on
> > x86, x86_64, arm and arm64. I've attempted to update the abilists for
> > all architectures, but cannot test all of them.
> 
> You can build compiler and glibcs using build-many-glibcs.py for all current
> supported targets and update automatically using the update-abi make rule
> inside the build directory. This can be run in cross-compile build.

Thanks. I'll try that.

> > I've compile-tested the powerpc and s390-specific implementations of
> > lll_clockwait. Although I've updated the sparc32-specific
> > implementation, I have been unable to test it since it appears that
> > even Debian hasn't supported sparc32 for nearly twenty years! I was
> > able to compile-test sparc64 though.

(It turns out that I misread the Debian Wiki page. It's only about ten
years. :-)

> 
> The gcc farm provides sparc64 machines with Debian 10 installed where
> you can test 32-bit build against it. The kernel will run in compat
> mode, similar to what i686 run in a x86_64 kernel. 

I was unaware of that. I've requested an account.

However, that made me realise that I could just use the Debian sparc64
cross compiler with -m32 (and apparently -mcpu=v9.) The build was
successful.

Thanks.

Mike.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v4 06/12] nptl: Add POSIX-proposed pthread_cond_clockwait
  2019-06-18 16:33 ` [PATCH v4 06/12] nptl: Add POSIX-proposed pthread_cond_clockwait Mike Crowe
@ 2019-06-24 19:35   ` Adhemerval Zanella
  0 siblings, 0 replies; 32+ messages in thread
From: Adhemerval Zanella @ 2019-06-24 19:35 UTC (permalink / raw
  To: libc-alpha



On 18/06/2019 13:33, Mike Crowe wrote:
> Add:
> 
>  int pthread_cond_clockwait (pthread_cond_t *cond,
>                              pthread_mutex_t *mutex,
>                              clockid_t clockid,
>                              const struct timespec *abstime)
> 
> which behaves just like pthread_cond_timedwait except it always measures
> abstime against the supplied clockid. Currently supports CLOCK_REALTIME and
> CLOCK_MONOTONIC and returns EINVAL if any other clock is specified.
> 
> Includes feedback from many others. This function was originally
> proposed[1] as pthread_cond_timedwaitonclock_np, but The Austin Group
> preferred the new name.
> 
> 	* nptl/Makefile: Add tst-cond26 and tst-cond27
> 
> 	* nptl/Versions (GLIBC_2.30): Add pthread_cond_clockwait
> 
> 	* sysdeps/nptl/pthread.h: Likewise
> 
> 	* nptl/forward.c: Add __pthread_cond_clockwait
> 
> 	* nptl/forward.c: Likewise
> 
> 	* nptl/pthreadP.h: Likewise
> 
> 	* sysdeps/nptl/pthread-functions.h: Likewise
> 
> 	* nptl/pthread_cond_wait.c (__pthread_cond_wait_common): Add
> 	clockid parameter and comment describing why we don't need to check
> 	its value. Use that value when calling
> 	futex_abstimed_wait_cancelable rather than reading the clock from
> 	the flags. (__pthread_cond_wait): Pass unused clockid parameter.
> 	(__pthread_cond_timedwait): Read clock from flags and pass it to
> 	__pthread_cond_wait_common. (__pthread_cond_clockwait): Add new
> 	function with weak alias from pthread_cond_clockwait.
> 
> 	* sysdeps/mach/hurd/i386/libpthread.abilist (GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/aarch64/libpthread.abilist (GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/alpha/libpthread.abilist (GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/arm/libpthread.abilist (GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/csky/libpthread.abilist (GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/hppa/libpthread.abilist (GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/i386/libpthread.abilist (GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/ia64/libpthread.abilist (GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/nios2/libpthread.abilist (GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/sh/libpthread.abilist (GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 
> 	* nptl/tst-cond11.c (run_test): Support testing
> 	pthread_cond_clockwait too by using a special magic
> 	CLOCK_USE_ATTR_CLOCK value to determine whether to call
> 	pthread_cond_timedwait or pthread_cond_clockwait. (do_test): Pass
> 	CLOCK_USE_ATTR_CLOCK for existing tests, and add new tests using
> 	all combinations of CLOCK_MONOTONIC and CLOCK_REALTIME.
> 
> 	* ntpl/tst-cond26.c: New test for passing unsupported and invalid
> 	clocks to pthread_cond_clockwait.
> 
> 	* nptl/tst-cond27.c: Add test similar to tst-cond5.c, but using
> 	struct timespec and pthread_cond_clockwait.
> 
> 	* manual/threads.texi: Document pthread_cond_clockwait. The comment
> 	was provided by Carlos O'Donell.
> 
> [1] https://sourceware.org/ml/libc-alpha/2015-07/msg00193.html

LGTM with just one nit below regarding alpha abilist (I will fix it prior
push).

> ---
>  ChangeLog                                                       | 85 +++++++-
>  manual/threads.texi                                             | 20 ++-
>  nptl/Makefile                                                   |  1 +-
>  nptl/Versions                                                   |  2 +-
>  nptl/forward.c                                                  |  5 +-
>  nptl/nptl-init.c                                                |  1 +-
>  nptl/pthreadP.h                                                 |  5 +-
>  nptl/pthread_cond_wait.c                                        | 44 +++-
>  nptl/tst-cond11.c                                               | 38 ++-
>  nptl/tst-cond26.c                                               | 77 ++++++-
>  nptl/tst-cond27.c                                               | 66 +++++-
>  sysdeps/nptl/pthread-functions.h                                |  4 +-
>  sysdeps/nptl/pthread.h                                          | 15 +-
>  sysdeps/unix/sysv/linux/aarch64/libpthread.abilist              |  1 +-
>  sysdeps/unix/sysv/linux/alpha/libpthread.abilist                |  1 +-
>  sysdeps/unix/sysv/linux/arm/libpthread.abilist                  |  1 +-
>  sysdeps/unix/sysv/linux/csky/libpthread.abilist                 |  1 +-
>  sysdeps/unix/sysv/linux/hppa/libpthread.abilist                 |  1 +-
>  sysdeps/unix/sysv/linux/i386/libpthread.abilist                 |  1 +-
>  sysdeps/unix/sysv/linux/ia64/libpthread.abilist                 |  1 +-
>  sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist        |  1 +-
>  sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist          |  1 +-
>  sysdeps/unix/sysv/linux/microblaze/libpthread.abilist           |  1 +-
>  sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist          |  1 +-
>  sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist          |  1 +-
>  sysdeps/unix/sysv/linux/nios2/libpthread.abilist                |  1 +-
>  sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist    |  1 +-
>  sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist |  1 +-
>  sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist |  1 +-
>  sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist           |  1 +-
>  sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist         |  1 +-
>  sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist         |  1 +-
>  sysdeps/unix/sysv/linux/sh/libpthread.abilist                   |  1 +-
>  sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist        |  1 +-
>  sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist        |  1 +-
>  sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist            |  1 +-
>  sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist           |  1 +-
>  37 files changed, 369 insertions(+), 18 deletions(-)
>  create mode 100644 nptl/tst-cond26.c
>  create mode 100644 nptl/tst-cond27.c
> 
> diff --git a/ChangeLog b/ChangeLog
> index 33502da..8386d5b 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,5 +1,90 @@
>  2019-05-27  Mike Crowe  <mac@mcrowe.com>
>  
> +	nptl: Add POSIX-proposed pthread_cond_clockwait which behaves just
> +	like pthread_cond_timedwait except it always measures abstime
> +	against the supplied clockid.
> +
> +	* nptl/Makefile: Add tst-cond26 and tst-cond27
> +
> +	* nptl/Versions (GLIBC_2.30): Add pthread_cond_clockwait
> +
> +	* sysdeps/nptl/pthread.h: Likewise
> +
> +	* nptl/forward.c: Add __pthread_cond_clockwait
> +
> +	* nptl/forward.c: Likewise
> +
> +	* nptl/pthreadP.h: Likewise
> +
> +	* sysdeps/nptl/pthread-functions.h: Likewise
> +
> +	* nptl/pthread_cond_wait.c (__pthread_cond_wait_common): Add
> +	clockid parameter and comment describing why we don't need to check
> +	its value. Use that value when calling
> +	futex_abstimed_wait_cancelable rather than reading the clock from
> +	the flags. (__pthread_cond_wait): Pass unused clockid parameter.
> +	(__pthread_cond_timedwait): Read clock from flags and pass it to
> +	__pthread_cond_wait_common. (__pthread_cond_clockwait): Add new
> +	function with weak alias from pthread_cond_clockwait.
> +
> +	* sysdeps/unix/sysv/linux/aarch64/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/alpha/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/arm/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/csky/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/hppa/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/i386/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/ia64/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/nios2/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/sh/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +
> +	* nptl/tst-cond11.c (run_test): Support testing
> +	pthread_cond_clockwait too by using a special magic
> +	CLOCK_USE_ATTR_CLOCK value to determine whether to call
> +	pthread_cond_timedwait or pthread_cond_clockwait. (do_test): Pass
> +	CLOCK_USE_ATTR_CLOCK for existing tests, and add new tests using
> +	all combinations of CLOCK_MONOTONIC and CLOCK_REALTIME.
> +
> +	* ntpl/tst-cond26.c: New test for passing unsupported and invalid
> +	clocks to pthread_cond_clockwait.
> +
> +	* nptl/tst-cond27.c: Add test similar to tst-cond5.c, but using
> +	struct timespec and pthread_cond_clockwait.
> +
> +	* manual/threads.texi: Document pthread_cond_clockwait. The comment
> +	was provided by Carlos O'Donell.
> +
> +2019-05-27  Mike Crowe  <mac@mcrowe.com>
> +
>  	nptl: Add POSIX-proposed sem_clockwait which behaves just like
>  	sem_timedwait, but measures abstime against the specified clock.
>  

Ok.

> diff --git a/manual/threads.texi b/manual/threads.texi
> index 674267c..91462f5 100644
> --- a/manual/threads.texi
> +++ b/manual/threads.texi
> @@ -679,6 +679,26 @@ against the clock specified by @var{clockid} rather than
>  @code{CLOCK_MONOTONIC} or @code{CLOCK_REALTIME}.
>  @end deftypefun
>  
> +@comment pthread.h
> +@comment POSIX-proposed
> +@deftypefun int pthread_cond_clockwait (pthread_cond_t *@var{cond}, pthread_mutex_t *@var{mutex},
> +                                        clockid_t @var{clockid}, const struct timespec *@var{abstime})
> +@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
> +@c If exactly the same function with arguments is called from a signal
> +@c handler that interrupts between the mutex unlock and sleep then it
> +@c will unlock the mutex twice resulting in undefined behaviour. Keep
> +@c in mind that the unlock and sleep are only atomic with respect to other
> +@c threads (really a happens-after relationship for pthread_cond_broadcast
> +@c and pthread_cond_signal).
> +@c In the AC case we would cancel the thread and the mutex would remain
> +@c locked and we can't recover from that.
> +Behaves like @code{pthread_cond_timedwait} except the time @var{abstime} is
> +measured against the clock specified by @var{clockid} rather than the clock
> +specified or defaulted when @code{pthread_cond_init} was called. Currently,
> +@var{clockid} must be either @code{CLOCK_MONOTONIC} or
> +@code{CLOCK_REALTIME}.
> +@end deftypefun
> +
>  @c FIXME these are undocumented:
>  @c pthread_atfork
>  @c pthread_attr_destroy

Ok.

> diff --git a/nptl/Makefile b/nptl/Makefile
> index 43a99dc..70a2139 100644
> --- a/nptl/Makefile
> +++ b/nptl/Makefile
> @@ -250,6 +250,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
>  	tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
>  	tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
>  	tst-cond20 tst-cond21 tst-cond22 tst-cond23 tst-cond24 tst-cond25 \
> +	tst-cond26 tst-cond27 \
>  	tst-cond-except \
>  	tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
>  	tst-robust6 tst-robust7 tst-robust8 tst-robust9 \

Ok.

> diff --git a/nptl/Versions b/nptl/Versions
> index cd1806c..8c094d0 100644
> --- a/nptl/Versions
> +++ b/nptl/Versions
> @@ -278,7 +278,7 @@ libpthread {
>    }
>  
>    GLIBC_2.30 {
> -    sem_clockwait;
> +    sem_clockwait; pthread_cond_clockwait;
>    }
>  
>    GLIBC_PRIVATE {

Ok.

> diff --git a/nptl/forward.c b/nptl/forward.c
> index ed1e7d0..50f358f 100644
> --- a/nptl/forward.c
> +++ b/nptl/forward.c
> @@ -164,6 +164,11 @@ FORWARD (__pthread_cond_timedwait,
>  	  const struct timespec *abstime), (cond, mutex, abstime), 0)
>  versioned_symbol (libc, __pthread_cond_timedwait, pthread_cond_timedwait,
>  		  GLIBC_2_3_2);
> +FORWARD (__pthread_cond_clockwait,
> +	 (pthread_cond_t *cond, pthread_mutex_t *mutex, clockid_t clockid,
> +	  const struct timespec *abstime), (cond, mutex, clockid, abstime),
> +	 0)
> +weak_alias (__pthread_cond_clockwait, pthread_cond_clockwait);
>  
>  
>  FORWARD (pthread_equal, (pthread_t thread1, pthread_t thread2),

Ok.

> diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c
> index 73935f8..9c2a3d7 100644
> --- a/nptl/nptl-init.c
> +++ b/nptl/nptl-init.c
> @@ -95,6 +95,7 @@ static const struct pthread_functions pthread_functions =
>      .ptr___pthread_cond_signal = __pthread_cond_signal,
>      .ptr___pthread_cond_wait = __pthread_cond_wait,
>      .ptr___pthread_cond_timedwait = __pthread_cond_timedwait,
> +    .ptr___pthread_cond_clockwait = __pthread_cond_clockwait,
>  # if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_3_2)
>      .ptr___pthread_cond_broadcast_2_0 = __pthread_cond_broadcast_2_0,
>      .ptr___pthread_cond_destroy_2_0 = __pthread_cond_destroy_2_0,

Ok.

> diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
> index 66527d8..d80662a 100644
> --- a/nptl/pthreadP.h
> +++ b/nptl/pthreadP.h
> @@ -449,6 +449,11 @@ extern int __pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);
>  extern int __pthread_cond_timedwait (pthread_cond_t *cond,
>  				     pthread_mutex_t *mutex,
>  				     const struct timespec *abstime);
> +extern int __pthread_cond_clockwait (pthread_cond_t *cond,
> +				     pthread_mutex_t *mutex,
> +				     clockid_t clockid,
> +				     const struct timespec *abstime)
> +  __nonnull ((1, 2, 4));
>  extern int __pthread_condattr_destroy (pthread_condattr_t *attr);
>  extern int __pthread_condattr_init (pthread_condattr_t *attr);
>  extern int __pthread_key_create (pthread_key_t *key, void (*destr) (void *));

Ok.

> diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
> index 7385562..558f930 100644
> --- a/nptl/pthread_cond_wait.c
> +++ b/nptl/pthread_cond_wait.c
> @@ -378,6 +378,7 @@ __condvar_cleanup_waiting (void *arg)
>  */
>  static __always_inline int
>  __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
> +    clockid_t clockid,
>      const struct timespec *abstime)
>  {
>    const int maxspin = 0;
> @@ -386,6 +387,11 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
>  
>    LIBC_PROBE (cond_wait, 2, cond, mutex);
>  
> +  /* clockid will already have been checked by
> +     __pthread_cond_clockwait or pthread_condattr_setclock, or we
> +     don't use it if abstime is NULL, so we don't need to check it
> +     here. */
> +
>    /* Acquire a position (SEQ) in the waiter sequence (WSEQ).  We use an
>       atomic operation because signals and broadcasts may update the group
>       switch without acquiring the mutex.  We do not need release MO here

Ok.

> @@ -511,10 +517,6 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
>  	        err = ETIMEDOUT;
>  	      else
>  		{
> -		  const clockid_t clockid =
> -		    ((flags & __PTHREAD_COND_CLOCK_MONOTONIC_MASK) != 0) ?
> -		    CLOCK_MONOTONIC : CLOCK_REALTIME;
> -
>  		  err = futex_abstimed_wait_cancelable
>                      (cond->__data.__g_signals + g, 0, clockid, abstime,
>                       private);

Ok.

> @@ -632,7 +634,8 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
>  int
>  __pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)
>  {
> -  return __pthread_cond_wait_common (cond, mutex, NULL);
> +  /* clockid is unused when abstime is NULL. */
> +  return __pthread_cond_wait_common (cond, mutex, 0, NULL);
>  }
>  
>  /* See __pthread_cond_wait_common.  */

Ok.

> @@ -644,10 +647,39 @@ __pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
>       it can assume that abstime is not NULL.  */
>    if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
>      return EINVAL;
> -  return __pthread_cond_wait_common (cond, mutex, abstime);
> +
> +  /* Relaxed MO is suffice because clock ID bit is only modified
> +     in condition creation.  */
> +  unsigned int flags = atomic_load_relaxed (&cond->__data.__wrefs);
> +  clockid_t clockid = (flags & __PTHREAD_COND_CLOCK_MONOTONIC_MASK)
> +                    ? CLOCK_MONOTONIC : CLOCK_REALTIME;
> +  return __pthread_cond_wait_common (cond, mutex, clockid, abstime);
> +}
> +
> +/* See __pthread_cond_wait_common.  */
> +int
> +__pthread_cond_clockwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
> +			  clockid_t clockid,
> +			  const struct timespec *abstime)
> +{
> +  /* Check parameter validity.  This should also tell the compiler that
> +     it can assume that abstime is not NULL.  */
> +  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
> +    return EINVAL;
> +
> +  if (!futex_abstimed_supported_clockid (clockid))
> +    return EINVAL;
> +
> +  /* If we do not support waiting using CLOCK_MONOTONIC, return an error.  */
> +  if (clockid == CLOCK_MONOTONIC
> +      && !futex_supports_exact_relative_timeouts ())
> +    return EINVAL;
> +
> +  return __pthread_cond_wait_common (cond, mutex, clockid, abstime);
>  }
>  
>  versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
>  		  GLIBC_2_3_2);
>  versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
>  		  GLIBC_2_3_2);
> +weak_alias (__pthread_cond_clockwait, pthread_cond_clockwait);

Ok (I will just move the versioned_symbol/weak_alias definition to be close to 
implementation).

> diff --git a/nptl/tst-cond11.c b/nptl/tst-cond11.c
> index 3bc4ff4..09346c6 100644
> --- a/nptl/tst-cond11.c
> +++ b/nptl/tst-cond11.c
> @@ -22,28 +22,32 @@
>  #include <time.h>
>  #include <unistd.h>
>  #include <support/check.h>
> +#include <support/test-driver.h>
>  #include <support/timespec.h>
>  #include <support/xthread.h>
>  #include <support/xtime.h>
>  
> +/* A bogus clock value that tells run_test to use
> +   pthread_cond_timedwait rather than pthread_condclockwait. */
> +#define CLOCK_USE_ATTR_CLOCK (-1)
>  
>  #if defined _POSIX_CLOCK_SELECTION && _POSIX_CLOCK_SELECTION >= 0
>  static int
> -run_test (clockid_t cl)
> +run_test (clockid_t attr_clock, clockid_t wait_clock)
>  {
>    pthread_condattr_t condattr;
>    pthread_cond_t cond;
>    pthread_mutexattr_t mutattr;
>    pthread_mutex_t mut;
>  
> -  printf ("clock = %d\n", (int) cl);
> +  verbose_printf ("attr_clock = %d\n", (int) attr_clock);
>  
>    TEST_COMPARE (pthread_condattr_init (&condattr), 0);
> -  TEST_COMPARE (pthread_condattr_setclock (&condattr, cl), 0);
> +  TEST_COMPARE (pthread_condattr_setclock (&condattr, attr_clock), 0);
>  
> -  clockid_t cl2;
> -  TEST_COMPARE (pthread_condattr_getclock (&condattr, &cl2), 0);
> -  TEST_COMPARE (cl, cl2);
> +  clockid_t attr_clock_read;
> +  TEST_COMPARE (pthread_condattr_getclock (&condattr, &attr_clock_read), 0);
> +  TEST_COMPARE (attr_clock, attr_clock_read);
>  
>    TEST_COMPARE (pthread_cond_init (&cond, &condattr), 0);
>    TEST_COMPARE (pthread_condattr_destroy (&condattr), 0);
> @@ -57,13 +61,20 @@ run_test (clockid_t cl)
>    TEST_COMPARE (pthread_mutex_lock (&mut), EDEADLK);
>  
>    struct timespec ts_timeout;
> -  xclock_gettime (cl, &ts_timeout);
> +  xclock_gettime (wait_clock == CLOCK_USE_ATTR_CLOCK ? attr_clock : wait_clock,
> +                  &ts_timeout);
>  
>    /* Wait one second.  */
>    ++ts_timeout.tv_sec;
>  
> -  TEST_COMPARE (pthread_cond_timedwait (&cond, &mut, &ts_timeout), ETIMEDOUT);
> -  TEST_TIMESPEC_BEFORE_NOW (ts_timeout, cl);
> +  if (wait_clock == CLOCK_USE_ATTR_CLOCK) {
> +    TEST_COMPARE (pthread_cond_timedwait (&cond, &mut, &ts_timeout), ETIMEDOUT);
> +    TEST_TIMESPEC_BEFORE_NOW (ts_timeout, attr_clock);
> +  } else {
> +    TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, wait_clock, &ts_timeout),
> +                  ETIMEDOUT);
> +    TEST_TIMESPEC_BEFORE_NOW (ts_timeout, wait_clock);
> +  }
>  
>    xpthread_mutex_unlock (&mut);
>    xpthread_mutex_destroy (&mut);
> @@ -83,7 +94,7 @@ do_test (void)
>  
>  #else
>  
> -  run_test (CLOCK_REALTIME);
> +  run_test (CLOCK_REALTIME, CLOCK_USE_ATTR_CLOCK);
>  
>  # if defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0
>  #  if _POSIX_MONOTONIC_CLOCK == 0
> @@ -93,8 +104,13 @@ do_test (void)
>    else if (e == 0)
>        FAIL_RET ("sysconf (_SC_MONOTONIC_CLOCK) must not return 0");
>    else
> +    {
>  #  endif
> -    run_test (CLOCK_MONOTONIC);
> +      run_test (CLOCK_MONOTONIC, CLOCK_USE_ATTR_CLOCK);
> +      run_test (CLOCK_REALTIME, CLOCK_MONOTONIC);
> +      run_test (CLOCK_MONOTONIC, CLOCK_MONOTONIC);
> +      run_test (CLOCK_MONOTONIC, CLOCK_REALTIME);
> +    }
>  # else
>    puts ("_POSIX_MONOTONIC_CLOCK not defined");
>  # endif

Ok.

> diff --git a/nptl/tst-cond26.c b/nptl/tst-cond26.c
> new file mode 100644
> index 0000000..2db7d2e
> --- /dev/null
> +++ b/nptl/tst-cond26.c
> @@ -0,0 +1,77 @@
> +/* Test unsupported/bad clocks passed to pthread_cond_clockwait.
> +
> +   Copyright (C) 2019 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
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <errno.h>
> +#include <pthread.h>
> +#include <stdio.h>
> +#include <time.h>
> +#include <unistd.h>
> +#include <support/check.h>
> +#include <support/timespec.h>
> +#include <support/xthread.h>
> +
> +static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
> +static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
> +
> +#define NOT_A_VALID_CLOCK 123456
> +
> +static int
> +do_test (void)
> +{
> +  xpthread_mutex_lock (&mut);
> +
> +  const struct timespec ts = make_timespec (0, 0);
> +
> +  /* These clocks are meaningless to sem_clockwait. */
> +#if defined(CLOCK_PROCESS_CPUTIME_ID)
> +  TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
> +                                        CLOCK_PROCESS_CPUTIME_ID, &ts), EINVAL);
> +#endif
> +#if defined(CLOCK_THREAD_CPUTIME_ID)
> +  TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
> +                                        CLOCK_THREAD_CPUTIME_ID, &ts), EINVAL);
> +#endif
> +
> +  /* These clocks might be meaningful, but are currently unsupported
> +     by pthread_cond_clockwait. */
> +#if defined(CLOCK_REALTIME_COARSE)
> +  TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
> +                                        CLOCK_REALTIME_COARSE, &ts), EINVAL);
> +#endif
> +#if defined(CLOCK_MONOTONIC_RAW)
> +  TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
> +                                        CLOCK_MONOTONIC_RAW, &ts), EINVAL);
> +#endif
> +#if defined(CLOCK_MONOTONIC_COARSE)
> +  TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
> +                                        CLOCK_MONOTONIC_COARSE, &ts), EINVAL);
> +#endif
> +#if defined(CLOCK_BOOTTIME)
> +  TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
> +                                        CLOCK_BOOTTIME, &ts), EINVAL);
> +#endif
> +
> +  /* This is a completely invalid clock */
> +  TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
> +                                        NOT_A_VALID_CLOCK, &ts), EINVAL);
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>

Ok.

> diff --git a/nptl/tst-cond27.c b/nptl/tst-cond27.c
> new file mode 100644
> index 0000000..0f18821
> --- /dev/null
> +++ b/nptl/tst-cond27.c
> @@ -0,0 +1,66 @@
> +/* Test pthread_cond_clockwait timeout.
> +
> +   Copyright (C) 2019 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
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <errno.h>
> +#include <pthread.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <time.h>
> +#include <sys/time.h>
> +#include <support/check.h>
> +#include <support/timespec.h>
> +#include <support/xthread.h>
> +
> +
> +static pthread_mutex_t mut = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
> +static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
> +
> +
> +static int
> +do_test_clock (clockid_t clockid)
> +{
> +  /* Get the mutex.  */
> +  xpthread_mutex_lock (&mut);
> +
> +  /* Waiting for the condition will fail.  But we want the timeout here.  */
> +  const struct timespec ts_now = xclock_now (clockid);
> +  const struct timespec ts_timeout =
> +    timespec_add (ts_now, make_timespec (0, 500000000));
> +
> +  /* In theory pthread_cond_clockwait could return zero here due to
> +     spurious wakeup. However that can't happen without a signal or an
> +     additional waiter. */
> +  TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, clockid, &ts_timeout),
> +                ETIMEDOUT);
> +
> +  xpthread_mutex_unlock (&mut);
> +
> +  return 0;
> +}
> +
> +static int
> +do_test (void)
> +{
> +  do_test_clock (CLOCK_MONOTONIC);
> +  do_test_clock (CLOCK_REALTIME);
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>

Ok.

> diff --git a/sysdeps/nptl/pthread-functions.h b/sysdeps/nptl/pthread-functions.h
> index cd5e94d..cfa9660 100644
> --- a/sysdeps/nptl/pthread-functions.h
> +++ b/sysdeps/nptl/pthread-functions.h
> @@ -55,6 +55,10 @@ struct pthread_functions
>    int (*ptr___pthread_cond_wait) (pthread_cond_t *, pthread_mutex_t *);
>    int (*ptr___pthread_cond_timedwait) (pthread_cond_t *, pthread_mutex_t *,
>  				       const struct timespec *);
> +  int (*ptr___pthread_cond_clockwait) (pthread_cond_t *,
> +				       pthread_mutex_t *,
> +				       clockid_t,
> +				       const struct timespec *);
>    int (*ptr___pthread_cond_broadcast_2_0) (pthread_cond_2_0_t *);
>    int (*ptr___pthread_cond_destroy_2_0) (pthread_cond_2_0_t *);
>    int (*ptr___pthread_cond_init_2_0) (pthread_cond_2_0_t *,

Ok.

> diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
> index 704a3c4..f000b1e 100644
> --- a/sysdeps/nptl/pthread.h
> +++ b/sysdeps/nptl/pthread.h
> @@ -1003,6 +1003,21 @@ extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,
>  				   const struct timespec *__restrict __abstime)
>       __nonnull ((1, 2, 3));
>  
> +# ifdef __USE_GNU
> +/* Wait for condition variable COND to be signaled or broadcast until
> +   ABSTIME measured by the specified clock. MUTEX is assumed to be
> +   locked before. CLOCK is the clock to use. ABSTIME is an absolute
> +   time specification against CLOCK's epoch.
> +
> +   This function is a cancellation point and therefore not marked with
> +   __THROW. */
> +extern int pthread_cond_clockwait (pthread_cond_t *__restrict __cond,
> +				   pthread_mutex_t *__restrict __mutex,
> +				   __clockid_t __clock_id,
> +				   const struct timespec *__restrict __abstime)
> +     __nonnull ((1, 2, 4));
> +# endif
> +
>  /* Functions for handling condition variable attributes.  */
>  
>  /* Initialize condition variable attribute ATTR.  */

Ok.

> diff --git a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
> index 0294cb3..5af4b8a 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
> @@ -243,4 +243,5 @@ GLIBC_2.28 tss_create F
>  GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
> index 1f63759..a00adfb 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
> @@ -227,6 +227,7 @@ GLIBC_2.28 tss_create F
>  GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.3.2 pthread_cond_broadcast F
>  GLIBC_2.3.2 pthread_cond_destroy F

Same issue as before, but I will fix it.

> diff --git a/sysdeps/unix/sysv/linux/arm/libpthread.abilist b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
> index 905392e..4aeee7b 100644
> --- a/sysdeps/unix/sysv/linux/arm/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
> @@ -27,6 +27,7 @@ GLIBC_2.28 tss_create F
>  GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 _IO_flockfile F
>  GLIBC_2.4 _IO_ftrylockfile F
> diff --git a/sysdeps/unix/sysv/linux/csky/libpthread.abilist b/sysdeps/unix/sysv/linux/csky/libpthread.abilist
> index fdf577c..2c08b76 100644
> --- a/sysdeps/unix/sysv/linux/csky/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/csky/libpthread.abilist
> @@ -233,4 +233,5 @@ GLIBC_2.29 tss_set F
>  GLIBC_2.29 wait F
>  GLIBC_2.29 waitpid F
>  GLIBC_2.29 write F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
> index fa02154..dc0d4ad 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
> @@ -245,6 +245,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/i386/libpthread.abilist b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
> index 86eb656..1830e40 100644
> --- a/sysdeps/unix/sysv/linux/i386/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
> @@ -253,6 +253,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
> index 406da6f..0811d73 100644
> --- a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
> @@ -247,6 +247,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
> index 905392e..4aeee7b 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
> @@ -27,6 +27,7 @@ GLIBC_2.28 tss_create F
>  GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 _IO_flockfile F
>  GLIBC_2.4 _IO_ftrylockfile F
> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
> index 86eb656..1830e40 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
> @@ -253,6 +253,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
> index bd9455d..f2be6b4 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
> @@ -243,4 +243,5 @@ GLIBC_2.28 tss_create F
>  GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
> index c1792c5..41527fe 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
> @@ -255,6 +255,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
> index c1792c5..41527fe 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
> @@ -255,6 +255,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
> index 8eca3c2..04fc3a6 100644
> --- a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
> @@ -241,4 +241,5 @@ GLIBC_2.28 tss_create F
>  GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
> index ca68bd7..ebdab1a 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
> @@ -255,6 +255,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.3.4 siglongjmp F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
> index 9e0500d..8a1fb34 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
> @@ -246,6 +246,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.3.4 siglongjmp F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
> index 0294cb3..5af4b8a 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
> @@ -243,4 +243,5 @@ GLIBC_2.28 tss_create F
>  GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> index c6bddf9..a1c8c2e 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> @@ -235,4 +235,5 @@ GLIBC_2.28 tss_create F
>  GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
> index 581e3be..0feb3cf 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
> @@ -255,6 +255,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
> index ed422c3..cc4f160 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
> @@ -247,6 +247,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/sh/libpthread.abilist b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
> index fa02154..dc0d4ad 100644
> --- a/sysdeps/unix/sysv/linux/sh/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
> @@ -245,6 +245,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
> index e31e905..ed0574a 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
> @@ -255,6 +255,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
> index 406da6f..0811d73 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
> @@ -247,6 +247,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> index 454d340..aaa1c3b 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> @@ -245,6 +245,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
>  GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
> index db565a1..5d02b03 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
> @@ -243,4 +243,5 @@ GLIBC_2.28 tss_create F
>  GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
> +GLIBC_2.30 pthread_cond_clockwait F
>  GLIBC_2.30 sem_clockwait F
> 

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v4 07/12] nptl: pthread_rwlock: Move timeout validation into _full functions
  2019-06-18 16:33 ` [PATCH v4 07/12] nptl: pthread_rwlock: Move timeout validation into _full functions Mike Crowe
@ 2019-06-25 20:42   ` Adhemerval Zanella
  0 siblings, 0 replies; 32+ messages in thread
From: Adhemerval Zanella @ 2019-06-25 20:42 UTC (permalink / raw
  To: libc-alpha



On 18/06/2019 13:33, Mike Crowe wrote:
> As recommended by the comments in the implementations of
> pthread_rwlock_timedrdlock and pthread_rwlock_timedwrlock, let's move the
> timeout validity checks into the corresponding pthread_rwlock_rdlock_full
> and pthread_rwlock_wrlock_full functions. Since these functions may be
> called with abstime == NULL, an extra check for that is necessary too.
> 
> 	* nptl/pthread_rwlock_common.c (__pthread_rwlock_rdlock_full):
> 	Check validity of abstime parameter.
> 	(__pthread_rwlock_rwlock_full): Likewise.
> 
> 	* nptl/pthread_rwlock_timedrdlock.c (pthread_rwlock_timedrdlock):
> 	Remove check for validity of abstime parameter.
> 
> 	* nptl/pthread_rwlock_timedwrlock.c (pthread_rwlock_timedwrlock):
> 	Likewise.

LGTM, I will commit this for you.

> ---
>  ChangeLog                         | 14 ++++++++++++++
>  nptl/pthread_rwlock_common.c      | 20 ++++++++++++++++++++
>  nptl/pthread_rwlock_timedrdlock.c | 10 ----------
>  nptl/pthread_rwlock_timedwrlock.c | 10 ----------
>  4 files changed, 34 insertions(+), 20 deletions(-)
> 
> diff --git a/ChangeLog b/ChangeLog
> index 8386d5b..452d047 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,5 +1,19 @@
>  2019-05-27  Mike Crowe  <mac@mcrowe.com>
>  
> +	nptl: pthread_rwlock: Move timeout validation into _full functions
> +
> +	* nptl/pthread_rwlock_common.c (__pthread_rwlock_rdlock_full):
> +	Check validity of abstime parameter.
> +	(__pthread_rwlock_rwlock_full): Likewise.
> +
> +	* nptl/pthread_rwlock_timedrdlock.c (pthread_rwlock_timedrdlock):
> +	Remove check for validity of abstime parameter.
> +
> +	* nptl/pthread_rwlock_timedwrlock.c (pthread_rwlock_timedwrlock):
> +	Likewise.
> +
> +2019-05-27  Mike Crowe  <mac@mcrowe.com>
> +
>  	nptl: Add POSIX-proposed pthread_cond_clockwait which behaves just
>  	like pthread_cond_timedwait except it always measures abstime
>  	against the supplied clockid.
> diff --git a/nptl/pthread_rwlock_common.c b/nptl/pthread_rwlock_common.c
> index 89ba21a..120b880 100644
> --- a/nptl/pthread_rwlock_common.c
> +++ b/nptl/pthread_rwlock_common.c
> @@ -282,6 +282,16 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
>  {
>    unsigned int r;
>  
> +  /* Make sure any passed in timeout value is valid.  Note that the previous
> +     implementation assumed that this check *must* not be performed if there
> +     would in fact be no blocking; however, POSIX only requires that "the
> +     validity of the abstime parameter need not be checked if the lock can be
> +     immediately acquired" (i.e., we need not but may check it).  */
> +  if (abstime
> +      && __glibc_unlikely (abstime->tv_nsec >= 1000000000
> +      || abstime->tv_nsec < 0))
> +    return EINVAL;
> +
>    /* Make sure we are not holding the rwlock as a writer.  This is a deadlock
>       situation we recognize and report.  */
>    if (__glibc_unlikely (atomic_load_relaxed (&rwlock->__data.__cur_writer)
> @@ -576,6 +586,16 @@ static __always_inline int
>  __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
>      const struct timespec *abstime)
>  {
> +  /* Make sure any passed in timeout value is valid.  Note that the previous
> +     implementation assumed that this check *must* not be performed if there
> +     would in fact be no blocking; however, POSIX only requires that "the
> +     validity of the abstime parameter need not be checked if the lock can be
> +     immediately acquired" (i.e., we need not but may check it).  */
> +  if (abstime
> +      && __glibc_unlikely (abstime->tv_nsec >= 1000000000
> +      || abstime->tv_nsec < 0))
> +    return EINVAL;
> +
>    /* Make sure we are not holding the rwlock as a writer.  This is a deadlock
>       situation we recognize and report.  */
>    if (__glibc_unlikely (atomic_load_relaxed (&rwlock->__data.__cur_writer)
> diff --git a/nptl/pthread_rwlock_timedrdlock.c b/nptl/pthread_rwlock_timedrdlock.c
> index aa00530..84c1983 100644
> --- a/nptl/pthread_rwlock_timedrdlock.c
> +++ b/nptl/pthread_rwlock_timedrdlock.c
> @@ -23,15 +23,5 @@ int
>  pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock,
>      const struct timespec *abstime)
>  {
> -  /* Make sure the passed in timeout value is valid.  Note that the previous
> -     implementation assumed that this check *must* not be performed if there
> -     would in fact be no blocking; however, POSIX only requires that "the
> -     validity of the abstime parameter need not be checked if the lock can be
> -     immediately acquired" (i.e., we need not but may check it).  */
> -  /* ??? Just move this to __pthread_rwlock_rdlock_full?  */
> -  if (__glibc_unlikely (abstime->tv_nsec >= 1000000000
> -      || abstime->tv_nsec < 0))
> -    return EINVAL;
> -
>    return __pthread_rwlock_rdlock_full (rwlock, abstime);
>  }
> diff --git a/nptl/pthread_rwlock_timedwrlock.c b/nptl/pthread_rwlock_timedwrlock.c
> index 3c92e44..f0b745d 100644
> --- a/nptl/pthread_rwlock_timedwrlock.c
> +++ b/nptl/pthread_rwlock_timedwrlock.c
> @@ -23,15 +23,5 @@ int
>  pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock,
>      const struct timespec *abstime)
>  {
> -  /* Make sure the passed in timeout value is valid.  Note that the previous
> -     implementation assumed that this check *must* not be performed if there
> -     would in fact be no blocking; however, POSIX only requires that "the
> -     validity of the abstime parameter need not be checked if the lock can be
> -     immediately acquired" (i.e., we need not but may check it).  */
> -  /* ??? Just move this to __pthread_rwlock_wrlock_full?  */
> -  if (__glibc_unlikely (abstime->tv_nsec >= 1000000000
> -      || abstime->tv_nsec < 0))
> -    return EINVAL;
> -
>    return __pthread_rwlock_wrlock_full (rwlock, abstime);
>  }
> 

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v4 08/12] nptl: Add POSIX-proposed pthread_rwlock_clockrdlock & pthread_rwlock_clockwrlock
  2019-06-18 16:33 ` [PATCH v4 08/12] nptl: Add POSIX-proposed pthread_rwlock_clockrdlock & pthread_rwlock_clockwrlock Mike Crowe
@ 2019-06-25 21:26   ` Adhemerval Zanella
  0 siblings, 0 replies; 32+ messages in thread
From: Adhemerval Zanella @ 2019-06-25 21:26 UTC (permalink / raw
  To: libc-alpha



On 18/06/2019 13:33, Mike Crowe wrote:
> Add:
>  int pthread_rwlock_clockrdlock (pthread_rwlock_t *rwlock,
>                                  clockid_t clockid,
>                                  const struct timespec *abstime)
> and:
>  int pthread_rwlock_clockwrlock (pthread_rwlock_t *rwlock,
>                                  clockid_t clockid,
>                                  const struct timespec *abstime)
> 
> which behave like pthread_rwlock_timedrdlock and pthread_rwlock_timedwrlock
> respectively, except they always measure abstime against the supplied
> clockid. The functions currently support CLOCK_REALTIME and CLOCK_MONOTONIC
> and return EINVAL if any other clock is specified.

LGTM with smalls nits regarding comments.

> 
> 	* sysdeps/nptl/pthread.h: Add pthread_rwlock_clockrdlock and
> 	pthread_wrlock_clockwrlock.
> 
> 	* nptl/Makefile: Build pthread_rwlock_clockrdlock.c and
> 	pthread_rwlock_clockwrlock.c.
> 
> 	* nptl/pthread_rwlock_clockrdlock.c: Implement
> 	pthread_rwlock_clockrdlock.
> 
> 	* nptl/pthread_rwlock_clockwrlock.c: Implement
> 	pthread_rwlock_clockwrlock.
> 
> 	* nptl/pthread_rwlock_common.c (__pthread_rwlock_rdlock_full): Add
> 	clockid parameter and verify that it indicates a supported clock on
> 	entry so that we fail even if it doesn't end up being used. Pass
> 	that clock on to futex_abstimed_wait when necessary.
> 	(__pthread_rwlock_wrlock_full): Likewise.
> 
> 	* nptl/pthread_rwlock_rdlock.c: (__pthread_rwlock_rdlock): Pass
> 	CLOCK_REALTIME to __pthread_rwlock_rdlock_full even though it won't
> 	be used because there's no timeout.
> 
> 	* nptl/pthread_rwlock_wrlock.c (__pthread_rwlock_wrlock): Pass
> 	CLOCK_REALTIME to __pthread_rwlock_wrlock_full even though it won't
> 	be used because there is no timeout.
> 
> 	* nptl/pthread_rwlock_timedrdlock.c (pthread_rwlock_timedrdlock):
> 	Pass CLOCK_REALTIME to __pthread_rwlock_rdlock_full since abstime
> 	uses that clock.
> 
> 	* nptl/pthread_rwlock_timedwrlock.c (pthread_rwlock_timedwrlock):
> 	Pass CLOCK_REALTIME to __pthread_rwlock_wrlock_full since abstime
> 	uses that clock.
> 
> 	* sysdeps/mach/hurd/i386/libpthread.abilist (GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/aarch64/libpthread.abilist (GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/alpha/libpthread.abilist (GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/arm/libpthread.abilist (GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/csky/libpthread.abilist (GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/hppa/libpthread.abilist (GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/i386/libpthread.abilist (GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/ia64/libpthread.abilist (GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/nios2/libpthread.abilist (GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/sh/libpthread.abilist (GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 	* sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
> 	(GLIBC_2.30): Likewise.
> 
> 	* nptl/tst-abstime.c (th): Add pthread_rwlock_clockrdlock and
> 	pthread_rwlock_clockwrlock timeout tests to match the existing
> 	pthread_rwlock_timedrdloock and pthread_rwlock_timedwrlock tests.
> 
> 	* nptl/tst-rwlock14.c (do_test): Likewise.
> 
> 	* nptl/tst-rwlock6.c Invent verbose_printf macro, and use for
> 	ancillary output throughout. (tf): Accept thread_args structure so
> 	that rwlock, a clockid and function name can be passed to the
> 	thread. (do_test_clock): Rename from do_test. Accept clockid
> 	parameter to specify test clock. Use the magic clockid value of
> 	CLOCK_USE_TIMEDLOCK to indicate that pthread_rwlock_timedrdlock and
> 	pthread_rwlock_timedwrlock should be tested, otherwise pass the
> 	specified clockid to pthread_rwlock_clockrdlock and
> 	pthread_rwlock_clockwrlock. Use xpthread_create and xpthread_join.
> 	(do_test): Call do_test_clock to test each clockid in turn.
> 
> 	* nptl/tst-rwlock7.c: Likewise.
> 
> 	* nptl/tst-rwlock9.c (writer_thread, reader_thread): Accept
> 	thread_args structure so that the (now int) thread number, the
> 	clockid and the function name can be passed to the thread.
> 	(do_test_clock): Renamed from do_test. Pass the necessary
> 	thread_args when creating the reader and writer threads. Use
> 	xpthread_create and xpthread_join.
> 	(do_test): Call do_test_clock to test each clockid in turn.
> 
> 	* manual/threads.texi: Add documentation for
> 	pthread_rwlock_clockrdlock and pthread_rwlock_clockwrclock.
> ---
>  ChangeLog                                                       | 114 +++++++-
>  manual/threads.texi                                             |  28 ++-
>  nptl/Makefile                                                   |   2 +-
>  nptl/Versions                                                   |   1 +-
>  nptl/pthread_rwlock_clockrdlock.c                               |  29 ++-
>  nptl/pthread_rwlock_clockwrlock.c                               |  29 ++-
>  nptl/pthread_rwlock_common.c                                    |  40 +-
>  nptl/pthread_rwlock_rdlock.c                                    |   2 +-
>  nptl/pthread_rwlock_timedrdlock.c                               |   2 +-
>  nptl/pthread_rwlock_timedwrlock.c                               |   2 +-
>  nptl/pthread_rwlock_wrlock.c                                    |   2 +-
>  nptl/tst-abstime.c                                              |   8 +-
>  nptl/tst-rwlock14.c                                             |  12 +-
>  nptl/tst-rwlock6.c                                              |  95 ++++--
>  nptl/tst-rwlock7.c                                              |  83 +++--
>  nptl/tst-rwlock9.c                                              | 102 ++++--
>  sysdeps/nptl/pthread.h                                          |  14 +-
>  sysdeps/unix/sysv/linux/aarch64/libpthread.abilist              |   2 +-
>  sysdeps/unix/sysv/linux/alpha/libpthread.abilist                |   2 +-
>  sysdeps/unix/sysv/linux/arm/libpthread.abilist                  |   2 +-
>  sysdeps/unix/sysv/linux/csky/libpthread.abilist                 |   2 +-
>  sysdeps/unix/sysv/linux/hppa/libpthread.abilist                 |   2 +-
>  sysdeps/unix/sysv/linux/i386/libpthread.abilist                 |   2 +-
>  sysdeps/unix/sysv/linux/ia64/libpthread.abilist                 |   2 +-
>  sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist        |   2 +-
>  sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist          |   2 +-
>  sysdeps/unix/sysv/linux/microblaze/libpthread.abilist           |   2 +-
>  sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist          |   2 +-
>  sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist          |   2 +-
>  sysdeps/unix/sysv/linux/nios2/libpthread.abilist                |   2 +-
>  sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist    |   2 +-
>  sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist |   2 +-
>  sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist |   2 +-
>  sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist           |   2 +-
>  sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist         |   2 +-
>  sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist         |   2 +-
>  sysdeps/unix/sysv/linux/sh/libpthread.abilist                   |   2 +-
>  sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist        |   2 +-
>  sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist        |   2 +-
>  sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist            |   2 +-
>  sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist           |   2 +-
>  41 files changed, 513 insertions(+), 100 deletions(-)
>  create mode 100644 nptl/pthread_rwlock_clockrdlock.c
>  create mode 100644 nptl/pthread_rwlock_clockwrlock.c
> 
> diff --git a/ChangeLog b/ChangeLog
> index 452d047..bd84ee4 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,5 +1,119 @@
>  2019-05-27  Mike Crowe  <mac@mcrowe.com>
>  
> +	nptl: Add POSIX-proposed pthread_rwlock_clockrdlock &
> +	pthread_rwlock_clockwrlock which behave like
> +	pthread_rwlock_timedrdlock and pthread_rwlock_timedwrlock
> +	respectively, except they always measure abstime against the
> +	supplied clockid. The functions currently support CLOCK_REALTIME
> +	and CLOCK_MONOTONIC and return EINVAL if any other clock is
> +	specified.
> +
> +	* sysdeps/nptl/pthread.h: Add pthread_rwlock_clockrdlock and
> +	pthread_wrlock_clockwrlock.
> +
> +	* nptl/Makefile: Build pthread_rwlock_clockrdlock.c and
> +	pthread_rwlock_clockwrlock.c.
> +
> +	* nptl/pthread_rwlock_clockrdlock.c: Implement
> +	pthread_rwlock_clockrdlock.
> +
> +	* nptl/pthread_rwlock_clockwrlock.c: Implement
> +	pthread_rwlock_clockwrlock.
> +
> +	* nptl/pthread_rwlock_common.c (__pthread_rwlock_rdlock_full): Add
> +	clockid parameter and verify that it indicates a supported clock on
> +	entry so that we fail even if it doesn't end up being used. Pass
> +	that clock on to futex_abstimed_wait when necessary.
> +	(__pthread_rwlock_wrlock_full): Likewise.
> +
> +	* nptl/pthread_rwlock_rdlock.c: (__pthread_rwlock_rdlock): Pass
> +	CLOCK_REALTIME to __pthread_rwlock_rdlock_full even though it won't
> +	be used because there's no timeout.
> +
> +	* nptl/pthread_rwlock_wrlock.c (__pthread_rwlock_wrlock): Pass
> +	CLOCK_REALTIME to __pthread_rwlock_wrlock_full even though it won't
> +	be used because there is no timeout.
> +
> +	* nptl/pthread_rwlock_timedrdlock.c (pthread_rwlock_timedrdlock):
> +	Pass CLOCK_REALTIME to __pthread_rwlock_rdlock_full since abstime
> +	uses that clock.
> +
> +	* nptl/pthread_rwlock_timedwrlock.c (pthread_rwlock_timedwrlock):
> +	Pass CLOCK_REALTIME to __pthread_rwlock_wrlock_full since abstime
> +	uses that clock.
> +
> +	* sysdeps/unix/sysv/linux/aarch64/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/alpha/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/arm/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/csky/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/hppa/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/i386/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/ia64/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/nios2/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/sh/libpthread.abilist (GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +
> +	* nptl/tst-abstime.c (th): Add pthread_rwlock_clockrdlock and
> +	pthread_rwlock_clockwrlock timeout tests to match the existing
> +	pthread_rwlock_timedrdloock and pthread_rwlock_timedwrlock tests.
> +
> +	* nptl/tst-rwlock14.c (do_test): Likewise.
> +
> +	* nptl/tst-rwlock6.c Invent verbose_printf macro, and use for
> +	ancillary output throughout. (tf): Accept thread_args structure so
> +	that rwlock, a clockid and function name can be passed to the
> +	thread. (do_test_clock): Rename from do_test. Accept clockid
> +	parameter to specify test clock. Use the magic clockid value of
> +	CLOCK_USE_TIMEDLOCK to indicate that pthread_rwlock_timedrdlock and
> +	pthread_rwlock_timedwrlock should be tested, otherwise pass the
> +	specified clockid to pthread_rwlock_clockrdlock and
> +	pthread_rwlock_clockwrlock. Use xpthread_create and xpthread_join.
> +	(do_test): Call do_test_clock to test each clockid in turn.
> +
> +	* nptl/tst-rwlock7.c: Likewise.
> +
> +	* nptl/tst-rwlock9.c (writer_thread, reader_thread): Accept
> +	thread_args structure so that the (now int) thread number, the
> +	clockid and the function name can be passed to the thread.
> +	(do_test_clock): Renamed from do_test. Pass the necessary
> +	thread_args when creating the reader and writer threads. Use
> +	xpthread_create and xpthread_join.
> +	(do_test): Call do_test_clock to test each clockid in turn.
> +
> +	* manual/threads.texi: Add documentation for
> +	pthread_rwlock_clockrdlock and pthread_rwlock_clockwrclock.
> +
> +2019-05-27  Mike Crowe  <mac@mcrowe.com>
> +
>  	nptl: pthread_rwlock: Move timeout validation into _full functions
>  
>  	* nptl/pthread_rwlock_common.c (__pthread_rwlock_rdlock_full):

Ok.

> diff --git a/manual/threads.texi b/manual/threads.texi
> index 91462f5..83b8bb6 100644
> --- a/manual/threads.texi
> +++ b/manual/threads.texi
> @@ -699,6 +699,34 @@ specified or defaulted when @code{pthread_cond_init} was called. Currently,
>  @code{CLOCK_REALTIME}.
>  @end deftypefun
>  
> +@comment pthread.h
> +@comment POSIX-proposed
> +@deftypefun int pthread_rwlock_clockrdlock (pthread_rwlock_t *@var{rwlock},
> +				       clockid_t @var{clockid},
> +				       const struct timespec *@var{abstime})
> +
> +@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
> +Behaves like @code{pthread_rwlock_timedrdlock} except the time
> +@var{abstime} is measured against the clock specified by @var{clockid}
> +rather than @code{CLOCK_REALTIME}. Currently, @var{clockid} must be either
> +@code{CLOCK_MONOTONIC} or @code{CLOCK_REALTIME}, otherwise @code{EINVAL} is
> +returned.
> +@end deftypefun
> +
> +@comment pthread.h
> +@comment POSIX-proposed
> +@deftypefun int pthread_rwlock_clockwrlock (pthread_rwlock_t *@var{rwlock},
> +				       clockid_t @var{clockid},
> +				       const struct timespec *@var{abstime})
> +
> +@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
> +Behaves like @code{pthread_rwlock_timedwrlock} except the time
> +@var{abstime} is measured against the clock specified by @var{clockid}
> +rather than @code{CLOCK_REALTIME}. Currently, @var{clockid} must be either
> +@code{CLOCK_MONOTONIC} or @code{CLOCK_REALTIME}, otherwise @code{EINVAL} is
> +returned.
> +@end deftypefun
> +
>  @c FIXME these are undocumented:
>  @c pthread_atfork
>  @c pthread_attr_destroy

Ok.

> diff --git a/nptl/Makefile b/nptl/Makefile
> index 70a2139..d86513a 100644
> --- a/nptl/Makefile
> +++ b/nptl/Makefile
> @@ -76,7 +76,9 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \
>  		      pthread_mutexattr_gettype pthread_mutexattr_settype \
>  		      pthread_rwlock_init pthread_rwlock_destroy \
>  		      pthread_rwlock_rdlock pthread_rwlock_timedrdlock \
> +		      pthread_rwlock_clockrdlock \
>  		      pthread_rwlock_wrlock pthread_rwlock_timedwrlock \
> +		      pthread_rwlock_clockwrlock \
>  		      pthread_rwlock_tryrdlock pthread_rwlock_trywrlock \
>  		      pthread_rwlock_unlock \
>  		      pthread_rwlockattr_init pthread_rwlockattr_destroy \

Ok.

> diff --git a/nptl/Versions b/nptl/Versions
> index 8c094d0..ce79959 100644
> --- a/nptl/Versions
> +++ b/nptl/Versions
> @@ -279,6 +279,7 @@ libpthread {
>  
>    GLIBC_2.30 {
>      sem_clockwait; pthread_cond_clockwait;
> +    pthread_rwlock_clockrdlock; pthread_rwlock_clockwrlock;
>    }
>  
>    GLIBC_PRIVATE {

Ok.

> diff --git a/nptl/pthread_rwlock_clockrdlock.c b/nptl/pthread_rwlock_clockrdlock.c
> new file mode 100644
> index 0000000..3c252f5
> --- /dev/null
> +++ b/nptl/pthread_rwlock_clockrdlock.c
> @@ -0,0 +1,29 @@
> +/* Implement pthread_rwlock_clockrdlock.
> +
> +   Copyright (C) 2019 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
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include "pthread_rwlock_common.c"
> +
> +/* See pthread_rwlock_common.c.  */
> +int
> +pthread_rwlock_clockrdlock (pthread_rwlock_t *rwlock,
> +    clockid_t clockid,
> +    const struct timespec *abstime)
> +{
> +  return __pthread_rwlock_rdlock_full (rwlock, clockid, abstime);
> +}

Ok.

> diff --git a/nptl/pthread_rwlock_clockwrlock.c b/nptl/pthread_rwlock_clockwrlock.c
> new file mode 100644
> index 0000000..38ba693
> --- /dev/null
> +++ b/nptl/pthread_rwlock_clockwrlock.c
> @@ -0,0 +1,29 @@
> +/* Implement pthread_rwlock_clockwrlock.
> +
> +   Copyright (C) 2019 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
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include "pthread_rwlock_common.c"
> +
> +/* See pthread_rwlock_common.c.  */
> +int
> +pthread_rwlock_clockwrlock (pthread_rwlock_t *rwlock,
> +    clockid_t clockid,
> +    const struct timespec *abstime)
> +{
> +  return __pthread_rwlock_wrlock_full (rwlock, clockid, abstime);
> +}

Ok.

> diff --git a/nptl/pthread_rwlock_common.c b/nptl/pthread_rwlock_common.c
> index 120b880..50a366e 100644
> --- a/nptl/pthread_rwlock_common.c
> +++ b/nptl/pthread_rwlock_common.c
> @@ -278,17 +278,19 @@ __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)
>  {
>    unsigned int r;
>  
> -  /* Make sure any passed in timeout value is valid.  Note that the previous
> -     implementation assumed that this check *must* not be performed if there
> -     would in fact be no blocking; however, POSIX only requires that "the
> -     validity of the abstime parameter need not be checked if the lock can be
> -     immediately acquired" (i.e., we need not but may check it).  */
> -  if (abstime
> -      && __glibc_unlikely (abstime->tv_nsec >= 1000000000
> +  /* Make sure any passed in clockid and timeout value are valid. Note

Two spaces after period (I will fix it for you). 

> +     that the previous implementation assumed that this check *must*
> +     not be performed if there would in fact be no blocking; however,
> +     POSIX only requires that "the validity of the abstime parameter
> +     need not be checked if the lock can be immediately acquired"
> +     (i.e., we need not but may check it). */

Two space after period (I will fix it for you).

> +  if (abstime && __glibc_unlikely (!futex_abstimed_supported_clockid (clockid)
> +      || abstime->tv_nsec >= 1000000000
>        || abstime->tv_nsec < 0))
>      return EINVAL;
>  

Ok.

> @@ -329,7 +331,7 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
>  		{
>  		  int private = __pthread_rwlock_get_private (rwlock);
>  		  int err = futex_abstimed_wait (&rwlock->__data.__readers,
> -						 r, CLOCK_REALTIME, abstime, private);
> +						 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,7 +459,7 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
>  	    continue;
>  	  int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
>  					 1 | PTHREAD_RWLOCK_FUTEX_USED,
> -					 CLOCK_REALTIME, abstime, private);
> +					 clockid, abstime, private);
>  	  if (err == ETIMEDOUT)
>  	    {
>  	      /* If we timed out, we need to unregister.  If no read phase

Ok.

> @@ -584,15 +586,17 @@ __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)
>  {
> -  /* Make sure any passed in timeout value is valid.  Note that the previous
> -     implementation assumed that this check *must* not be performed if there
> -     would in fact be no blocking; however, POSIX only requires that "the
> -     validity of the abstime parameter need not be checked if the lock can be
> -     immediately acquired" (i.e., we need not but may check it).  */
> -  if (abstime
> -      && __glibc_unlikely (abstime->tv_nsec >= 1000000000
> +  /* Make sure any passed in clockid and timeout value are valid. Note

Two spaces after period (I will fix it for you).

> +     that the previous implementation assumed that this check *must*
> +     not be performed if there would in fact be no blocking; however,
> +     POSIX only requires that "the validity of the abstime parameter
> +     need not be checked if the lock can be immediately acquired"
> +     (i.e., we need not but may check it). */

Two space after period (I will fix it for you).

> +  if (abstime && __glibc_unlikely (!futex_abstimed_supported_clockid (clockid)
> +      || abstime->tv_nsec >= 1000000000
>        || abstime->tv_nsec < 0))
>      return EINVAL;
>  
> @@ -727,7 +731,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
>  	  may_share_futex_used_flag = true;
>  	  int err = futex_abstimed_wait (&rwlock->__data.__writers_futex,
>  					 1 | PTHREAD_RWLOCK_FUTEX_USED,
> -					 CLOCK_REALTIME, abstime, private);
> +					 clockid, abstime, private);
>  	  if (err == ETIMEDOUT)
>  	    {
>  	      if (prefer_writer)
> @@ -826,7 +830,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
>  	    continue;
>  	  int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
>  					 PTHREAD_RWLOCK_FUTEX_USED,
> -					 CLOCK_REALTIME, abstime, private);
> +					 clockid, abstime, private);
>  	  if (err == ETIMEDOUT)
>  	    {
>  	      if (rwlock->__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP)

Ok.

> diff --git a/nptl/pthread_rwlock_rdlock.c b/nptl/pthread_rwlock_rdlock.c
> index 5fdc89e..387c824 100644
> --- a/nptl/pthread_rwlock_rdlock.c
> +++ b/nptl/pthread_rwlock_rdlock.c
> @@ -24,7 +24,7 @@ __pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
>  {
>    LIBC_PROBE (rdlock_entry, 1, rwlock);
>  
> -  int result = __pthread_rwlock_rdlock_full (rwlock, NULL);
> +  int result = __pthread_rwlock_rdlock_full (rwlock, CLOCK_REALTIME, NULL);
>    LIBC_PROBE (rdlock_acquire_read, 1, rwlock);
>    return result;
>  }

Ok.

> diff --git a/nptl/pthread_rwlock_timedrdlock.c b/nptl/pthread_rwlock_timedrdlock.c
> index 84c1983..8f8e680 100644
> --- a/nptl/pthread_rwlock_timedrdlock.c
> +++ b/nptl/pthread_rwlock_timedrdlock.c
> @@ -23,5 +23,5 @@ int
>  pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock,
>      const struct timespec *abstime)
>  {
> -  return __pthread_rwlock_rdlock_full (rwlock, abstime);
> +  return __pthread_rwlock_rdlock_full (rwlock, CLOCK_REALTIME, abstime);
>  }

Ok.

> diff --git a/nptl/pthread_rwlock_timedwrlock.c b/nptl/pthread_rwlock_timedwrlock.c
> index f0b745d..a5616de 100644
> --- a/nptl/pthread_rwlock_timedwrlock.c
> +++ b/nptl/pthread_rwlock_timedwrlock.c
> @@ -23,5 +23,5 @@ int
>  pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock,
>      const struct timespec *abstime)
>  {
> -  return __pthread_rwlock_wrlock_full (rwlock, abstime);
> +  return __pthread_rwlock_wrlock_full (rwlock, CLOCK_REALTIME, abstime);
>  }

Ok.

> diff --git a/nptl/pthread_rwlock_wrlock.c b/nptl/pthread_rwlock_wrlock.c
> index 194a14c..da246d8 100644
> --- a/nptl/pthread_rwlock_wrlock.c
> +++ b/nptl/pthread_rwlock_wrlock.c
> @@ -24,7 +24,7 @@ __pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
>  {
>    LIBC_PROBE (wrlock_entry, 1, rwlock);
>  
> -  int result = __pthread_rwlock_wrlock_full (rwlock, NULL);
> +  int result = __pthread_rwlock_wrlock_full (rwlock, CLOCK_REALTIME, NULL);
>    LIBC_PROBE (wrlock_acquire_write, 1, rwlock);
>    return result;
>  }

Ok.

> diff --git a/nptl/tst-abstime.c b/nptl/tst-abstime.c
> index 56fb8a5..c5040c5 100644
> --- a/nptl/tst-abstime.c
> +++ b/nptl/tst-abstime.c
> @@ -38,6 +38,14 @@ th (void *arg)
>    TEST_COMPARE (pthread_mutex_timedlock (&m1, &t), ETIMEDOUT);
>    TEST_COMPARE (pthread_rwlock_timedrdlock (&rw1, &t), ETIMEDOUT);
>    TEST_COMPARE (pthread_rwlock_timedwrlock (&rw2, &t), ETIMEDOUT);
> +  TEST_COMPARE (pthread_rwlock_clockrdlock (&rw1, CLOCK_REALTIME, &t),
> +                ETIMEDOUT);
> +  TEST_COMPARE (pthread_rwlock_clockwrlock (&rw2, CLOCK_REALTIME, &t),
> +                ETIMEDOUT);
> +  TEST_COMPARE (pthread_rwlock_clockrdlock (&rw1, CLOCK_MONOTONIC, &t),
> +                ETIMEDOUT);
> +  TEST_COMPARE (pthread_rwlock_clockwrlock (&rw2, CLOCK_MONOTONIC, &t),
> +                ETIMEDOUT);
>    return NULL;
>  }
>  

Ok.

> diff --git a/nptl/tst-rwlock14.c b/nptl/tst-rwlock14.c
> index af176b6..f4e1422 100644
> --- a/nptl/tst-rwlock14.c
> +++ b/nptl/tst-rwlock14.c
> @@ -64,19 +64,31 @@ do_test (void)
>    ts.tv_nsec = -1;
>  
>    TEST_COMPARE (pthread_rwlock_timedrdlock (&r, &ts), EINVAL);
> +  TEST_COMPARE (pthread_rwlock_clockrdlock (&r, CLOCK_REALTIME, &ts), EINVAL);
> +  TEST_COMPARE (pthread_rwlock_clockrdlock (&r, CLOCK_MONOTONIC, &ts), EINVAL);
>    TEST_COMPARE (pthread_rwlock_timedwrlock (&r, &ts), EINVAL);
> +  TEST_COMPARE (pthread_rwlock_clockwrlock (&r, CLOCK_REALTIME, &ts), EINVAL);
> +  TEST_COMPARE (pthread_rwlock_clockwrlock (&r, CLOCK_MONOTONIC, &ts), EINVAL);
>  
>    ts.tv_nsec = 1000000000;
>  
>    TEST_COMPARE (pthread_rwlock_timedrdlock (&r, &ts), EINVAL);
> +  TEST_COMPARE (pthread_rwlock_clockrdlock (&r, CLOCK_REALTIME, &ts), EINVAL);
> +  TEST_COMPARE (pthread_rwlock_clockrdlock (&r, CLOCK_MONOTONIC, &ts), EINVAL);
>    TEST_COMPARE (pthread_rwlock_timedwrlock (&r, &ts), EINVAL);
> +  TEST_COMPARE (pthread_rwlock_clockwrlock (&r, CLOCK_REALTIME, &ts), EINVAL);
> +  TEST_COMPARE (pthread_rwlock_clockwrlock (&r, CLOCK_MONOTONIC, &ts), EINVAL);
>  
>    ts.tv_nsec = (__typeof (ts.tv_nsec)) 0x100001000LL;
>    if ((__typeof (ts.tv_nsec)) 0x100001000LL != 0x100001000LL)
>      ts.tv_nsec = 2000000000;
>  
>    TEST_COMPARE (pthread_rwlock_timedrdlock (&r, &ts), EINVAL);
> +  TEST_COMPARE (pthread_rwlock_clockrdlock (&r, CLOCK_REALTIME, &ts), EINVAL);
> +  TEST_COMPARE (pthread_rwlock_clockrdlock (&r, CLOCK_MONOTONIC, &ts), EINVAL);
>    TEST_COMPARE (pthread_rwlock_timedwrlock (&r, &ts), EINVAL);
> +  TEST_COMPARE (pthread_rwlock_clockwrlock (&r, CLOCK_REALTIME, &ts), EINVAL);
> +  TEST_COMPARE (pthread_rwlock_clockwrlock (&r, CLOCK_MONOTONIC, &ts), EINVAL);
>  
>    return 0;
>  }

Ok.

> diff --git a/nptl/tst-rwlock6.c b/nptl/tst-rwlock6.c
> index 5e73f50..fc24edc 100644
> --- a/nptl/tst-rwlock6.c
> +++ b/nptl/tst-rwlock6.c
> @@ -23,11 +23,17 @@
>  #include <string.h>
>  #include <sys/time.h>
>  #include <support/check.h>
> +#include <support/test-driver.h>
>  #include <support/timespec.h>
>  #include <support/xthread.h>
>  #include <support/xtime.h>
>  
>  
> +/* A bogus clock value that tells run_test to use
> +   pthread_rwlock_timedrdlock and pthread_rwlock_timedwrlock rather
> +   than pthread_rwlock_clockrdlock and pthread_rwlock_clockwrlock. */

Two space after period (I will fix it for you).

> +#define CLOCK_USE_TIMEDLOCK (-1)
> +
>  static int kind[] =
>    {
>      PTHREAD_RWLOCK_PREFER_READER_NP,
> @@ -35,43 +41,63 @@ static int kind[] =
>      PTHREAD_RWLOCK_PREFER_WRITER_NP,
>    };
>  
> +struct thread_args
> +{
> +  pthread_rwlock_t *rwlock;
> +  clockid_t clockid;
> +  const char *fnname;
> +};
>  
>  static void *
>  tf (void *arg)
>  {
> -  pthread_rwlock_t *r = arg;
> +  struct thread_args *args = arg;
> +  pthread_rwlock_t *r = args->rwlock;
> +  const clockid_t clockid = args->clockid;
> +  const clockid_t clockid_for_get =
> +    (clockid == CLOCK_USE_TIMEDLOCK) ? CLOCK_REALTIME : clockid;
> +  const char *fnname = args->fnname;
>  
>    /* Timeout: 0.3 secs.  */
>    struct timespec ts_start;
> -  xclock_gettime (CLOCK_REALTIME, &ts_start);
> +  xclock_gettime (clockid_for_get, &ts_start);
>  
>    struct timespec ts_timeout = timespec_add (ts_start,
>                                               make_timespec (0, 300000000));
>  
> -  puts ("child calling timedrdlock");
> +  verbose_printf ("child calling %srdlock\n", fnname);
>  
> -  TEST_COMPARE (pthread_rwlock_timedrdlock (r, &ts_timeout), ETIMEDOUT);
> +  if (clockid == CLOCK_USE_TIMEDLOCK)
> +    TEST_COMPARE (pthread_rwlock_timedrdlock (r, &ts_timeout), ETIMEDOUT);
> +  else
> +    TEST_COMPARE (pthread_rwlock_clockrdlock (r, clockid, &ts_timeout),
> +                  ETIMEDOUT);
>  
> -  puts ("1st child timedrdlock done");
> +  verbose_printf ("1st child %srdlock done\n", fnname);
>  
>    TEST_TIMESPEC_NOW_OR_AFTER (CLOCK_REALTIME, ts_timeout);
>  
> -  xclock_gettime (CLOCK_REALTIME, &ts_timeout);
> +  xclock_gettime (clockid_for_get, &ts_timeout);
>    ts_timeout.tv_sec += 10;
>    /* Note that the following operation makes ts invalid.  */
>    ts_timeout.tv_nsec += 1000000000;
>  
> -  TEST_COMPARE (pthread_rwlock_timedrdlock (r, &ts_timeout), EINVAL);
> +  if (clockid == CLOCK_USE_TIMEDLOCK)
> +    TEST_COMPARE (pthread_rwlock_timedrdlock (r, &ts_timeout), EINVAL);
> +  else
> +    TEST_COMPARE (pthread_rwlock_clockrdlock (r, clockid, &ts_timeout), EINVAL);
>  
> -  puts ("2nd child timedrdlock done");
> +  verbose_printf ("2nd child %srdlock done\n", fnname);
>  
>    return NULL;
>  }
>  
>  

Ok.

>  static int
> -do_test (void)
> +do_test_clock (clockid_t clockid, const char *fnname)
>  {
> +  const clockid_t clockid_for_get =
> +    (clockid == CLOCK_USE_TIMEDLOCK) ? CLOCK_REALTIME : clockid;
>    size_t cnt;
>    for (cnt = 0; cnt < sizeof (kind) / sizeof (kind[0]); ++cnt)
>      {
> @@ -91,39 +117,46 @@ do_test (void)
>          FAIL_EXIT1 ("round %Zu: rwlockattr_destroy failed\n", cnt);
>  
>        struct timespec ts;
> -      xclock_gettime (CLOCK_REALTIME, &ts);
> +      xclock_gettime (clockid_for_get, &ts);
>        ++ts.tv_sec;
>  
>        /* Get a write lock.  */
> -      int e = pthread_rwlock_timedwrlock (&r, &ts);
> +      int e = (clockid == CLOCK_USE_TIMEDLOCK)
> +	? pthread_rwlock_timedwrlock (&r, &ts)
> +	: pthread_rwlock_clockwrlock (&r, clockid, &ts);
>        if (e != 0)
> -        FAIL_EXIT1 ("round %Zu: rwlock_timedwrlock failed (%d)\n", cnt, e);
> +        FAIL_EXIT1 ("round %Zu: %swrlock failed (%d)\n",
> +                    cnt, fnname, e);
>  
> -      puts ("1st timedwrlock done");
> +      verbose_printf ("1st %swrlock done\n", fnname);
>  
> -      xclock_gettime (CLOCK_REALTIME, &ts);
> +      xclock_gettime (clockid_for_get, &ts);
>        ++ts.tv_sec;
> -      TEST_COMPARE (pthread_rwlock_timedrdlock (&r, &ts), EDEADLK);
> +      if (clockid == CLOCK_USE_TIMEDLOCK)
> +        TEST_COMPARE (pthread_rwlock_timedrdlock (&r, &ts), EDEADLK);
> +      else
> +        TEST_COMPARE (pthread_rwlock_clockrdlock (&r, clockid, &ts), EDEADLK);
>  
> -      puts ("1st timedrdlock done");
> +      verbose_printf ("1st %srdlock done\n", fnname);
>  
> -      xclock_gettime (CLOCK_REALTIME, &ts);
> +      xclock_gettime (clockid_for_get, &ts);
>        ++ts.tv_sec;
> -      TEST_COMPARE (pthread_rwlock_timedwrlock (&r, &ts), EDEADLK);
> +      if (clockid == CLOCK_USE_TIMEDLOCK)
> +        TEST_COMPARE (pthread_rwlock_timedwrlock (&r, &ts), EDEADLK);
> +      else
> +        TEST_COMPARE (pthread_rwlock_clockwrlock (&r, clockid, &ts), EDEADLK);
>  
> -      puts ("2nd timedwrlock done");
> +      verbose_printf ("2nd %swrlock done\n", fnname);
>  
> -      pthread_t th;
> -      if (pthread_create (&th, NULL, tf, &r) != 0)
> -        FAIL_EXIT1 ("round %Zu: create failed\n", cnt);
> +      struct thread_args args;
> +      args.rwlock = &r;
> +      args.clockid = clockid;
> +      args.fnname = fnname;
> +      pthread_t th = xpthread_create (NULL, tf, &args);
>  
>        puts ("started thread");
>  
> -      void *status;
> -      if (pthread_join (th, &status) != 0)
> -        FAIL_EXIT1 ("round %Zu: join failed\n", cnt);
> -      if (status != NULL)
> -        FAIL_EXIT1 ("failure in round %Zu\n", cnt);
> +      (void) xpthread_join (th);
>  
>        puts ("joined thread");
>  
> @@ -134,4 +167,12 @@ do_test (void)
>    return 0;
>  }
>  
> +static int do_test (void)
> +{
> +  do_test_clock (CLOCK_USE_TIMEDLOCK, "timed");
> +  do_test_clock (CLOCK_REALTIME, "clock(realtime)");
> +  do_test_clock (CLOCK_MONOTONIC, "clock(monotonic)");
> +  return 0;
> +}
> +
>  #include <support/test-driver.c>

Ok.

> diff --git a/nptl/tst-rwlock7.c b/nptl/tst-rwlock7.c
> index df50f0a..aa05f30 100644
> --- a/nptl/tst-rwlock7.c
> +++ b/nptl/tst-rwlock7.c
> @@ -28,6 +28,11 @@
>  #include <support/xtime.h>
>  
>  
> +/* A bogus clock value that tells run_test to use
> +   pthread_rwlock_timedrdlock and pthread_rwlock_timedwrlock rather
> +   than pthread_rwlock_clockrdlock and pthread_rwlock_clockwrlock. */

Two space after period (I will fix it for you).

> +#define CLOCK_USE_TIMEDLOCK (-1)
> +
>  static int kind[] =
>    {
>      PTHREAD_RWLOCK_PREFER_READER_NP,
> @@ -35,40 +40,60 @@ static int kind[] =
>      PTHREAD_RWLOCK_PREFER_WRITER_NP,
>    };
>  
> +struct thread_args
> +{
> +  pthread_rwlock_t *rwlock;
> +  clockid_t clockid;
> +  const char *fnname;
> +};
>  
>  static void *
>  tf (void *arg)
>  {
> -  pthread_rwlock_t *r = arg;
> +  struct thread_args *args = arg;
> +  pthread_rwlock_t *r = args->rwlock;
> +  const clockid_t clockid = args->clockid;
> +  const clockid_t clockid_for_get =
> +    (clockid == CLOCK_USE_TIMEDLOCK) ? CLOCK_REALTIME : clockid;
> +  const char *fnname = args->fnname;
>  
>    /* Timeout: 0.3 secs.  */
>    struct timespec ts_start;
> -  xclock_gettime (CLOCK_REALTIME, &ts_start);
> +  xclock_gettime (clockid_for_get, &ts_start);
>    const struct timespec ts_timeout = timespec_add (ts_start,
>                                                     make_timespec (0, 300000000));
>  
> -  TEST_COMPARE (pthread_rwlock_timedwrlock (r, &ts_timeout), ETIMEDOUT);
> -  puts ("child: timedwrlock failed with ETIMEDOUT");
> +  if (clockid == CLOCK_USE_TIMEDLOCK)
> +    TEST_COMPARE (pthread_rwlock_timedwrlock (r, &ts_timeout), ETIMEDOUT);
> +  else
> +    TEST_COMPARE (pthread_rwlock_clockwrlock (r, clockid, &ts_timeout),
> +                  ETIMEDOUT);
> +  printf ("child: %swrlock failed with ETIMEDOUT", fnname);
>  
> -  TEST_TIMESPEC_NOW_OR_AFTER (CLOCK_REALTIME, ts_timeout);
> +  TEST_TIMESPEC_NOW_OR_AFTER (clockid_for_get, ts_timeout);
>  
>    struct timespec ts_invalid;
> -  xclock_gettime (CLOCK_REALTIME, &ts_invalid);
> +  xclock_gettime (clockid_for_get, &ts_invalid);
>    ts_invalid.tv_sec += 10;
>    /* Note that the following operation makes ts invalid.  */
>    ts_invalid.tv_nsec += 1000000000;
>  
> -  TEST_COMPARE (pthread_rwlock_timedwrlock (r, &ts_invalid), EINVAL);
> +  if (clockid == CLOCK_USE_TIMEDLOCK)
> +    TEST_COMPARE (pthread_rwlock_timedwrlock (r, &ts_invalid), EINVAL);
> +  else
> +    TEST_COMPARE (pthread_rwlock_clockwrlock (r, clockid, &ts_invalid), EINVAL);
>  
> -  puts ("child: timedwrlock failed with EINVAL");
> +  printf ("child: %swrlock failed with EINVAL", fnname);
>  
>    return NULL;
>  }
>  
>  
>  static int
> -do_test (void)
> +do_test_clock (clockid_t clockid, const char *fnname)
>  {
> +  const clockid_t clockid_for_get =
> +    (clockid == CLOCK_USE_TIMEDLOCK) ? CLOCK_REALTIME : clockid;
>    size_t cnt;
>    for (cnt = 0; cnt < sizeof (kind) / sizeof (kind[0]); ++cnt)
>      {
> @@ -88,23 +113,27 @@ do_test (void)
>          FAIL_EXIT1 ("round %Zu: rwlockattr_destroy failed\n", cnt);
>  
>        struct timespec ts;
> -      xclock_gettime (CLOCK_REALTIME, &ts);
> +      xclock_gettime (clockid_for_get, &ts);
>  
>        ++ts.tv_sec;
>  
>        /* Get a read lock.  */
> -      if (pthread_rwlock_timedrdlock (&r, &ts) != 0)
> -        FAIL_EXIT1 ("round %Zu: rwlock_timedrdlock failed\n", cnt);
> -
> -      printf ("%zu: got timedrdlock\n", cnt);
> -
> -      pthread_t th;
> -      if (pthread_create (&th, NULL, tf, &r) != 0)
> -        FAIL_EXIT1 ("round %Zu: create failed\n", cnt);
> -
> -      void *status;
> -      if (pthread_join (th, &status) != 0)
> -        FAIL_EXIT1 ("round %Zu: join failed\n", cnt);
> +      if (clockid == CLOCK_USE_TIMEDLOCK) {
> +        if (pthread_rwlock_timedrdlock (&r, &ts) != 0)
> +          FAIL_EXIT1 ("round %Zu: rwlock_timedrdlock failed\n", cnt);
> +      } else {
> +        if (pthread_rwlock_clockrdlock (&r, clockid, &ts) != 0)
> +          FAIL_EXIT1 ("round %Zu: rwlock_%srdlock failed\n", cnt, fnname);
> +      }
> +
> +      printf ("%zu: got %srdlock\n", cnt, fnname);
> +
> +      struct thread_args args;
> +      args.rwlock = &r;
> +      args.clockid = clockid;
> +      args.fnname = fnname;
> +      pthread_t th = xpthread_create (NULL, tf, &args);
> +      void *status = xpthread_join (th);
>        if (status != NULL)
>          FAIL_EXIT1 ("failure in round %Zu\n", cnt);
>  
> @@ -115,4 +144,14 @@ do_test (void)
>    return 0;
>  }
>  
> +static int
> +do_test (void)
> +{
> +  do_test_clock (CLOCK_USE_TIMEDLOCK, "timed");
> +  do_test_clock (CLOCK_MONOTONIC, "clock(monotonic)");
> +  do_test_clock (CLOCK_REALTIME, "clock(realtime)");
> +
> +  return 0;
> +}
> +
>  #include <support/test-driver.c>

Ok.

> diff --git a/nptl/tst-rwlock9.c b/nptl/tst-rwlock9.c
> index e772247..e975554 100644
> --- a/nptl/tst-rwlock9.c
> +++ b/nptl/tst-rwlock9.c
> @@ -26,6 +26,7 @@
>  #include <sys/time.h>
>  #include <support/check.h>
>  #include <support/timespec.h>
> +#include <support/xthread.h>
>  
>  
>  #define NWRITERS 15
> @@ -40,12 +41,30 @@ static const struct timespec delay = { 0, 1000000 };
>  # define KIND PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
>  #endif
>  
> +/* A bogus clock value that tells the tests to use
> +   pthread_rwlock_timedrdlock and pthread_rwlock_timedwrlock rather
> +   than pthread_rwlock_clockrdlock and pthread_rwlock_clockwrlock. */
> +#define CLOCK_USE_TIMEDLOCK (-1)

Two space after period (I will fix it for you).

> +
>  static pthread_rwlock_t lock;
>  
> +struct thread_args
> +{
> +  int nr;
> +  clockid_t clockid;
> +  const char *fnname;
> +};
>  
>  static void *
> -writer_thread (void *nr)
> +writer_thread (void *arg)
>  {
> +  struct thread_args *args = arg;
> +  const int nr = args->nr;
> +  const clockid_t clockid = args->clockid;
> +  const clockid_t clockid_for_get =
> +    (clockid == CLOCK_USE_TIMEDLOCK) ? CLOCK_REALTIME : clockid;
> +  const char *fnname = args->fnname;
> +
>    struct timespec ts;
>    int n;
>  
> @@ -54,27 +73,29 @@ writer_thread (void *nr)
>        int e;
>        do
>  	{
> -	  xclock_gettime (CLOCK_REALTIME, &ts);
> +	  xclock_gettime (clockid_for_get, &ts);
>  
>            ts = timespec_add (ts, timeout);
>            ts = timespec_add (ts, timeout);
>  
> -	  printf ("writer thread %ld tries again\n", (long int) nr);
> +	  printf ("writer thread %d tries again\n", nr);
>  
> -	  e = pthread_rwlock_timedwrlock (&lock, &ts);
> +	  e = (clockid == CLOCK_USE_TIMEDLOCK)
> +	    ? pthread_rwlock_timedwrlock (&lock, &ts)
> +	    : pthread_rwlock_clockwrlock (&lock, clockid, &ts);
>  	  if (e != 0 && e != ETIMEDOUT)
> -            FAIL_EXIT1 ("timedwrlock failed");
> +            FAIL_EXIT1 ("%swrlock failed", fnname);
>  	}
>        while (e == ETIMEDOUT);
>  
> -      printf ("writer thread %ld succeeded\n", (long int) nr);
> +      printf ("writer thread %d succeeded\n", nr);
>  
>        nanosleep (&delay, NULL);
>  
>        if (pthread_rwlock_unlock (&lock) != 0)
>          FAIL_EXIT1 ("unlock for writer failed");
>  
> -      printf ("writer thread %ld released\n", (long int) nr);
> +      printf ("writer thread %d released\n", nr);
>      }
>  
>    return NULL;
> @@ -82,8 +103,15 @@ writer_thread (void *nr)
>  
>  
>  static void *
> -reader_thread (void *nr)
> +reader_thread (void *arg)
>  {
> +  struct thread_args *args = arg;
> +  const int nr = args->nr;
> +  const clockid_t clockid = args->clockid;
> +  const clockid_t clockid_for_get =
> +    (clockid == CLOCK_USE_TIMEDLOCK) ? CLOCK_REALTIME : clockid;
> +  const char *fnname = args->fnname;
> +
>    struct timespec ts;
>    int n;
>  
> @@ -92,26 +120,29 @@ reader_thread (void *nr)
>        int e;
>        do
>  	{
> -	  xclock_gettime (CLOCK_REALTIME, &ts);
> +	  xclock_gettime (clockid_for_get, &ts);
>  
>            ts = timespec_add (ts, timeout);
>  
> -	  printf ("reader thread %ld tries again\n", (long int) nr);
> +	  printf ("reader thread %d tries again\n", nr);
>  
> -	  e = pthread_rwlock_timedrdlock (&lock, &ts);
> +	  if (clockid == CLOCK_USE_TIMEDLOCK)
> +	    e = pthread_rwlock_timedrdlock (&lock, &ts);
> +          else
> +	    e = pthread_rwlock_clockrdlock (&lock, clockid, &ts);
>  	  if (e != 0 && e != ETIMEDOUT)
> -            FAIL_EXIT1 ("timedrdlock failed");
> +            FAIL_EXIT1 ("%srdlock failed", fnname);
>  	}
>        while (e == ETIMEDOUT);
>  
> -      printf ("reader thread %ld succeeded\n", (long int) nr);
> +      printf ("reader thread %d succeeded\n", nr);
>  
>        nanosleep (&delay, NULL);
>  
>        if (pthread_rwlock_unlock (&lock) != 0)
>          FAIL_EXIT1 ("unlock for reader failed");
>  
> -      printf ("reader thread %ld released\n", (long int) nr);
> +      printf ("reader thread %d released\n", nr);
>      }
>  
>    return NULL;
> @@ -119,12 +150,11 @@ reader_thread (void *nr)
>  
>  
>  static int
> -do_test (void)
> +do_test_clock (clockid_t clockid, const char *fnname)
>  {
>    pthread_t thwr[NWRITERS];
>    pthread_t thrd[NREADERS];
>    int n;
> -  void *res;
>    pthread_rwlockattr_t a;
>  
>    if (pthread_rwlockattr_init (&a) != 0)
> @@ -142,23 +172,37 @@ do_test (void)
>    /* Make sure we see all message, even those on stdout.  */
>    setvbuf (stdout, NULL, _IONBF, 0);
>  
> -  for (n = 0; n < NWRITERS; ++n)
> -    if (pthread_create (&thwr[n], NULL, writer_thread,
> -			(void *) (long int) n) != 0)
> -      FAIL_EXIT1 ("writer create failed");
> -
> -  for (n = 0; n < NREADERS; ++n)
> -    if (pthread_create (&thrd[n], NULL, reader_thread,
> -			(void *) (long int) n) != 0)
> -      FAIL_EXIT1 ("reader create failed");
> +  struct thread_args wargs[NWRITERS];
> +  for (n = 0; n < NWRITERS; ++n) {
> +    wargs[n].nr = n;
> +    wargs[n].clockid = clockid;
> +    wargs[n].fnname = fnname;
> +    thwr[n] = xpthread_create (NULL, writer_thread, &wargs[n]);
> +  }
> +
> +  struct thread_args rargs[NREADERS];
> +  for (n = 0; n < NREADERS; ++n) {
> +    rargs[n].nr = n;
> +    rargs[n].clockid = clockid;
> +    rargs[n].fnname = fnname;
> +    thrd[n] = xpthread_create (NULL, reader_thread, &rargs[n]);
> +  }
>  
>    /* Wait for all the threads.  */
>    for (n = 0; n < NWRITERS; ++n)
> -    if (pthread_join (thwr[n], &res) != 0)
> -      FAIL_EXIT1 ("writer join failed");
> +    xpthread_join (thwr[n]);
>    for (n = 0; n < NREADERS; ++n)
> -    if (pthread_join (thrd[n], &res) != 0)
> -      FAIL_EXIT1 ("reader join failed");
> +    xpthread_join (thrd[n]);
> +
> +  return 0;
> +}
> +
> +static int
> +do_test (void)
> +{
> +  do_test_clock (CLOCK_USE_TIMEDLOCK, "timed");
> +  do_test_clock (CLOCK_REALTIME, "clock(realtime)");
> +  do_test_clock (CLOCK_MONOTONIC, "clock(monotonic)");
>  
>    return 0;
>  }

Ok.

> diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
> index f000b1e..e78003e 100644
> --- a/sysdeps/nptl/pthread.h
> +++ b/sysdeps/nptl/pthread.h
> @@ -909,6 +909,13 @@ extern int pthread_rwlock_timedrdlock (pthread_rwlock_t *__restrict __rwlock,
>  				       __abstime) __THROWNL __nonnull ((1, 2));
>  # endif
>  
> +# ifdef __USE_GNU
> +extern int pthread_rwlock_clockrdlock (pthread_rwlock_t *__restrict __rwlock,
> +				       clockid_t __clockid,
> +				       const struct timespec *__restrict
> +				       __abstime) __THROWNL __nonnull ((1, 3));
> +# endif
> +
>  /* Acquire write lock for RWLOCK.  */
>  extern int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock)
>       __THROWNL __nonnull ((1));
> @@ -924,6 +931,13 @@ extern int pthread_rwlock_timedwrlock (pthread_rwlock_t *__restrict __rwlock,
>  				       __abstime) __THROWNL __nonnull ((1, 2));
>  # endif
>  
> +# ifdef __USE_GNU
> +extern int pthread_rwlock_clockwrlock (pthread_rwlock_t *__restrict __rwlock,
> +				       clockid_t __clockid,
> +				       const struct timespec *__restrict
> +				       __abstime) __THROWNL __nonnull ((1, 3));
> +# endif
> +
>  /* Unlock RWLOCK.  */
>  extern int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock)
>       __THROWNL __nonnull ((1));

Ok.

> diff --git a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
> index 5af4b8a..9f65baf 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
> @@ -244,4 +244,6 @@ GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
> index a00adfb..0709855 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
> @@ -228,6 +228,8 @@ GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.3.2 pthread_cond_broadcast F
>  GLIBC_2.3.2 pthread_cond_destroy F
> diff --git a/sysdeps/unix/sysv/linux/arm/libpthread.abilist b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
> index 4aeee7b..a2be572 100644
> --- a/sysdeps/unix/sysv/linux/arm/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
> @@ -28,6 +28,8 @@ GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 _IO_flockfile F
>  GLIBC_2.4 _IO_ftrylockfile F
> diff --git a/sysdeps/unix/sysv/linux/csky/libpthread.abilist b/sysdeps/unix/sysv/linux/csky/libpthread.abilist
> index 2c08b76..c3a1834 100644
> --- a/sysdeps/unix/sysv/linux/csky/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/csky/libpthread.abilist
> @@ -234,4 +234,6 @@ GLIBC_2.29 wait F
>  GLIBC_2.29 waitpid F
>  GLIBC_2.29 write F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
> index dc0d4ad..2a00ebc 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
> @@ -246,6 +246,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/i386/libpthread.abilist b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
> index 1830e40..4479947 100644
> --- a/sysdeps/unix/sysv/linux/i386/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
> @@ -254,6 +254,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
> index 0811d73..40a1faf 100644
> --- a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
> @@ -248,6 +248,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
> index 4aeee7b..a2be572 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
> @@ -28,6 +28,8 @@ GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 _IO_flockfile F
>  GLIBC_2.4 _IO_ftrylockfile F
> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
> index 1830e40..4479947 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
> @@ -254,6 +254,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
> index f2be6b4..254b708 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
> @@ -244,4 +244,6 @@ GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
> index 41527fe..29ffdd1 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
> @@ -256,6 +256,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
> index 41527fe..29ffdd1 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
> @@ -256,6 +256,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
> index 04fc3a6..3fae328 100644
> --- a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
> @@ -242,4 +242,6 @@ GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
> index ebdab1a..a90010d 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
> @@ -256,6 +256,8 @@ GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.3.4 siglongjmp F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
> index 8a1fb34..339eab8 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
> @@ -247,6 +247,8 @@ GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.3.4 siglongjmp F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
> index 5af4b8a..9f65baf 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
> @@ -244,4 +244,6 @@ GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> index a1c8c2e..83082fb 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> @@ -236,4 +236,6 @@ GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
> index 0feb3cf..54e937b 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
> @@ -256,6 +256,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
> index cc4f160..87f978b 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
> @@ -248,6 +248,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/sh/libpthread.abilist b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
> index dc0d4ad..2a00ebc 100644
> --- a/sysdeps/unix/sysv/linux/sh/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
> @@ -246,6 +246,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
> index ed0574a..bc29a66 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
> @@ -256,6 +256,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
> index 0811d73..40a1faf 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
> @@ -248,6 +248,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> index aaa1c3b..70f04cc 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> @@ -246,6 +246,8 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
>  GLIBC_2.4 pthread_mutex_consistent_np F
>  GLIBC_2.4 pthread_mutex_getprioceiling F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
> index 5d02b03..92cd2f4 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
> @@ -244,4 +244,6 @@ GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_rwlock_clockrdlock F
> +GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> 

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v4 09/12] nptl: Rename lll_timedlock to lll_clocklock and add clockid parameter
  2019-06-18 16:33 ` [PATCH v4 09/12] nptl: Rename lll_timedlock to lll_clocklock and add clockid parameter Mike Crowe
@ 2019-06-25 21:36   ` Adhemerval Zanella
  0 siblings, 0 replies; 32+ messages in thread
From: Adhemerval Zanella @ 2019-06-25 21:36 UTC (permalink / raw
  To: libc-alpha



On 18/06/2019 13:33, Mike Crowe wrote:
> Rename lll_timedlock to lll_clocklock and add clockid
> parameter to indicate the clock that the abstime parameter should
> be measured against in preparation for adding
> pthread_mutex_clocklock.
> 
> The name change mirrors the naming for the exposed pthread functions:
> 
>  timed => absolute timeout measured against CLOCK_REALTIME (or clock
>           specified by attribute in the case of pthread_cond_timedwait.)
> 
>  clock => absolute timeout measured against clock specified in preceding
>           parameter.
> 
> * sysdeps/nptl/lowlevellock.h (lll_clocklock): Rename from lll_timedlock
>   and add clockid parameter. (__lll_clocklock): Rename from __lll_timedlock
>   and add clockid parameter.

LGTM with smalls nits regarding comments.

> 
> * sysdeps/unix/sysv/linux/sparc/lowlevellock.h (lll_clocklock): Likewise.
> 
> * nptl/lll_timedlock_wait.c (__lll_clocklock_wait): Rename from
>   __lll_timedlock_wait and add clockid parameter. Use __clock_gettime
>   rather than __gettimeofday so that clockid can be used. This means that
>   conversion from struct timeval is no longer required.
> 
> * sysdeps/sparc/sparc32/lowlevellock.c (lll_clocklock_wait): Likewise.
> 
> * sysdeps/sparc/sparc32/lll_timedlock_wait.c: Update comment to refer to
>   __lll_clocklock_wait rather than __lll_timedlock_wait.
> 
> * nptl/pthread_mutex_timedlock.c (lll_clocklock_elision): Rename from
>   lll_timedlock_elision, add clockid parameter and use meaningful names for
>   other parameters. (__pthread_mutex_timedlock): Pass CLOCK_REALTIME where
>   necessary to lll_clocklock and lll_clocklock_elision.
> 
> * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h (lll_clocklock_elision):
>   Rename from lll_timedlock_elision and add clockid parameter.
>   (__lll_clocklock_elision): Rename from __lll_timedlock_elision and add
>   clockid parameter. * sysdeps/unix/sysv/linux/s390/lowlevellock.h:
>   Likewise. * sysdeps/unix/sysv/linux/x86/lowlevellock.h: Likewise.
> 
> * sysdeps/unix/sysv/linux/powerpc/elision-timed.c (__lll_lock_elision):
>   Call __lll_clocklock_elision rather than __lll_timedlock_elision.
>   (EXTRAARG): Add clockid parameter. (LLL_LOCK): Likewise. *
>   sysdeps/unix/sysv/linux/s390/elision-timed.c: Likewise. *
>   sysdeps/unix/sysv/linux/x86/elision-timed.c: Likewise.

Ok.

> ---
>  ChangeLog                                       | 54 ++++++++++++++++++-
>  nptl/lll_timedlock_wait.c                       | 15 +++--
>  nptl/pthread_mutex_timedlock.c                  | 16 ++---
>  sysdeps/nptl/lowlevellock.h                     | 16 ++---
>  sysdeps/sparc/sparc32/lll_timedlock_wait.c      |  2 +-
>  sysdeps/sparc/sparc32/lowlevellock.c            | 15 +++--
>  sysdeps/unix/sysv/linux/powerpc/elision-timed.c |  6 +-
>  sysdeps/unix/sysv/linux/powerpc/lowlevellock.h  |  9 +--
>  sysdeps/unix/sysv/linux/s390/elision-timed.c    |  6 +-
>  sysdeps/unix/sysv/linux/s390/lowlevellock.h     |  9 +--
>  sysdeps/unix/sysv/linux/sparc/lowlevellock.h    | 11 ++--
>  sysdeps/unix/sysv/linux/x86/elision-timed.c     |  6 +-
>  sysdeps/unix/sysv/linux/x86/lowlevellock.h      | 11 ++--
>  13 files changed, 122 insertions(+), 54 deletions(-)
> 
> diff --git a/ChangeLog b/ChangeLog
> index bd84ee4..713c677 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,3 +1,57 @@
> +2019-05-31  Mike Crowe  <mac@mcrowe.com>
> +
> +	nptl: Rename lll_timedlock to lll_clocklock and add clockid
> +	parameter to indicate the clock that the abstime parameter should
> +	be measured against in preparation for adding
> +	pthread_mutex_clocklock.
> +
> +	The name change mirrors the naming for the exposed pthread functions:
> +
> +	 timed => absolute timeout measured against CLOCK_REALTIME (or
> +		  clock specified by attribute in the case of
> +		  pthread_cond_timedwait.)
> +
> +	 clock => absolute timeout measured against clock specified in preceding
> +		  parameter.
> +
> +	* sysdeps/nptl/lowlevellock.h (lll_clocklock): Rename from
> +	lll_timedlock and add clockid parameter. (__lll_clocklock): Rename
> +	from __lll_timedlock and add clockid parameter.
> +
> +	* sysdeps/unix/sysv/linux/sparc/lowlevellock.h (lll_clocklock):
> +	Likewise.
> +
> +	* nptl/lll_timedlock_wait.c (__lll_clocklock_wait): Rename from
> +	__lll_timedlock_wait and add clockid parameter. Use __clock_gettime
> +	rather than __gettimeofday so that clockid can be used. This means
> +	that conversion from struct timeval is no longer required.
> +
> +	* sysdeps/sparc/sparc32/lowlevellock.c (lll_clocklock_wait):
> +	Likewise.
> +
> +	* sysdeps/sparc/sparc32/lll_timedlock_wait.c: Update comment to
> +	refer to __lll_clocklock_wait rather than __lll_timedlock_wait.
> +
> +	* nptl/pthread_mutex_timedlock.c (lll_clocklock_elision): Rename
> +	from lll_timedlock_elision, add clockid parameter and use
> +	meaningful names for other parameters. (__pthread_mutex_timedlock):
> +	Pass CLOCK_REALTIME where necessary to lll_clocklock and
> +	lll_clocklock_elision.
> +
> +	* sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
> +	(lll_clocklock_elision): Rename from lll_timedlock_elision and add
> +	clockid parameter. (__lll_clocklock_elision): Rename from
> +	__lll_timedlock_elision and add clockid parameter.
> +	* sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise.
> +	* sysdeps/unix/sysv/linux/x86/lowlevellock.h: Likewise.
> +
> +	* sysdeps/unix/sysv/linux/powerpc/elision-timed.c
> +	(__lll_lock_elision): Call __lll_clocklock_elision rather than
> +	__lll_timedlock_elision. (EXTRAARG): Add clockid parameter.
> +	(LLL_LOCK): Likewise.
> +	* sysdeps/unix/sysv/linux/s390/elision-timed.c: Likewise.
> +	* sysdeps/unix/sysv/linux/x86/elision-timed.c: Likewise.
> +
>  2019-05-27  Mike Crowe  <mac@mcrowe.com>
>  
>  	nptl: Add POSIX-proposed pthread_rwlock_clockrdlock &
> diff --git a/nptl/lll_timedlock_wait.c b/nptl/lll_timedlock_wait.c
> index 1f489ed..ad28724 100644
> --- a/nptl/lll_timedlock_wait.c
> +++ b/nptl/lll_timedlock_wait.c
> @@ -24,7 +24,8 @@
>  
>  
>  int
> -__lll_timedlock_wait (int *futex, const struct timespec *abstime, int private)
> +__lll_clocklock_wait (int *futex, clockid_t clockid,
> +		      const struct timespec *abstime, int private)
>  {
>    /* Reject invalid timeouts.  */
>    if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
> @@ -33,15 +34,17 @@ __lll_timedlock_wait (int *futex, const struct timespec *abstime, int private)
>    /* Try locking.  */
>    while (atomic_exchange_acq (futex, 2) != 0)
>      {
> -      struct timeval tv;
> +      struct timespec ts;
>  
> -      /* Get the current time.  */
> -      (void) __gettimeofday (&tv, NULL);
> +      /* Get the current time. This can only fail if clockid is not
> +         valid. */

Two spaces after period (I will fix it for you). 


> +      if (__glibc_unlikely (__clock_gettime (clockid, &ts) != 0))
> +        return EINVAL;
>  
>        /* Compute relative timeout.  */
>        struct timespec rt;
> -      rt.tv_sec = abstime->tv_sec - tv.tv_sec;
> -      rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
> +      rt.tv_sec = abstime->tv_sec - ts.tv_sec;
> +      rt.tv_nsec = abstime->tv_nsec - ts.tv_nsec;
>        if (rt.tv_nsec < 0)
>          {
>            rt.tv_nsec += 1000000000;

Ok.

> diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
> index d4d11cc..10a9989 100644
> --- a/nptl/pthread_mutex_timedlock.c
> +++ b/nptl/pthread_mutex_timedlock.c
> @@ -28,8 +28,9 @@
>  
>  #include <stap-probe.h>
>  
> -#ifndef lll_timedlock_elision
> -#define lll_timedlock_elision(a,dummy,b,c) lll_timedlock(a, b, c)
> +#ifndef lll_clocklock_elision
> +#define lll_clocklock_elision(futex, adapt_count, clockid, abstime, private) \
> +  lll_clocklock (futex, clockid, abstime, private)
>  #endif
>  
>  #ifndef lll_trylock_elision
> @@ -75,7 +76,7 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
>  	}
>  
>        /* We have to get the mutex.  */
> -      result = lll_timedlock (mutex->__data.__lock, abstime,
> +      result = lll_clocklock (mutex->__data.__lock, CLOCK_REALTIME, abstime,
>  			      PTHREAD_MUTEX_PSHARED (mutex));
>  
>        if (result != 0)
> @@ -98,16 +99,16 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
>        FORCE_ELISION (mutex, goto elision);
>      simple:
>        /* Normal mutex.  */
> -      result = lll_timedlock (mutex->__data.__lock, abstime,
> +      result = lll_clocklock (mutex->__data.__lock, CLOCK_REALTIME, abstime,
>  			      PTHREAD_MUTEX_PSHARED (mutex));
>        break;
>  
>      case PTHREAD_MUTEX_TIMED_ELISION_NP:
>      elision: __attribute__((unused))
>        /* Don't record ownership */
> -      return lll_timedlock_elision (mutex->__data.__lock,
> +      return lll_clocklock_elision (mutex->__data.__lock,
>  				    mutex->__data.__spins,
> -				    abstime,
> +				    CLOCK_REALTIME, abstime,
>  				    PTHREAD_MUTEX_PSHARED (mutex));
>  

Ok.

>  
> @@ -124,7 +125,8 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
>  	    {
>  	      if (cnt++ >= max_cnt)
>  		{
> -		  result = lll_timedlock (mutex->__data.__lock, abstime,
> +		  result = lll_clocklock (mutex->__data.__lock,
> +					  CLOCK_REALTIME, abstime,
>  					  PTHREAD_MUTEX_PSHARED (mutex));
>  		  break;
>  		}

Ok.

> diff --git a/sysdeps/nptl/lowlevellock.h b/sysdeps/nptl/lowlevellock.h
> index e905829..8ca50f4 100644
> --- a/sysdeps/nptl/lowlevellock.h
> +++ b/sysdeps/nptl/lowlevellock.h
> @@ -121,24 +121,26 @@ extern void __lll_lock_wait (int *futex, int private) attribute_hidden;
>  #define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private)
>  
>  
> -extern int __lll_timedlock_wait (int *futex, const struct timespec *,
> +extern int __lll_clocklock_wait (int *futex, clockid_t,
> +				 const struct timespec *,
>  				 int private) attribute_hidden;
>  
>  
> -/* As __lll_lock, but with a timeout.  If the timeout occurs then return
> -   ETIMEDOUT.  If ABSTIME is invalid, return EINVAL.  */
> -#define __lll_timedlock(futex, abstime, private)                \
> +/* As __lll_lock, but with an absolute timeout measured against the
> +   clock specified in CLOCKID. If the timeout occurs then return
> +   ETIMEDOUT. If ABSTIME is invalid, return EINVAL. */

Two spaces after period (I will fix it for you). 

> +#define __lll_clocklock(futex, clockid, abstime, private)       \
>    ({                                                            \
>      int *__futex = (futex);                                     \
>      int __val = 0;                                              \
>                                                                  \
>      if (__glibc_unlikely                                        \
>          (atomic_compare_and_exchange_bool_acq (__futex, 1, 0))) \
> -      __val = __lll_timedlock_wait (__futex, abstime, private); \
> +      __val = __lll_clocklock_wait (__futex, clockid, abstime, private); \
>      __val;                                                      \
>    })
> -#define lll_timedlock(futex, abstime, private)  \
> -  __lll_timedlock (&(futex), abstime, private)
> +#define lll_clocklock(futex, clockid, abstime, private)         \
> +  __lll_clocklock (&(futex), clockid, abstime, private)
>  
>  
>  /* This is an expression rather than a statement even though its value is

Ok.

> diff --git a/sysdeps/sparc/sparc32/lll_timedlock_wait.c b/sysdeps/sparc/sparc32/lll_timedlock_wait.c
> index c2c93fa..bd639a7 100644
> --- a/sysdeps/sparc/sparc32/lll_timedlock_wait.c
> +++ b/sysdeps/sparc/sparc32/lll_timedlock_wait.c
> @@ -1 +1 @@
> -/* __lll_timedlock_wait is in lowlevellock.c.  */
> +/* __lll_clocklock_wait is in lowlevellock.c.  */

Ok.

> diff --git a/sysdeps/sparc/sparc32/lowlevellock.c b/sysdeps/sparc/sparc32/lowlevellock.c
> index 1a0b7bb..b0c5a6d 100644
> --- a/sysdeps/sparc/sparc32/lowlevellock.c
> +++ b/sysdeps/sparc/sparc32/lowlevellock.c
> @@ -52,7 +52,8 @@ __lll_lock_wait (int *futex, int private)
>  
>  
>  int
> -__lll_timedlock_wait (int *futex, const struct timespec *abstime, int private)
> +__lll_clocklock_wait (int *futex, clockid_t clockid,
> +                      const struct timespec *abstime, int private)
>  {
>    /* Reject invalid timeouts.  */
>    if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
> @@ -60,15 +61,17 @@ __lll_timedlock_wait (int *futex, const struct timespec *abstime, int private)
>  
>    do
>      {
> -      struct timeval tv;
> +      struct timespec ts;
>        struct timespec rt;
>  
> -      /* Get the current time.  */
> -      (void) __gettimeofday (&tv, NULL);
> +      /* Get the current time. This can only fail if clockid is not
> +         valid. */
> +      if (__glibc_unlikely (__clock_gettime (clockid, &ts) != 0))
> +        return EINVAL;
>  
>        /* Compute relative timeout.  */
> -      rt.tv_sec = abstime->tv_sec - tv.tv_sec;
> -      rt.tv_nsec = abstime->tv_nsec - tv.tv_usec * 1000;
> +      rt.tv_sec = abstime->tv_sec - ts.tv_sec;
> +      rt.tv_nsec = abstime->tv_nsec - ts.tv_nsec;
>        if (rt.tv_nsec < 0)
>  	{
>  	  rt.tv_nsec += 1000000000;

Ok.

> diff --git a/sysdeps/unix/sysv/linux/powerpc/elision-timed.c b/sysdeps/unix/sysv/linux/powerpc/elision-timed.c
> index f65818b..739cb6e 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/elision-timed.c
> +++ b/sysdeps/unix/sysv/linux/powerpc/elision-timed.c
> @@ -20,9 +20,9 @@
>  #include <elision-conf.h>
>  #include "lowlevellock.h"
>  
> -#define __lll_lock_elision __lll_timedlock_elision
> -#define EXTRAARG const struct timespec *t,
> +#define __lll_lock_elision __lll_clocklock_elision
> +#define EXTRAARG clockid_t clockid, const struct timespec *t,
>  #undef LLL_LOCK
> -#define LLL_LOCK(a, b) lll_timedlock(a, t, b)
> +#define LLL_LOCK(a, b) lll_clocklock(a, clockid, t, b)
>  
>  #include "elision-lock.c"

Ok.

> diff --git a/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h b/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
> index 77235d7..4686c49 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
> +++ b/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
> @@ -22,12 +22,13 @@
>  #include <sysdeps/nptl/lowlevellock.h>
>  
>  /* Transactional lock elision definitions.  */
> -extern int __lll_timedlock_elision
> -  (int *futex, short *adapt_count, const struct timespec *timeout, int private)
> +extern int __lll_clocklock_elision
> +  (int *futex, short *adapt_count,
> +   clockid_t clockid, const struct timespec *timeout, int private)
>    attribute_hidden;
>  
> -#define lll_timedlock_elision(futex, adapt_count, timeout, private)	      \
> -  __lll_timedlock_elision(&(futex), &(adapt_count), timeout, private)
> +#define lll_clocklock_elision(futex, adapt_count, clockid, timeout, private) \
> +  __lll_clocklock_elision (&(futex), &(adapt_count), clockid, timeout, private)
>  
>  extern int __lll_lock_elision (int *futex, short *adapt_count, int private)
>    attribute_hidden;

Ok.

> diff --git a/sysdeps/unix/sysv/linux/s390/elision-timed.c b/sysdeps/unix/sysv/linux/s390/elision-timed.c
> index f7a90fa..2563176 100644
> --- a/sysdeps/unix/sysv/linux/s390/elision-timed.c
> +++ b/sysdeps/unix/sysv/linux/s390/elision-timed.c
> @@ -19,8 +19,8 @@
>  #include <time.h>
>  #include <elision-conf.h>
>  #include <lowlevellock.h>
> -#define __lll_lock_elision __lll_timedlock_elision
> -#define EXTRAARG const struct timespec *t,
> +#define __lll_lock_elision __lll_clocklock_elision
> +#define EXTRAARG clockid_t clockid, const struct timespec *t,
>  #undef LLL_LOCK
> -#define LLL_LOCK(a, b) lll_timedlock(a, t, b)
> +#define LLL_LOCK(a, b) lll_clocklock(a, clockid, t, b)
>  #include "elision-lock.c"

Ok.

> diff --git a/sysdeps/unix/sysv/linux/s390/lowlevellock.h b/sysdeps/unix/sysv/linux/s390/lowlevellock.h
> index 77e7580..2388bf2 100644
> --- a/sysdeps/unix/sysv/linux/s390/lowlevellock.h
> +++ b/sysdeps/unix/sysv/linux/s390/lowlevellock.h
> @@ -22,12 +22,13 @@
>  #include <sysdeps/nptl/lowlevellock.h>
>  
>  /* Transactional lock elision definitions.  */
> -extern int __lll_timedlock_elision
> -  (int *futex, short *adapt_count, const struct timespec *timeout, int private)
> +extern int __lll_clocklock_elision
> +  (int *futex, short *adapt_count,
> +   clockid_t clockid, const struct timespec *timeout, int private)
>    attribute_hidden;
>  
> -#  define lll_timedlock_elision(futex, adapt_count, timeout, private)	\
> -  __lll_timedlock_elision(&(futex), &(adapt_count), timeout, private)
> +#  define lll_clocklock_elision(futex, adapt_count, clockid, timeout, private) \
> +  __lll_clocklock_elision (&(futex), &(adapt_count), clockid, timeout, private)
>  
>  extern int __lll_lock_elision (int *futex, short *adapt_count, int private)
>    attribute_hidden;

Ok.

> diff --git a/sysdeps/unix/sysv/linux/sparc/lowlevellock.h b/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
> index c778f42..c79a947 100644
> --- a/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
> +++ b/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
> @@ -75,22 +75,23 @@ __lll_cond_lock (int *futex, int private)
>  #define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private)
>  
>  
> -extern int __lll_timedlock_wait (int *futex, const struct timespec *,
> +extern int __lll_clocklock_wait (int *futex, clockid_t, const struct timespec *,
>  				 int private) attribute_hidden;
>  
>  static inline int
>  __attribute__ ((always_inline))
> -__lll_timedlock (int *futex, const struct timespec *abstime, int private)
> +__lll_clocklock (int *futex, clockid_t clockid,
> +                 const struct timespec *abstime, int private)
>  {
>    int val = atomic_compare_and_exchange_val_24_acq (futex, 1, 0);
>    int result = 0;
>  
>    if (__glibc_unlikely (val != 0))
> -    result = __lll_timedlock_wait (futex, abstime, private);
> +    result = __lll_clocklock_wait (futex, clockid, abstime, private);
>    return result;
>  }
> -#define lll_timedlock(futex, abstime, private) \
> -  __lll_timedlock (&(futex), abstime, private)
> +#define lll_clocklock(futex, clockid, abstime, private)  \
> +  __lll_clocklock (&(futex), clockid, abstime, private)
>  
>  #define lll_unlock(lock, private) \
>    ((void) ({			

Ok.
					      \
> diff --git a/sysdeps/unix/sysv/linux/x86/elision-timed.c b/sysdeps/unix/sysv/linux/x86/elision-timed.c
> index 9abc6ec..2c5073b 100644
> --- a/sysdeps/unix/sysv/linux/x86/elision-timed.c
> +++ b/sysdeps/unix/sysv/linux/x86/elision-timed.c
> @@ -19,8 +19,8 @@
>  #include <time.h>
>  #include <elision-conf.h>
>  #include "lowlevellock.h"
> -#define __lll_lock_elision __lll_timedlock_elision
> -#define EXTRAARG const struct timespec *t,
> +#define __lll_lock_elision __lll_clocklock_elision
> +#define EXTRAARG clockid_t clockid, const struct timespec *t,
>  #undef LLL_LOCK
> -#define LLL_LOCK(a, b) lll_timedlock(a, t, b)
> +#define LLL_LOCK(a, b) lll_clocklock (a, clockid, t, b)
>  #include "elision-lock.c"

Ok.

> diff --git a/sysdeps/unix/sysv/linux/x86/lowlevellock.h b/sysdeps/unix/sysv/linux/x86/lowlevellock.h
> index 8a78dcf..e6c59ea 100644
> --- a/sysdeps/unix/sysv/linux/x86/lowlevellock.h
> +++ b/sysdeps/unix/sysv/linux/x86/lowlevellock.h
> @@ -82,12 +82,13 @@ __lll_cas_lock (int *futex)
>         __lll_unlock (&(lock), private);					     \
>     }))
>  
> -extern int __lll_timedlock_elision (int *futex, short *adapt_count,
> -					 const struct timespec *timeout,
> -					 int private) attribute_hidden;
> +extern int __lll_clocklock_elision (int *futex, short *adapt_count,
> +                                    clockid_t clockid,
> +				    const struct timespec *timeout,
> +				    int private) attribute_hidden;
>  
> -#define lll_timedlock_elision(futex, adapt_count, timeout, private)	\
> -  __lll_timedlock_elision(&(futex), &(adapt_count), timeout, private)
> +#define lll_clocklock_elision(futex, adapt_count, clockid, timeout, private) \
> +  __lll_clocklock_elision (&(futex), &(adapt_count), clockid, timeout, private)
>  
>  extern int __lll_lock_elision (int *futex, short *adapt_count, int private)
>    attribute_hidden;
> 

Ok.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v4 10/12] nptl: Add POSIX-proposed pthread_mutex_clocklock
  2019-06-18 16:33 ` [PATCH v4 10/12] nptl: Add POSIX-proposed pthread_mutex_clocklock Mike Crowe
@ 2019-06-25 21:59   ` Adhemerval Zanella
  0 siblings, 0 replies; 32+ messages in thread
From: Adhemerval Zanella @ 2019-06-25 21:59 UTC (permalink / raw
  To: libc-alpha



On 18/06/2019 13:33, Mike Crowe wrote:
> nptl: Add POSIX-proposed pthread_mutex_clocklock function that works like
> pthread_mutex_timedlock but takes a clockid parameter to measure the
> abstime parameter against.

LGTM with smalls nits regarding comments.

> 
> * sysdeps/nptl/pthread.h: Add pthread_mutex_clocklock.
> 
> * nptl/DESIGN-systemtap-probes.txt: Likewise.
> 
> * nptl/pthread_mutex_timedlock.c (__pthread_mutex_clocklock_common): Rename
>   from __pthread_mutex_timedlock and add clockid parameter. Pass this
>   parameter to lll_clocklock and lll_clocklock_elision in place of
>   CLOCK_REALTIME. (__pthread_mutex_clocklock): New function to add
>   LIBC_PROBE and validate clockid parameter before calling
>   __pthread_mutex_clocklock_common. (__pthread_mutex_timedlock): New
>   implementation to add LIBC_PROBE and calls
>   __pthread_mutex_clocklock_common passing CLOCK_REALTIME as the clockid.
> 
> * nptl/Makefile: Add tst-mutex11.c.
> 
> * nptl/tst-abstime.c (th): Add tests for pthread_mutex_clocklock.
> 
> * nptl/tst-mutex11.c: New tests for passing invalid and unsupported clockid
>   parameters to pthread_mutex_clocklock.
> 
> * nptl/tst-mutex5.c (do_test_clock): Rename from do_test and take clockid
>   parameter to indicate which clock to be used. Call
>   pthread_mutex_timedlock or pthread_mutex_clocklock as appropriate.
>   (do_test): Call do_test_clock to separately test pthread_mutex_timedlock,
>   pthread_mutex_clocklock(CLOCK_REALTIME) and
>   pthread_mutex_clocklock(CLOCK_MONOTONIC).
> 
> * nptl/tst-mutex9.c: Likewise.
> 
> * nptl/Versions (GLIBC_2.30): Add pthread_mutex_clocklock.
> 
> * sysdeps/unix/sysv/linux/aarch64/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * sysdeps/unix/sysv/linux/alpha/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * sysdeps/unix/sysv/linux/arm/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * sysdeps/unix/sysv/linux/csky/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * sysdeps/unix/sysv/linux/hppa/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * sysdeps/unix/sysv/linux/i386/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * sysdeps/unix/sysv/linux/ia64/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * sysdeps/unix/sysv/linux/microblaze/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * sysdeps/unix/sysv/linux/nios2/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
>   (GLIBC_2.30): Likewise.
> 
> * sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
>   (GLIBC_2.30): Likewise.
> 
> * sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
>   (GLIBC_2.30): Likewise.
> 
> * sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * sysdeps/unix/sysv/linux/sh/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> 
> * sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist (GLIBC_2.30):
>   Likewise.
> ---
>  ChangeLog                                                       | 81 +++++++-
>  nptl/DESIGN-systemtap-probes.txt                                |  3 +-
>  nptl/Makefile                                                   |  2 +-
>  nptl/Versions                                                   |  1 +-
>  nptl/pthread_mutex_timedlock.c                                  | 40 ++-
>  nptl/tst-abstime.c                                              |  2 +-
>  nptl/tst-mutex11.c                                              | 69 ++++++-
>  nptl/tst-mutex5.c                                               | 36 ++-
>  nptl/tst-mutex9.c                                               | 24 +-
>  sysdeps/nptl/pthread.h                                          |  7 +-
>  sysdeps/unix/sysv/linux/aarch64/libpthread.abilist              |  1 +-
>  sysdeps/unix/sysv/linux/alpha/libpthread.abilist                |  1 +-
>  sysdeps/unix/sysv/linux/arm/libpthread.abilist                  |  1 +-
>  sysdeps/unix/sysv/linux/csky/libpthread.abilist                 |  1 +-
>  sysdeps/unix/sysv/linux/hppa/libpthread.abilist                 |  1 +-
>  sysdeps/unix/sysv/linux/i386/libpthread.abilist                 |  1 +-
>  sysdeps/unix/sysv/linux/ia64/libpthread.abilist                 |  1 +-
>  sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist        |  1 +-
>  sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist          |  1 +-
>  sysdeps/unix/sysv/linux/microblaze/libpthread.abilist           |  1 +-
>  sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist          |  1 +-
>  sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist          |  1 +-
>  sysdeps/unix/sysv/linux/nios2/libpthread.abilist                |  1 +-
>  sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist    |  1 +-
>  sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist |  1 +-
>  sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist |  1 +-
>  sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist           |  1 +-
>  sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist         |  1 +-
>  sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist         |  1 +-
>  sysdeps/unix/sysv/linux/sh/libpthread.abilist                   |  1 +-
>  sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist        |  1 +-
>  sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist        |  1 +-
>  sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist            |  1 +-
>  sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist           |  1 +-
>  34 files changed, 267 insertions(+), 22 deletions(-)
>  create mode 100644 nptl/tst-mutex11.c
> 
> diff --git a/ChangeLog b/ChangeLog
> index 713c677..a213eb1 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,5 +1,86 @@
>  2019-05-31  Mike Crowe  <mac@mcrowe.com>
>  
> +	nptl: Add POSIX-proposed pthread_mutex_clocklock function that
> +	works like pthread_mutex_timedlock but takes a clockid parameter to
> +	measure the abstime parameter against.
> +
> +	* sysdeps/nptl/pthread.h: Add pthread_mutex_clocklock.
> +	* nptl/DESIGN-systemtap-probes.txt: Likewise.
> +	* nptl/pthread_mutex_timedlock.c
> +	(__pthread_mutex_clocklock_common): Rename from
> +	__pthread_mutex_timedlock and add clockid parameter. Pass this
> +	parameter to lll_clocklock and lll_clocklock_elision in place of
> +	CLOCK_REALTIME. (__pthread_mutex_clocklock): New function to add
> +	LIBC_PROBE and validate clockid parameter before calling
> +	__pthread_mutex_clocklock_common. (__pthread_mutex_timedlock): New
> +	implementation to add LIBC_PROBE and calls
> +	__pthread_mutex_clocklock_common passing CLOCK_REALTIME as the
> +	clockid.
> +
> +	* nptl/Makefile: Add tst-mutex11.c.
> +	* nptl/tst-abstime.c (th): Add tests for pthread_mutex_clocklock.
> +	* nptl/tst-mutex11.c: New tests for passing invalid and unsupported
> +	clockid parameters to pthread_mutex_clocklock.
> +	* nptl/tst-mutex5.c (do_test_clock): Rename from do_test and take
> +	clockid parameter to indicate which clock to be used. Call
> +	pthread_mutex_timedlock or pthread_mutex_clocklock as appropriate.
> +	(do_test): Call do_test_clock to separately test
> +	pthread_mutex_timedlock, pthread_mutex_clocklock(CLOCK_REALTIME)
> +	and pthread_mutex_clocklock(CLOCK_MONOTONIC).
> +	* nptl/tst-mutex9.c: Likewise.
> +
> +	* nptl/Versions (GLIBC_2.30): Add pthread_mutex_clocklock.
> +	* sysdeps/unix/sysv/linux/aarch64/libpthread.abilist (GLIBC_2.30):
> +	Likewise.
> +	* sysdeps/unix/sysv/linux/alpha/libpthread.abilist (GLIBC_2.30):
> +	Likewise.
> +	* sysdeps/unix/sysv/linux/arm/libpthread.abilist (GLIBC_2.30):
> +	Likewise.
> +	* sysdeps/unix/sysv/linux/csky/libpthread.abilist (GLIBC_2.30):
> +	Likewise.
> +	* sysdeps/unix/sysv/linux/hppa/libpthread.abilist (GLIBC_2.30):
> +	Likewise.
> +	* sysdeps/unix/sysv/linux/i386/libpthread.abilist (GLIBC_2.30):
> +	Likewise.
> +	* sysdeps/unix/sysv/linux/ia64/libpthread.abilist (GLIBC_2.30):
> +	Likewise.
> +	* sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/nios2/libpthread.abilist (GLIBC_2.30):
> +	Likewise.
> +	* sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/sh/libpthread.abilist (GLIBC_2.30):
> +	Likewise.
> +	* sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +	* sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
> +	(GLIBC_2.30): Likewise.
> +
> +2019-05-31  Mike Crowe  <mac@mcrowe.com>
> +
>  	nptl: Rename lll_timedlock to lll_clocklock and add clockid
>  	parameter to indicate the clock that the abstime parameter should
>  	be measured against in preparation for adding

Ok.

> diff --git a/nptl/DESIGN-systemtap-probes.txt b/nptl/DESIGN-systemtap-probes.txt
> index ac972a9..6a62e25 100644
> --- a/nptl/DESIGN-systemtap-probes.txt
> +++ b/nptl/DESIGN-systemtap-probes.txt
> @@ -32,6 +32,9 @@ mutex_entry   - probe for entry to the pthread_mutex_lock function
>                arg1 = address of mutex lock
>  mutex_timedlock_entry - probe for entry to the pthread_mutex_timedlock function
>                        arg1 = address of mutex lock, arg2 = address of timespec
> +mutex_clocklock_entry - probe for entry to the pthread_mutex_clocklock function
> +                      arg1 = address of mutex lock, arg2 = clockid,
> +		      arg3 = address of timespec
>  mutex_release - probe for pthread_mutex_unlock after the successful release of a
>                  mutex lock
>                arg1 = address of mutex lock

Ok.

> diff --git a/nptl/Makefile b/nptl/Makefile
> index d86513a..a2d25fb 100644
> --- a/nptl/Makefile
> +++ b/nptl/Makefile
> @@ -243,7 +243,7 @@ LDLIBS-tst-minstack-throw = -lstdc++
>  
>  tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
>  	tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \
> -	tst-mutex7 tst-mutex9 tst-mutex10 tst-mutex5a tst-mutex7a \
> +	tst-mutex7 tst-mutex9 tst-mutex10 tst-mutex11 tst-mutex5a tst-mutex7a \
>  	tst-mutex7robust tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 \
>  	tst-mutexpi5 tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a \
>  	tst-mutexpi9 \

Ok.

> diff --git a/nptl/Versions b/nptl/Versions
> index ce79959..e903b84 100644
> --- a/nptl/Versions
> +++ b/nptl/Versions
> @@ -280,6 +280,7 @@ libpthread {
>    GLIBC_2.30 {
>      sem_clockwait; pthread_cond_clockwait;
>      pthread_rwlock_clockrdlock; pthread_rwlock_clockwrlock;
> +    pthread_mutex_clocklock;
>    }
>  
>    GLIBC_PRIVATE {

Ok.

> diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
> index 10a9989..52c258e 100644
> --- a/nptl/pthread_mutex_timedlock.c
> +++ b/nptl/pthread_mutex_timedlock.c
> @@ -42,15 +42,14 @@
>  #endif
>  
>  int
> -__pthread_mutex_timedlock (pthread_mutex_t *mutex,
> -			   const struct timespec *abstime)
> +__pthread_mutex_clocklock_common (pthread_mutex_t *mutex,
> +				  clockid_t clockid,
> +				  const struct timespec *abstime)
>  {
>    int oldval;
>    pid_t id = THREAD_GETMEM (THREAD_SELF, tid);
>    int result = 0;
>  
> -  LIBC_PROBE (mutex_timedlock_entry, 2, mutex, abstime);
> -
>    /* We must not check ABSTIME here.  If the thread does not block
>       abstime must not be checked for a valid value.  */
>  
> @@ -76,7 +75,7 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
>  	}
>  
>        /* We have to get the mutex.  */
> -      result = lll_clocklock (mutex->__data.__lock, CLOCK_REALTIME, abstime,
> +      result = lll_clocklock (mutex->__data.__lock, clockid, abstime,
>  			      PTHREAD_MUTEX_PSHARED (mutex));
>  
>        if (result != 0)

Ok.

> @@ -99,7 +98,7 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
>        FORCE_ELISION (mutex, goto elision);
>      simple:
>        /* Normal mutex.  */
> -      result = lll_clocklock (mutex->__data.__lock, CLOCK_REALTIME, abstime,
> +      result = lll_clocklock (mutex->__data.__lock, clockid, abstime,
>  			      PTHREAD_MUTEX_PSHARED (mutex));
>        break;
>  
> @@ -108,7 +107,7 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
>        /* Don't record ownership */
>        return lll_clocklock_elision (mutex->__data.__lock,
>  				    mutex->__data.__spins,
> -				    CLOCK_REALTIME, abstime,
> +				    clockid, abstime,
>  				    PTHREAD_MUTEX_PSHARED (mutex));
>  
>  
> @@ -126,7 +125,7 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
>  	      if (cnt++ >= max_cnt)
>  		{
>  		  result = lll_clocklock (mutex->__data.__lock,
> -					  CLOCK_REALTIME, abstime,
> +					  clockid, abstime,
>  					  PTHREAD_MUTEX_PSHARED (mutex));
>  		  break;
>  		}
> @@ -269,7 +268,7 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
>  
>  	  /* Block using the futex.  */
>  	  int err = lll_futex_clock_wait_bitset (&mutex->__data.__lock,
> -	      oldval, CLOCK_REALTIME, abstime,
> +	      oldval, clockid, abstime,
>  	      PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
>  	  /* The futex call timed out.  */
>  	  if (err == -ETIMEDOUT)
> @@ -405,7 +404,7 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
>  		    struct timespec reltime;
>  		    struct timespec now;
>  
> -		    INTERNAL_SYSCALL (clock_gettime, __err, 2, CLOCK_REALTIME,
> +		    INTERNAL_SYSCALL (clock_gettime, __err, 2, clockid,
>  				      &now);
>  		    reltime.tv_sec = abstime->tv_sec - now.tv_sec;
>  		    reltime.tv_nsec = abstime->tv_nsec - now.tv_nsec;

Ok.

> @@ -623,4 +622,25 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
>   out:
>    return result;
>  }
> +
> +int
> +__pthread_mutex_clocklock (pthread_mutex_t *mutex,
> +			   clockid_t clockid,
> +			   const struct timespec *abstime)
> +{
> +  if (__glibc_unlikely (!lll_futex_supported_clockid (clockid)))
> +    return EINVAL;
> +
> +  LIBC_PROBE (mutex_clocklock_entry, 3, mutex, clockid, abstime);
> +  return __pthread_mutex_clocklock_common (mutex, clockid, abstime);
> +}
> +weak_alias (__pthread_mutex_clocklock, pthread_mutex_clocklock)
> +
> +int
> +__pthread_mutex_timedlock (pthread_mutex_t *mutex,
> +			   const struct timespec *abstime)
> +{
> +  LIBC_PROBE (mutex_timedlock_entry, 2, mutex, abstime);
> +  return __pthread_mutex_clocklock_common (mutex, CLOCK_REALTIME, abstime);
> +}
>  weak_alias (__pthread_mutex_timedlock, pthread_mutex_timedlock)

Ok.

> diff --git a/nptl/tst-abstime.c b/nptl/tst-abstime.c
> index c5040c5..30dea4d 100644
> --- a/nptl/tst-abstime.c
> +++ b/nptl/tst-abstime.c
> @@ -36,6 +36,8 @@ th (void *arg)
>    struct timespec t = { -2, 0 };
>  
>    TEST_COMPARE (pthread_mutex_timedlock (&m1, &t), ETIMEDOUT);
> +  TEST_COMPARE (pthread_mutex_clocklock (&m1, CLOCK_REALTIME, &t), ETIMEDOUT);
> +  TEST_COMPARE (pthread_mutex_clocklock (&m1, CLOCK_MONOTONIC, &t), ETIMEDOUT);
>    TEST_COMPARE (pthread_rwlock_timedrdlock (&rw1, &t), ETIMEDOUT);
>    TEST_COMPARE (pthread_rwlock_timedwrlock (&rw2, &t), ETIMEDOUT);
>    TEST_COMPARE (pthread_rwlock_clockrdlock (&rw1, CLOCK_REALTIME, &t),

Ok.

> diff --git a/nptl/tst-mutex11.c b/nptl/tst-mutex11.c
> new file mode 100644
> index 0000000..91f4281
> --- /dev/null
> +++ b/nptl/tst-mutex11.c
> @@ -0,0 +1,69 @@
> +/* Test unsupported/bad clocks passed to pthread_mutex_clocklock.
> +
> +   Copyright (C) 2019 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
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <errno.h>
> +#include <pthread.h>
> +#include <stdio.h>
> +#include <time.h>
> +#include <unistd.h>
> +#include <support/check.h>
> +
> +static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
> +
> +static void test_bad_clockid (clockid_t clockid)
> +{
> +  const struct timespec ts = {0,0};
> +  TEST_COMPARE (pthread_mutex_clocklock (&mut, clockid, &ts), EINVAL);
> +}
> +
> +#define NOT_A_VALID_CLOCK 123456
> +
> +static int
> +do_test (void)
> +{
> +  /* These clocks are meaningless to pthread_mutex_clocklock. */
> +#if defined(CLOCK_PROCESS_CPUTIME_ID)
> +  test_bad_clockid (CLOCK_PROCESS_CPUTIME_ID);
> +#endif
> +#if defined(CLOCK_THREAD_CPUTIME_ID)
> +  test_bad_clockid (CLOCK_PROCESS_CPUTIME_ID);
> +#endif
> +
> +  /* These clocks might be meaningful, but are currently unsupported
> +     by pthread_mutex_clocklock. */
> +#if defined(CLOCK_REALTIME_COARSE)
> +  test_bad_clockid (CLOCK_REALTIME_COARSE);
> +#endif
> +#if defined(CLOCK_MONOTONIC_RAW)
> +  test_bad_clockid (CLOCK_MONOTONIC_RAW);
> +#endif
> +#if defined(CLOCK_MONOTONIC_COARSE)
> +  test_bad_clockid (CLOCK_MONOTONIC_COARSE);
> +#endif
> +#if defined(CLOCK_BOOTTIME)
> +  test_bad_clockid (CLOCK_BOOTTIME);
> +#endif
> +
> +  /* This is a completely invalid clock. */
> +  test_bad_clockid (NOT_A_VALID_CLOCK);
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>

Ok.

> diff --git a/nptl/tst-mutex5.c b/nptl/tst-mutex5.c
> index fb27152..838ef7f 100644
> --- a/nptl/tst-mutex5.c
> +++ b/nptl/tst-mutex5.c
> @@ -32,12 +32,17 @@
>  # define TYPE PTHREAD_MUTEX_NORMAL
>  #endif
>  
> +/* A bogus clock value that tells run_test to use
> +   pthread_mutex_timedlock rather than pthread_mutex_clocklock. */
> +#define CLOCK_USE_TIMEDLOCK (-1)

Two spaces after period (I will fix it for you). 

>  
>  static int
> -do_test (void)
> +do_test_clock (clockid_t clockid, const char *fnname)
>  {
>    pthread_mutex_t m;
>    pthread_mutexattr_t a;
> +  const clockid_t clockid_for_get =
> +    (clockid == CLOCK_USE_TIMEDLOCK) ? CLOCK_REALTIME : clockid;
>  
>    TEST_COMPARE (pthread_mutexattr_init (&a), 0);
>    TEST_COMPARE (pthread_mutexattr_settype (&a, TYPE), 0);
> @@ -62,16 +67,22 @@ do_test (void)
>      FAIL_EXIT1 ("mutex_trylock succeeded");
>  
>    /* Wait 2 seconds.  */
> -  struct timespec ts_timeout = timespec_add (xclock_now (CLOCK_REALTIME),
> +  struct timespec ts_timeout = timespec_add (xclock_now (clockid_for_get),
>                                               make_timespec (2, 0));
>  
> -  TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), ETIMEDOUT);
> -  TEST_TIMESPEC_BEFORE_NOW (ts_timeout, CLOCK_REALTIME);
> +  if (clockid == CLOCK_USE_TIMEDLOCK)
> +    TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), ETIMEDOUT);
> +  else
> +    TEST_COMPARE (pthread_mutex_clocklock (&m, clockid, &ts_timeout), ETIMEDOUT);

Line too long.

> +  TEST_TIMESPEC_BEFORE_NOW (ts_timeout, clockid_for_get);
>  
>    /* The following makes the ts value invalid.  */
>    ts_timeout.tv_nsec += 1000000000;
>  
> -  TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), EINVAL);
> +  if (clockid == CLOCK_USE_TIMEDLOCK)
> +    TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), EINVAL);
> +  else
> +    TEST_COMPARE (pthread_mutex_clocklock (&m, clockid, &ts_timeout), EINVAL);
>    TEST_COMPARE (pthread_mutex_unlock (&m), 0);
>  
>    const struct timespec ts_start = xclock_now (CLOCK_REALTIME);
> @@ -79,9 +90,12 @@ do_test (void)
>    /* Wait 2 seconds.  */
>    ts_timeout = timespec_add (ts_start, make_timespec (2, 0));
>  
> -  TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), 0);
> +  if (clockid == CLOCK_USE_TIMEDLOCK)
> +    TEST_COMPARE (pthread_mutex_timedlock (&m, &ts_timeout), 0);
> +  else
> +    TEST_COMPARE (pthread_mutex_clocklock (&m, clockid, &ts_timeout), 0);
>  
> -  const struct timespec ts_end = xclock_now (CLOCK_REALTIME);
> +  const struct timespec ts_end = xclock_now (clockid_for_get);
>  
>    /* Check that timedlock didn't delay.  We use a limit of 0.1 secs.  */
>    TEST_TIMESPEC_BEFORE (ts_end,
> @@ -93,4 +107,12 @@ do_test (void)
>    return 0;
>  }
>  
> +static int do_test (void)
> +{
> +  do_test_clock (CLOCK_USE_TIMEDLOCK, "timedlock");
> +  do_test_clock (CLOCK_REALTIME, "clocklock(realtime)");
> +  do_test_clock (CLOCK_MONOTONIC, "clocklock(monotonic)");
> +  return 0;
> +}
> +
>  #include <support/test-driver.c>

Ok.

> diff --git a/nptl/tst-mutex9.c b/nptl/tst-mutex9.c
> index e9fd8e2..c058d20 100644
> --- a/nptl/tst-mutex9.c
> +++ b/nptl/tst-mutex9.c
> @@ -31,9 +31,15 @@
>  #include <support/xunistd.h>
>  
>  
> -static int
> -do_test (void)
> +/* A bogus clock value that tells run_test to use
> +   pthread_mutex_timedlock rather than pthread_mutex_clocklock. */

Two spaces after period (I will fix it for you). 

> +#define CLOCK_USE_TIMEDLOCK (-1)
> +
> +static void
> +do_test_clock (clockid_t clockid)
>  {
> +  const clockid_t clockid_for_get =
> +    (clockid == CLOCK_USE_TIMEDLOCK) ? CLOCK_REALTIME : clockid;
>    size_t ps = sysconf (_SC_PAGESIZE);
>    char tmpfname[] = "/tmp/tst-mutex9.XXXXXX";
>    char data[ps];
> @@ -95,10 +101,13 @@ do_test (void)
>        if (pthread_mutex_unlock (m) == 0)
>          FAIL_EXIT1 ("child: mutex_unlock succeeded");
>  
> -      const struct timespec ts = timespec_add (xclock_now (CLOCK_REALTIME),
> +      const struct timespec ts = timespec_add (xclock_now (clockid_for_get),
>                                                 make_timespec (0, 500000000));
>  
> -      TEST_COMPARE (pthread_mutex_timedlock (m, &ts), ETIMEDOUT);
> +      if (clockid == CLOCK_USE_TIMEDLOCK)
> +        TEST_COMPARE (pthread_mutex_timedlock (m, &ts), ETIMEDOUT);
> +      else
> +        TEST_COMPARE (pthread_mutex_clocklock (m, clockid, &ts), ETIMEDOUT);
>  
>        alarm (1);
>  
> @@ -117,7 +126,14 @@ do_test (void)
>    if (! WIFSIGNALED (status))
>      FAIL_EXIT1 ("child not killed by signal");
>    TEST_COMPARE (WTERMSIG (status), SIGALRM);
> +}
>  
> +static int
> +do_test (void)
> +{
> +  do_test_clock (CLOCK_USE_TIMEDLOCK);
> +  do_test_clock (CLOCK_REALTIME);
> +  do_test_clock (CLOCK_MONOTONIC);
>    return 0;
>  }
>  

Ok.

> diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
> index e78003e..a767d6f 100644
> --- a/sysdeps/nptl/pthread.h
> +++ b/sysdeps/nptl/pthread.h
> @@ -770,6 +770,13 @@ extern int pthread_mutex_timedlock (pthread_mutex_t *__restrict __mutex,
>  				    __abstime) __THROWNL __nonnull ((1, 2));
>  #endif
>  
> +#ifdef __USE_GNU
> +extern int pthread_mutex_clocklock (pthread_mutex_t *__restrict __mutex,
> +				    clockid_t __clockid,
> +				    const struct timespec *__restrict
> +				    __abstime) __THROWNL __nonnull ((1, 3));
> +#endif
> +
>  /* Unlock a mutex.  */
>  extern int pthread_mutex_unlock (pthread_mutex_t *__mutex)
>       __THROWNL __nonnull ((1));

Ok.

> diff --git a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
> index 9f65baf..69f48bf 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
> @@ -244,6 +244,7 @@ GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
> index 0709855..d1d53cf 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
> @@ -228,6 +228,7 @@ GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/arm/libpthread.abilist b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
> index a2be572..3d2287b 100644
> --- a/sysdeps/unix/sysv/linux/arm/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
> @@ -28,6 +28,7 @@ GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/csky/libpthread.abilist b/sysdeps/unix/sysv/linux/csky/libpthread.abilist
> index c3a1834..52373fc 100644
> --- a/sysdeps/unix/sysv/linux/csky/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/csky/libpthread.abilist
> @@ -234,6 +234,7 @@ GLIBC_2.29 wait F
>  GLIBC_2.29 waitpid F
>  GLIBC_2.29 write F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
> index 2a00ebc..d11e150 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
> @@ -246,6 +246,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/i386/libpthread.abilist b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
> index 4479947..1b385ca 100644
> --- a/sysdeps/unix/sysv/linux/i386/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
> @@ -254,6 +254,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
> index 40a1faf..bde9948 100644
> --- a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
> @@ -248,6 +248,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
> index a2be572..3d2287b 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
> @@ -28,6 +28,7 @@ GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
> index 4479947..1b385ca 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
> @@ -254,6 +254,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
> index 254b708..f0365f3 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
> @@ -244,6 +244,7 @@ GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
> index 29ffdd1..b1dff8e 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
> @@ -256,6 +256,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
> index 29ffdd1..b1dff8e 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
> @@ -256,6 +256,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
> index 3fae328..0150ea3 100644
> --- a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
> @@ -242,6 +242,7 @@ GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
> index a90010d..9e71e17 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
> @@ -256,6 +256,7 @@ GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.3.4 siglongjmp F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
> index 339eab8..393ec87 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
> @@ -247,6 +247,7 @@ GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.3.4 siglongjmp F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
> index 9f65baf..69f48bf 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
> @@ -244,6 +244,7 @@ GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> index 83082fb..7dab4e5 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
> @@ -236,6 +236,7 @@ GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
> index 54e937b..7db2a0c 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
> @@ -256,6 +256,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
> index 87f978b..7c10bb2 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
> @@ -248,6 +248,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/sh/libpthread.abilist b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
> index 2a00ebc..d11e150 100644
> --- a/sysdeps/unix/sysv/linux/sh/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
> @@ -246,6 +246,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
> index bc29a66..7aa6416 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
> @@ -256,6 +256,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
> index 40a1faf..bde9948 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
> @@ -248,6 +248,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> index 70f04cc..c5ecb12 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> @@ -246,6 +246,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
>  GLIBC_2.3.4 pthread_setaffinity_np F
>  GLIBC_2.3.4 pthread_setschedprio F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
> index 92cd2f4..a7ff3fb 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
> @@ -244,6 +244,7 @@ GLIBC_2.28 tss_delete F
>  GLIBC_2.28 tss_get F
>  GLIBC_2.28 tss_set F
>  GLIBC_2.30 pthread_cond_clockwait F
> +GLIBC_2.30 pthread_mutex_clocklock F
>  GLIBC_2.30 pthread_rwlock_clockrdlock F
>  GLIBC_2.30 pthread_rwlock_clockwrlock F
>  GLIBC_2.30 sem_clockwait F
> 

Ok.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v4 11/12] Update NEWS for new _clockwait and _clocklock functions
  2019-06-18 16:33 ` [PATCH v4 11/12] Update NEWS for new _clockwait and _clocklock functions Mike Crowe
@ 2019-06-25 22:01   ` Adhemerval Zanella
  0 siblings, 0 replies; 32+ messages in thread
From: Adhemerval Zanella @ 2019-06-25 22:01 UTC (permalink / raw
  To: libc-alpha



On 18/06/2019 13:33, Mike Crowe wrote:
> * NEWS: Mention recently-added pthread_cond_clockwait,
> 	pthread_mutex_clocklock, pthread_rwlock_clockrdlock,
> 	pthread_rwlock_clockwrlock and sem_clockwait functions.

LGTM, I will commit this for you.

> ---
>  ChangeLog |  6 ++++++
>  NEWS      |  9 +++++++++
>  2 files changed, 15 insertions(+)
> 
> diff --git a/ChangeLog b/ChangeLog
> index a213eb1..984275c 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,3 +1,9 @@
> +2019-05-27  Mike Crowe  <mac@mcrowe.com>
> +
> +	* NEWS: Mention recently-added pthread_cond_clockwait,
> +	pthread_rwlock_clockrdlock, pthread_rwlock_clockwrlock and
> +	sem_clockwait functions.
> +
>  2019-05-31  Mike Crowe  <mac@mcrowe.com>
>  
>  	nptl: Add POSIX-proposed pthread_mutex_clocklock function that
> diff --git a/NEWS b/NEWS
> index 8a2fece..653a69d 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -34,6 +34,15 @@ Major new features:
>    pointer subtraction within the allocated object, where results might
>    overflow the ptrdiff_t type.
>  
> +* Add new POSIX-proposed pthread_cond_clockwait, pthread_mutex_clocklock,
> +  pthread_rwlock_clockrdlock, pthread_rwlock_clockwrlock and sem_clockwait
> +  functions. These behave similarly to their "timed" equivalents, but also
> +  accept a clockid_t parameter to determine which clock their timeout should
> +  be measured against. All functions allow waiting against CLOCK_MONOTONIC
> +  and CLOCK_REALTIME. The decision of which clock to be used is made at the
> +  time of the wait (unlike with pthread_condattr_setclock, which requires
> +  the clock choice at initialization time.)
> +

Two spaces after period and ) after period (I will fix it for you). 

>  Deprecated and removed features, and other changes affecting compatibility:
>  
>  * The functions clock_gettime, clock_getres, clock_settime,
> 

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v4 12/12] nptl: Remove futex_supports_exact_relative_timeouts
  2019-06-18 16:33 ` [PATCH v4 12/12] nptl: Remove futex_supports_exact_relative_timeouts Mike Crowe
@ 2019-06-25 22:09   ` Adhemerval Zanella
  0 siblings, 0 replies; 32+ messages in thread
From: Adhemerval Zanella @ 2019-06-25 22:09 UTC (permalink / raw
  To: libc-alpha



On 18/06/2019 13:33, Mike Crowe wrote:
> The only implementation of futex_supports_exact_relative_timeouts always
> returns true. Let's remove it and all its callers.

LGTM.

> 
> * nptl/pthread_cond_wait.c: (__pthread_cond_clockwait): Remove code that is
>   only useful if futex_supports_exact_relative_timeouts () returns false.
> 
> * nptl/pthread_condattr_setclock.c: (pthread_condattr_setclock): Likewise.
> 
> * sysdeps/nptl/futex-internal.h: Remove comment about relative timeouts
>   potentially being imprecise since it's no longer true. Remove declaration
>   of futex_supports_exact_relative_timeouts.
> 
> * sysdeps/unix/sysv/linux/futex-internal.h: Remove implementation of
>   futex_supports_exact_relative_timeouts.

Ok.

> ---
>  ChangeLog                                | 13 +++++++++++++
>  nptl/pthread_cond_wait.c                 |  5 -----
>  nptl/pthread_condattr_setclock.c         |  5 -----
>  sysdeps/nptl/futex-internal.h            |  9 +--------
>  sysdeps/unix/sysv/linux/futex-internal.h |  8 --------
>  5 files changed, 14 insertions(+), 26 deletions(-)
> 
> diff --git a/ChangeLog b/ChangeLog
> index 984275c..cf07e4d 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,3 +1,16 @@
> +2019-06-18  Mike Crowe  <mac@mcrowe.com>
> +
> +	* nptl/pthread_cond_wait.c: (__pthread_cond_clockwait): Remove code
> +	that is only useful if futex_supports_exact_relative_timeouts ()
> +	returns false.
> +	* nptl/pthread_condattr_setclock.c: (pthread_condattr_setclock):
> +	Likewise.
> +	* sysdeps/nptl/futex-internal.h: Remove comment about relative
> +	timeouts potentially being imprecise since it's no longer true.
> +	Remove declaration of futex_supports_exact_relative_timeouts.
> +	* sysdeps/unix/sysv/linux/futex-internal.h: Remove implementation
> +	of futex_supports_exact_relative_timeouts.
> +
>  2019-05-27  Mike Crowe  <mac@mcrowe.com>
>  
>  	* NEWS: Mention recently-added pthread_cond_clockwait,
> diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
> index 558f930..cd98f50 100644
> --- a/nptl/pthread_cond_wait.c
> +++ b/nptl/pthread_cond_wait.c
> @@ -670,11 +670,6 @@ __pthread_cond_clockwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
>    if (!futex_abstimed_supported_clockid (clockid))
>      return EINVAL;
>  
> -  /* If we do not support waiting using CLOCK_MONOTONIC, return an error.  */
> -  if (clockid == CLOCK_MONOTONIC
> -      && !futex_supports_exact_relative_timeouts ())
> -    return EINVAL;
> -
>    return __pthread_cond_wait_common (cond, mutex, clockid, abstime);
>  }
>  

Ok.

> diff --git a/nptl/pthread_condattr_setclock.c b/nptl/pthread_condattr_setclock.c
> index 641a041..ac91923 100644
> --- a/nptl/pthread_condattr_setclock.c
> +++ b/nptl/pthread_condattr_setclock.c
> @@ -33,11 +33,6 @@ pthread_condattr_setclock (pthread_condattr_t *attr, clockid_t clock_id)
>         in the pthread_cond_t structure needs to be adjusted.  */
>      return EINVAL;
>  
> -  /* If we do not support waiting using CLOCK_MONOTONIC, return an error.  */
> -  if (clock_id == CLOCK_MONOTONIC
> -      && !futex_supports_exact_relative_timeouts())
> -    return ENOTSUP;
> -
>    /* Make sure the value fits in the bits we reserved.  */
>    assert (clock_id < (1 << COND_CLOCK_BITS));
>  


Ok.

> diff --git a/sysdeps/nptl/futex-internal.h b/sysdeps/nptl/futex-internal.h
> index bc29bdb..9baae38 100644
> --- a/sysdeps/nptl/futex-internal.h
> +++ b/sysdeps/nptl/futex-internal.h
> @@ -51,8 +51,7 @@
>     Both absolute and relative timeouts can be used.  An absolute timeout
>     expires when the given specific point in time on the specified clock
>     passes, or when it already has passed.  A relative timeout expires when
> -   the given duration of time on the CLOCK_MONOTONIC clock passes.  Relative
> -   timeouts may be imprecise (see futex_supports_exact_relative_timeouts).
> +   the given duration of time on the CLOCK_MONOTONIC clock passes.
>  
>     Due to POSIX requirements on when synchronization data structures such
>     as mutexes or semaphores can be destroyed and due to the futex design
> @@ -81,12 +80,6 @@
>  static __always_inline int
>  futex_supports_pshared (int pshared);
>  
> -/* Returns true if relative timeouts are robust to concurrent changes to the
> -   system clock.  If this returns false, relative timeouts can still be used
> -   but might be effectively longer or shorter than requested.  */
> -static __always_inline bool
> -futex_supports_exact_relative_timeouts (void);
> -
>  /* Atomically wrt other futex operations on the same futex, this blocks iff
>     the value *FUTEX_WORD matches the expected value.  This is
>     semantically equivalent to:

Ok.

> diff --git a/sysdeps/unix/sysv/linux/futex-internal.h b/sysdeps/unix/sysv/linux/futex-internal.h
> index 03312d6..30707e7 100644
> --- a/sysdeps/unix/sysv/linux/futex-internal.h
> +++ b/sysdeps/unix/sysv/linux/futex-internal.h
> @@ -46,14 +46,6 @@ futex_supports_pshared (int pshared)
>      return EINVAL;
>  }
>  
> -/* The Linux kernel supports relative timeouts measured against the
> -   CLOCK_MONOTONIC clock.  */
> -static __always_inline bool
> -futex_supports_exact_relative_timeouts (void)
> -{
> -  return true;
> -}
> -
>  /* See sysdeps/nptl/futex-internal.h for details.  */
>  static __always_inline int
>  futex_wait (unsigned int *futex_word, unsigned int expected, int private)
> 

Ok.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions
  2019-06-18 16:33 [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions Mike Crowe
                   ` (12 preceding siblings ...)
  2019-06-19 19:33 ` [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions Adhemerval Zanella
@ 2019-06-25 22:13 ` Adhemerval Zanella
  2019-06-26 18:41   ` Adhemerval Zanella
  13 siblings, 1 reply; 32+ messages in thread
From: Adhemerval Zanella @ 2019-06-25 22:13 UTC (permalink / raw
  To: Mike Crowe, libc-alpha, Florian Weimer



On 18/06/2019 13:33, Mike Crowe wrote:
> My attempts[1] to add a variant of pthread_cond_timedwait that would accept
> a clockid_t parameter led me to propose[2] to The Austin Group the addition
> of an entire family of functions that accept a clockid_t parameter to
> indicate the clock that the timespec absolute timeout parameter should be
> measured against. They responded positively to the request but an
> implementation is required before the proposal can proceed.
> 
> This patch series is the second version of the first part of that
> implementation in glibc, it contains implementations and tests for
> four new functions:
> 
> int pthread_cond_clockwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
>                            clockid_t clock, const struct timespec *abstime)
> 
> int pthread_rwlock_clockrdlock(pthread_rwlock_t *rwlock, clockid_t clock,
>                                const struct timespec *abstime)
> 
> int pthread_rwlock_clockwrlock(pthread_rwlock_t *rwlock, clockid_t clock,
>                                const struct timespec *abstime)
> 
> int sem_clockwait(sem_t *restrict, clockid_t clock_id, const struct
>                   timespec *restrict)
> 
> int pthread_mutex_clocklock (pthread_mutex_t *mutex,
> 			     clockid_t clockid,
> 			     const struct timespec *abstime)

Hi Mike, 

I have created a personal branch [1] with remaining patches with the small
fixes I pointed on the review.  It just to make it simpler you give me ack
and avoid resending all the patch all over again.

Florian, I am using the original naming scheme as indicated above. I think
we should follow what is expected from standard once we have an actual 
implementation.

[1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/master-posix_clock

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions
  2019-06-25 22:13 ` Adhemerval Zanella
@ 2019-06-26 18:41   ` Adhemerval Zanella
  2019-06-27 17:15     ` Mike Crowe
  0 siblings, 1 reply; 32+ messages in thread
From: Adhemerval Zanella @ 2019-06-26 18:41 UTC (permalink / raw
  To: Mike Crowe, libc-alpha, Florian Weimer



On 25/06/2019 19:13, Adhemerval Zanella wrote:
> 
> 
> On 18/06/2019 13:33, Mike Crowe wrote:
>> My attempts[1] to add a variant of pthread_cond_timedwait that would accept
>> a clockid_t parameter led me to propose[2] to The Austin Group the addition
>> of an entire family of functions that accept a clockid_t parameter to
>> indicate the clock that the timespec absolute timeout parameter should be
>> measured against. They responded positively to the request but an
>> implementation is required before the proposal can proceed.
>>
>> This patch series is the second version of the first part of that
>> implementation in glibc, it contains implementations and tests for
>> four new functions:
>>
>> int pthread_cond_clockwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
>>                            clockid_t clock, const struct timespec *abstime)
>>
>> int pthread_rwlock_clockrdlock(pthread_rwlock_t *rwlock, clockid_t clock,
>>                                const struct timespec *abstime)
>>
>> int pthread_rwlock_clockwrlock(pthread_rwlock_t *rwlock, clockid_t clock,
>>                                const struct timespec *abstime)
>>
>> int sem_clockwait(sem_t *restrict, clockid_t clock_id, const struct
>>                   timespec *restrict)
>>
>> int pthread_mutex_clocklock (pthread_mutex_t *mutex,
>> 			     clockid_t clockid,
>> 			     const struct timespec *abstime)
> 
> Hi Mike, 
> 
> I have created a personal branch [1] with remaining patches with the small
> fixes I pointed on the review.  It just to make it simpler you give me ack
> and avoid resending all the patch all over again.
> 
> Florian, I am using the original naming scheme as indicated above. I think
> we should follow what is expected from standard once we have an actual 
> implementation.
> 
> [1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/master-posix_clock
> 

Hi Mike, I have updated the branch with some other style fixes (mostly
regarding missing space before period).

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions
  2019-06-26 18:41   ` Adhemerval Zanella
@ 2019-06-27 17:15     ` Mike Crowe
  2019-07-02 17:46       ` Adhemerval Zanella
  0 siblings, 1 reply; 32+ messages in thread
From: Mike Crowe @ 2019-06-27 17:15 UTC (permalink / raw
  To: Adhemerval Zanella; +Cc: libc-alpha

On Wednesday 26 June 2019 at 15:41:24 -0300, Adhemerval Zanella wrote:
> On 25/06/2019 19:13, Adhemerval Zanella wrote:
> > 
> > 
> > On 18/06/2019 13:33, Mike Crowe wrote:
> >> My attempts[1] to add a variant of pthread_cond_timedwait that would accept
> >> a clockid_t parameter led me to propose[2] to The Austin Group the addition
> >> of an entire family of functions that accept a clockid_t parameter to
> >> indicate the clock that the timespec absolute timeout parameter should be
> >> measured against. They responded positively to the request but an
> >> implementation is required before the proposal can proceed.
> >>
> >> This patch series is the second version of the first part of that
> >> implementation in glibc, it contains implementations and tests for
> >> four new functions:
> >>
> >> int pthread_cond_clockwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
> >>                            clockid_t clock, const struct timespec *abstime)
> >>
> >> int pthread_rwlock_clockrdlock(pthread_rwlock_t *rwlock, clockid_t clock,
> >>                                const struct timespec *abstime)
> >>
> >> int pthread_rwlock_clockwrlock(pthread_rwlock_t *rwlock, clockid_t clock,
> >>                                const struct timespec *abstime)
> >>
> >> int sem_clockwait(sem_t *restrict, clockid_t clock_id, const struct
> >>                   timespec *restrict)
> >>
> >> int pthread_mutex_clocklock (pthread_mutex_t *mutex,
> >> 			     clockid_t clockid,
> >> 			     const struct timespec *abstime)
> > 
> > Hi Mike, 
> > 
> > I have created a personal branch [1] with remaining patches with the small
> > fixes I pointed on the review.  It just to make it simpler you give me ack
> > and avoid resending all the patch all over again.
> > 
> > Florian, I am using the original naming scheme as indicated above. I think
> > we should follow what is expected from standard once we have an actual 
> > implementation.
> > 
> > [1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/master-posix_clock
> > 
> 
> Hi Mike, I have updated the branch with some other style fixes (mostly
> regarding missing space before period).

Hi Adhemerval,

I've looked at the branch. It looks like you've used a tool to regenerate
the ChangeLog from the commit messages. This means that some of my more
detailed descriptions have gone missing (which is presumably fine.)
However, it means that a mistake in the commit message for

 nptl: Add POSIX-proposed pthread_rwlock_clockrdlock & pthread_rwlock_clockwrlock

is now in the ChangeLog too. Neither should contain the line:

I'll never get the hang of "two spaces after a period". Thanks for fixing
them up. I spotted that you've missed one in
sysdeps/unix/sysv/linux/lowlevellock-futex.h though:

 CLOCK_REALTIME timeouts for FUTEX_WAIT_BITSET. We could attempt to

It looks like you've also reformatted many of the comments with a longer
line length. I used the Emacs default of 70 characters. Should I have used
79 or 80?

Thanks for doing all this. It's looking quite tight to get this in for
v2.30 though. Is there anything else you're waiting for me to do?

Mike.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions
  2019-06-27 17:15     ` Mike Crowe
@ 2019-07-02 17:46       ` Adhemerval Zanella
  0 siblings, 0 replies; 32+ messages in thread
From: Adhemerval Zanella @ 2019-07-02 17:46 UTC (permalink / raw
  To: Mike Crowe; +Cc: libc-alpha, Florian Weimer



On 27/06/2019 14:15, Mike Crowe wrote:
> On Wednesday 26 June 2019 at 15:41:24 -0300, Adhemerval Zanella wrote:
>> On 25/06/2019 19:13, Adhemerval Zanella wrote:
>>>
>>>
>>> On 18/06/2019 13:33, Mike Crowe wrote:
>>>> My attempts[1] to add a variant of pthread_cond_timedwait that would accept
>>>> a clockid_t parameter led me to propose[2] to The Austin Group the addition
>>>> of an entire family of functions that accept a clockid_t parameter to
>>>> indicate the clock that the timespec absolute timeout parameter should be
>>>> measured against. They responded positively to the request but an
>>>> implementation is required before the proposal can proceed.
>>>>
>>>> This patch series is the second version of the first part of that
>>>> implementation in glibc, it contains implementations and tests for
>>>> four new functions:
>>>>
>>>> int pthread_cond_clockwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
>>>>                            clockid_t clock, const struct timespec *abstime)
>>>>
>>>> int pthread_rwlock_clockrdlock(pthread_rwlock_t *rwlock, clockid_t clock,
>>>>                                const struct timespec *abstime)
>>>>
>>>> int pthread_rwlock_clockwrlock(pthread_rwlock_t *rwlock, clockid_t clock,
>>>>                                const struct timespec *abstime)
>>>>
>>>> int sem_clockwait(sem_t *restrict, clockid_t clock_id, const struct
>>>>                   timespec *restrict)
>>>>
>>>> int pthread_mutex_clocklock (pthread_mutex_t *mutex,
>>>> 			     clockid_t clockid,
>>>> 			     const struct timespec *abstime)
>>>
>>> Hi Mike, 
>>>
>>> I have created a personal branch [1] with remaining patches with the small
>>> fixes I pointed on the review.  It just to make it simpler you give me ack
>>> and avoid resending all the patch all over again.
>>>
>>> Florian, I am using the original naming scheme as indicated above. I think
>>> we should follow what is expected from standard once we have an actual 
>>> implementation.
>>>
>>> [1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/master-posix_clock
>>>
>>
>> Hi Mike, I have updated the branch with some other style fixes (mostly
>> regarding missing space before period).
> 
> Hi Adhemerval,
> 
> I've looked at the branch. It looks like you've used a tool to regenerate
> the ChangeLog from the commit messages. This means that some of my more
> detailed descriptions have gone missing (which is presumably fine.)
> However, it means that a mistake in the commit message for
> 
>  nptl: Add POSIX-proposed pthread_rwlock_clockrdlock & pthread_rwlock_clockwrlock
> 
> is now in the ChangeLog too. Neither should contain the line:

I think I have corrected it and added the missing descriptions you have
added on your original submission.

> 
> I'll never get the hang of "two spaces after a period". Thanks for fixing
> them up. I spotted that you've missed one in
> sysdeps/unix/sysv/linux/lowlevellock-futex.h though:
> 
>  CLOCK_REALTIME timeouts for FUTEX_WAIT_BITSET. We could attempt to

Fixed.

> 
> It looks like you've also reformatted many of the comments with a longer
> line length. I used the Emacs default of 70 characters. Should I have used
> 79 or 80?

According to our syle and conventions wiki you should use 79-column lines [1].

> 
> Thanks for doing all this. It's looking quite tight to get this in for
> v2.30 though. Is there anything else you're waiting for me to do?

We need to get consensus on the naming scheme for the symbols itself. 
The personal branches uses the expected names I think we should go
for it. Florian seems to have doubts about it yet.

> 
> Mike.
> 

[1] https://sourceware.org/glibc/wiki/Style_and_Conventions

^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2019-07-02 17:46 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-06-18 16:33 [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions Mike Crowe
2019-06-18 16:33 ` [PATCH v4 01/12] support: Add xclock_now helper function Mike Crowe
2019-06-19 20:01   ` Adhemerval Zanella
2019-06-18 16:33 ` [PATCH v4 02/12] support: Invent verbose_printf macro Mike Crowe
2019-06-19 20:15   ` Adhemerval Zanella
2019-06-18 16:33 ` [PATCH v4 03/12] nptl: Convert various tests to use libsupport Mike Crowe
2019-06-19 20:33   ` Adhemerval Zanella
2019-06-18 16:33 ` [PATCH v4 04/12] nptl: Add clockid parameter to futex timed wait calls Mike Crowe
2019-06-21 14:51   ` Adhemerval Zanella
2019-06-18 16:33 ` [PATCH v4 05/12] nptl: Add POSIX-proposed sem_clockwait Mike Crowe
2019-06-21 16:02   ` Adhemerval Zanella
2019-06-22 20:44     ` Mike Crowe
2019-06-18 16:33 ` [PATCH v4 06/12] nptl: Add POSIX-proposed pthread_cond_clockwait Mike Crowe
2019-06-24 19:35   ` Adhemerval Zanella
2019-06-18 16:33 ` [PATCH v4 07/12] nptl: pthread_rwlock: Move timeout validation into _full functions Mike Crowe
2019-06-25 20:42   ` Adhemerval Zanella
2019-06-18 16:33 ` [PATCH v4 08/12] nptl: Add POSIX-proposed pthread_rwlock_clockrdlock & pthread_rwlock_clockwrlock Mike Crowe
2019-06-25 21:26   ` Adhemerval Zanella
2019-06-18 16:33 ` [PATCH v4 09/12] nptl: Rename lll_timedlock to lll_clocklock and add clockid parameter Mike Crowe
2019-06-25 21:36   ` Adhemerval Zanella
2019-06-18 16:33 ` [PATCH v4 10/12] nptl: Add POSIX-proposed pthread_mutex_clocklock Mike Crowe
2019-06-25 21:59   ` Adhemerval Zanella
2019-06-18 16:33 ` [PATCH v4 11/12] Update NEWS for new _clockwait and _clocklock functions Mike Crowe
2019-06-25 22:01   ` Adhemerval Zanella
2019-06-18 16:33 ` [PATCH v4 12/12] nptl: Remove futex_supports_exact_relative_timeouts Mike Crowe
2019-06-25 22:09   ` Adhemerval Zanella
2019-06-19 19:33 ` [PATCH v4 00/12] nptl: Implement POSIX-proposed _clock variants of existing _timed functions Adhemerval Zanella
2019-06-22 21:11   ` Mike Crowe
2019-06-25 22:13 ` Adhemerval Zanella
2019-06-26 18:41   ` Adhemerval Zanella
2019-06-27 17:15     ` Mike Crowe
2019-07-02 17:46       ` Adhemerval Zanella

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).