public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Semaphores: add sem_timedwait_monotonic GNU extension [BZ #14717]
@ 2018-12-13 20:28 Jan Klötzke
  2018-12-13 22:27 ` Joseph Myers
  0 siblings, 1 reply; 9+ messages in thread
From: Jan Klötzke @ 2018-12-13 20:28 UTC (permalink / raw)
  To: libc-alpha

As defined by POSIX.1-2001 the 'abstime' timeout of  sem_timedwait()
shall be based on CLOCK_REALTIME. This has the unpleasant effect that
application timeouts are affected by system clock adjustments.

The added sem_timedwait_monotonic() function behaves just like
sem_timedwait() but is based on CLOCK_MONOTONIC. An identically named
function is already provided by QNX for the same reasons.

Signed-off-by: Jan Klötzke <jan@kloetzke.net>
---

Tested on AArch64 and X86_64.

 ChangeLog                                          | 48 ++++++++++++++++++++++
 htl/Makefile                                       |  4 +-
 htl/Versions                                       |  3 ++
 manual/ipc.texi                                    | 11 +++++
 nptl/Makefile                                      |  3 +-
 nptl/Versions                                      |  4 ++
 nptl/sem_timedwait.c                               |  2 +-
 nptl/sem_timedwait_monotonic.c                     | 40 ++++++++++++++++++
 nptl/sem_wait.c                                    |  2 +-
 nptl/sem_waitcommon.c                              | 41 ++++++++++++++----
 sysdeps/htl/sem-timedwait-monotonic.c              | 32 +++++++++++++++
 sysdeps/htl/sem-timedwait.c                        |  7 ++--
 sysdeps/htl/sem-wait.c                             |  5 ++-
 sysdeps/mach/hurd/i386/libpthread.abilist          |  1 +
 sysdeps/pthread/semaphore.h                        |  6 +++
 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/hppa/libpthread.abilist    |  1 +
 sysdeps/unix/sysv/linux/i386/libpthread.abilist    |  1 +
 sysdeps/unix/sysv/linux/ia64/libpthread.abilist    |  1 +
 .../sysv/linux/m68k/coldfire/libpthread.abilist    |  1 +
 .../unix/sysv/linux/m68k/m680x0/libpthread.abilist |  1 +
 .../unix/sysv/linux/microblaze/libpthread.abilist  |  1 +
 .../unix/sysv/linux/mips/mips32/libpthread.abilist |  1 +
 .../unix/sysv/linux/mips/mips64/libpthread.abilist |  1 +
 sysdeps/unix/sysv/linux/nios2/libpthread.abilist   |  1 +
 .../linux/powerpc/powerpc32/libpthread.abilist     |  1 +
 .../linux/powerpc/powerpc64/be/libpthread.abilist  |  1 +
 .../linux/powerpc/powerpc64/le/libpthread.abilist  |  1 +
 .../unix/sysv/linux/riscv/rv64/libpthread.abilist  |  1 +
 .../sysv/linux/s390/s390-32/libpthread.abilist     |  1 +
 .../sysv/linux/s390/s390-64/libpthread.abilist     |  1 +
 sysdeps/unix/sysv/linux/sh/libpthread.abilist      |  1 +
 .../sysv/linux/sparc/sparc32/libpthread.abilist    |  1 +
 .../sysv/linux/sparc/sparc64/libpthread.abilist    |  1 +
 .../unix/sysv/linux/x86_64/64/libpthread.abilist   |  1 +
 .../unix/sysv/linux/x86_64/x32/libpthread.abilist  |  1 +
 38 files changed, 213 insertions(+), 19 deletions(-)
 create mode 100644 nptl/sem_timedwait_monotonic.c
 create mode 100644 sysdeps/htl/sem-timedwait-monotonic.c

diff --git a/ChangeLog b/ChangeLog
index 92683cb643..9386c129eb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,51 @@
+2018-12-13  Jan Klötzke  <jan@kloetzke.net>
+
+	[BZ #14717]
+	* htl/Makefile (libpthread-routines): Add sem-timedwait-monotonic.
+	* htl/Versions: Add sem_timedwait_monotonic.
+	* manual/ipc.texi: Likewise.
+	* nptl/Makefile: Likewise.
+	* nptl/Versions: Likewise.
+	* nptl/sem_timedwait.c (sem_timedwait): Add __new_sem_wait_slow
+	parameter.
+	* nptl/sem_timedwait_monotonic.c: New file.
+	* nptl/sem_wait.c: Add __new_sem_wait_slow parameter.
+	* nptl/sem_waitcommon.c (do_futex_wait): Add 'monotonic' parameter.
+	* sysdeps/htl/sem-timedwait-monotonic.c: New file.
+	* sysdeps/htl/sem-timedwait.c (__sem_timedwait_internal): Add
+	'clock_id' parameter.
+	(__sem_timedwait): Pass CLOCK_REALTIME to __sem_timedwait_internal.
+	* sysdeps/htl/sem-wait.c (__sem_wait): Likewise.
+	* sysdeps/mach/hurd/i386/libpthread.abilist: Add
+	sem_timedwait_monotonic.
+	* sysdeps/pthread/semaphore.h: Likewise.
+	* sysdeps/unix/sysv/linux/aarch64/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/alpha/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/arm/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/hppa/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/i386/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/ia64/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/microblaze/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/nios2/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist:
+	Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread-le.abilist:
+	Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libpthread.abilist:
+	Likewise.
+	* sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/sh/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist: Likewise.
+
 2018-12-12  Joseph Myers  <joseph@codesourcery.com>
 
 	* sysdeps/x86/fpu/bits/mathinline.h (hypot): Remove inline
diff --git a/htl/Makefile b/htl/Makefile
index 11c21df4d3..72125058b4 100644
--- a/htl/Makefile
+++ b/htl/Makefile
@@ -129,8 +129,8 @@ libpthread-routines := pt-attr pt-attr-destroy pt-attr-getdetachstate	    \
 	pt-yield							    \
 									    \
 	sem-close sem-destroy sem-getvalue sem-init sem-open		    \
-	sem-post sem-timedwait sem-trywait sem-unlink			    \
-	sem-wait							    \
+	sem-post sem-timedwait sem-timedwait-monotonic sem-trywait	    \
+	sem-unlink sem-wait						    \
 									    \
 	shm-directory							    \
 									    \
diff --git a/htl/Versions b/htl/Versions
index c5a616da10..a4598ba39c 100644
--- a/htl/Versions
+++ b/htl/Versions
@@ -141,6 +141,9 @@ libpthread {
     pthread_hurd_cond_wait_np;
     pthread_hurd_cond_timedwait_np;
   }
+  GLIBC_2.29 {
+    sem_timedwait_monotonic;
+  }
   GLIBC_PRIVATE {
     __shm_directory;
     __pthread_threads;
diff --git a/manual/ipc.texi b/manual/ipc.texi
index 081b98fe29..c122d436a8 100644
--- a/manual/ipc.texi
+++ b/manual/ipc.texi
@@ -100,6 +100,17 @@ by @theglibc{}.
 @c Same safety issues as sem_wait.
 @end deftypefun
 
+@deftypefun int sem_timedwait_monotonic (sem_t *@var{sem}, const struct timespec *@var{abstime});
+@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}}
+@c Same safety issues as sem_wait.
+This function is similar to @code{sem_timedwait}, but uses
+@code{CLOCK_MONOTONIC} instead of @code{CLOCK_REALTIME} for the absolute
+timeout. This makes the timeout unaffected by changes to the system real time
+clock.
+
+This function is a GNU extension.
+@end deftypefun
+
 @deftypefun int sem_trywait (sem_t *@var{sem});
 @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 @c All atomic operations are safe in all contexts.
diff --git a/nptl/Makefile b/nptl/Makefile
index 34ae830276..3c52bc0979 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -114,7 +114,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_timedwait_monotonic sem_post \
 		      cleanup cleanup_defer cleanup_compat \
 		      cleanup_defer_compat unwind \
 		      pt-longjmp pt-cleanup\
@@ -194,6 +194,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_timedwait_monotonic.c += -fexceptions -fasynchronous-unwind-tables
 
 # These are the function wrappers we have to duplicate here.
 CFLAGS-fcntl.c += -fexceptions -fasynchronous-unwind-tables
diff --git a/nptl/Versions b/nptl/Versions
index e7f691da7a..a32c1ef252 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.29 {
+    sem_timedwait_monotonic;
+  }
+
   GLIBC_PRIVATE {
     __pthread_initialize_minimal;
     __pthread_clock_gettime; __pthread_clock_settime;
diff --git a/nptl/sem_timedwait.c b/nptl/sem_timedwait.c
index 8886ea2fb3..dec6882f41 100644
--- a/nptl/sem_timedwait.c
+++ b/nptl/sem_timedwait.c
@@ -36,5 +36,5 @@ 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, abstime, 0);
 }
diff --git a/nptl/sem_timedwait_monotonic.c b/nptl/sem_timedwait_monotonic.c
new file mode 100644
index 0000000000..832b58175b
--- /dev/null
+++ b/nptl/sem_timedwait_monotonic.c
@@ -0,0 +1,40 @@
+/* sem_timedwait_monotonic -- wait on a semaphore with timeout against CLOCK_MONOTONIC.
+   Copyright (C) 2003-2018 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"
+
+/* This is in a separate file because because sem_timedwait_monotonic is only
+   provided if __USE_GNU is defined.  */
+int
+sem_timedwait_monotonic (sem_t *sem, const struct timespec *abstime)
+{
+  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  /* Check sem_wait.c for a more detailed explanation why it is required.  */
+  __pthread_testcancel ();
+
+  if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0)
+    return 0;
+  else
+    return __new_sem_wait_slow((struct new_sem *) sem, abstime, 1);
+}
+
diff --git a/nptl/sem_wait.c b/nptl/sem_wait.c
index e7d910613f..de29868fdb 100644
--- a/nptl/sem_wait.c
+++ b/nptl/sem_wait.c
@@ -39,7 +39,7 @@ __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, NULL, 0);
 }
 versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1);
 
diff --git a/nptl/sem_waitcommon.c b/nptl/sem_waitcommon.c
index 30984be2d0..7012c3fdf1 100644
--- a/nptl/sem_waitcommon.c
+++ b/nptl/sem_waitcommon.c
@@ -103,19 +103,42 @@ __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, const struct timespec *abstime, int monotonic)
 {
   int err;
+  unsigned int * futex_word;
 
 #if __HAVE_64B_ATOMICS
-  err = futex_abstimed_wait_cancelable (
-      (unsigned int *) &sem->data + SEM_VALUE_OFFSET, 0, abstime,
-      sem->private);
+  futex_word = (unsigned int *) &sem->data + SEM_VALUE_OFFSET;
 #else
-  err = futex_abstimed_wait_cancelable (&sem->value, SEM_NWAITERS_MASK,
-					abstime, sem->private);
+  futex_word = &sem->value;
 #endif
 
+  if (monotonic)
+    {
+      /* 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 (futex_word, 0, &rt, sem->private);
+    }
+  else
+    err = futex_abstimed_wait_cancelable (futex_word, 0, abstime, sem->private);
+
   return err;
 }
 
@@ -160,7 +183,7 @@ __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, const struct timespec *abstime, int monotonic)
 {
   int err = 0;
 
@@ -178,7 +201,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, abstime, monotonic);
 	  /* 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.
@@ -279,7 +302,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, abstime, monotonic);
 	      if (err == ETIMEDOUT || err == EINTR)
 		{
 		  __set_errno (err);
diff --git a/sysdeps/htl/sem-timedwait-monotonic.c b/sysdeps/htl/sem-timedwait-monotonic.c
new file mode 100644
index 0000000000..4ba370f17f
--- /dev/null
+++ b/sysdeps/htl/sem-timedwait-monotonic.c
@@ -0,0 +1,32 @@
+/* Wait on a semaphore.  Generic version.
+   Copyright (C) 2005-2018 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 <semaphore.h>
+#include <pt-internal.h>
+
+extern int __sem_timedwait_internal (sem_t *restrict sem,
+				     const struct timespec *restrict timeout,
+				     clockid_t clock_id);
+
+int
+__sem_timedwait_monotonic (sem_t *restrict sem, const struct timespec *restrict timeout)
+{
+  return __sem_timedwait_internal (sem, timeout, CLOCK_MONOTONIC);
+}
+
+strong_alias (__sem_timedwait_monotonic, sem_timedwait_monotonic);
diff --git a/sysdeps/htl/sem-timedwait.c b/sysdeps/htl/sem-timedwait.c
index 803a5c04f4..a7a057faca 100644
--- a/sysdeps/htl/sem-timedwait.c
+++ b/sysdeps/htl/sem-timedwait.c
@@ -24,7 +24,8 @@
 
 int
 __sem_timedwait_internal (sem_t *restrict sem,
-			  const struct timespec *restrict timeout)
+			  const struct timespec *restrict timeout,
+			  clockid_t clock_id)
 {
   error_t err;
   int drain;
@@ -53,7 +54,7 @@ __sem_timedwait_internal (sem_t *restrict sem,
 
   /* Block the thread.  */
   if (timeout != NULL)
-    err = __pthread_timedblock (self, timeout, CLOCK_REALTIME);
+    err = __pthread_timedblock (self, timeout, clock_id);
   else
     {
       err = 0;
@@ -92,7 +93,7 @@ __sem_timedwait_internal (sem_t *restrict sem,
 int
 __sem_timedwait (sem_t *restrict sem, const struct timespec *restrict timeout)
 {
-  return __sem_timedwait_internal (sem, timeout);
+  return __sem_timedwait_internal (sem, timeout, CLOCK_REALTIME);
 }
 
 weak_alias (__sem_timedwait, sem_timedwait);
diff --git a/sysdeps/htl/sem-wait.c b/sysdeps/htl/sem-wait.c
index 9fcd22781b..484c43dc13 100644
--- a/sysdeps/htl/sem-wait.c
+++ b/sysdeps/htl/sem-wait.c
@@ -20,12 +20,13 @@
 #include <pt-internal.h>
 
 extern int __sem_timedwait_internal (sem_t *restrict sem,
-				     const struct timespec *restrict timeout);
+				     const struct timespec *restrict timeout,
+				     clockid_t clock_id);
 
 int
 __sem_wait (sem_t *sem)
 {
-  return __sem_timedwait_internal (sem, 0);
+  return __sem_timedwait_internal (sem, 0, CLOCK_REALTIME);
 }
 
 strong_alias (__sem_wait, sem_wait);
diff --git a/sysdeps/mach/hurd/i386/libpthread.abilist b/sysdeps/mach/hurd/i386/libpthread.abilist
index 4c7d06d073..8443bdc890 100644
--- a/sysdeps/mach/hurd/i386/libpthread.abilist
+++ b/sysdeps/mach/hurd/i386/libpthread.abilist
@@ -147,3 +147,4 @@ GLIBC_2.2.6 _IO_ftrylockfile F
 GLIBC_2.2.6 _IO_funlockfile F
 GLIBC_2.21 pthread_hurd_cond_timedwait_np F
 GLIBC_2.21 pthread_hurd_cond_wait_np F
+GLIBC_2.29 sem_timedwait_monotonic F
diff --git a/sysdeps/pthread/semaphore.h b/sysdeps/pthread/semaphore.h
index ff672ebd24..66eca69d61 100644
--- a/sysdeps/pthread/semaphore.h
+++ b/sysdeps/pthread/semaphore.h
@@ -61,6 +61,12 @@ extern int sem_timedwait (sem_t *__restrict __sem,
 			  const struct timespec *__restrict __abstime);
 #endif
 
+#ifdef __USE_GNU
+/* Similar to `sem_timedwait' but uses CLOCK_MONOTONIC.  */
+extern int sem_timedwait_monotonic (sem_t *__restrict __sem,
+			  const struct timespec *__restrict __abstime);
+#endif
+
 /* Test whether SEM is posted.  */
 extern int sem_trywait (sem_t *__sem) __THROWNL;
 
diff --git a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
index 9a9e4cee85..82de41f4fc 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.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
index b413007ccb..7c30232cbf 100644
--- a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
@@ -264,3 +264,4 @@ GLIBC_2.4 pthread_mutexattr_getrobust_np F
 GLIBC_2.4 pthread_mutexattr_setprioceiling F
 GLIBC_2.4 pthread_mutexattr_setprotocol F
 GLIBC_2.4 pthread_mutexattr_setrobust_np F
+GLIBC_2.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/arm/libpthread.abilist b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
index af82a4c632..cd9d66e996 100644
--- a/sysdeps/unix/sysv/linux/arm/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libpthread.abilist
@@ -243,3 +243,4 @@ GLIBC_2.4 vfork F
 GLIBC_2.4 wait F
 GLIBC_2.4 waitpid F
 GLIBC_2.4 write F
+GLIBC_2.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
index bcba07f575..539c7438db 100644
--- a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
@@ -254,3 +254,4 @@ GLIBC_2.4 pthread_mutexattr_getrobust_np F
 GLIBC_2.4 pthread_mutexattr_setprioceiling F
 GLIBC_2.4 pthread_mutexattr_setprotocol F
 GLIBC_2.4 pthread_mutexattr_setrobust_np F
+GLIBC_2.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/i386/libpthread.abilist b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
index bece86d246..c3f9e95879 100644
--- a/sysdeps/unix/sysv/linux/i386/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
@@ -262,3 +262,4 @@ GLIBC_2.4 pthread_mutexattr_getrobust_np F
 GLIBC_2.4 pthread_mutexattr_setprioceiling F
 GLIBC_2.4 pthread_mutexattr_setprotocol F
 GLIBC_2.4 pthread_mutexattr_setrobust_np F
+GLIBC_2.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
index ccc9449826..9d6d8469da 100644
--- a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
@@ -256,3 +256,4 @@ GLIBC_2.4 pthread_mutexattr_getrobust_np F
 GLIBC_2.4 pthread_mutexattr_setprioceiling F
 GLIBC_2.4 pthread_mutexattr_setprotocol F
 GLIBC_2.4 pthread_mutexattr_setrobust_np F
+GLIBC_2.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
index af82a4c632..cd9d66e996 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
@@ -243,3 +243,4 @@ GLIBC_2.4 vfork F
 GLIBC_2.4 wait F
 GLIBC_2.4 waitpid F
 GLIBC_2.4 write F
+GLIBC_2.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
index bece86d246..c3f9e95879 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
@@ -262,3 +262,4 @@ GLIBC_2.4 pthread_mutexattr_getrobust_np F
 GLIBC_2.4 pthread_mutexattr_setprioceiling F
 GLIBC_2.4 pthread_mutexattr_setprotocol F
 GLIBC_2.4 pthread_mutexattr_setrobust_np F
+GLIBC_2.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
index 5067375d23..02f686d5e4 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.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
index 02144967c6..6d55011941 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
@@ -264,3 +264,4 @@ GLIBC_2.4 pthread_mutexattr_getrobust_np F
 GLIBC_2.4 pthread_mutexattr_setprioceiling F
 GLIBC_2.4 pthread_mutexattr_setprotocol F
 GLIBC_2.4 pthread_mutexattr_setrobust_np F
+GLIBC_2.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
index 02144967c6..6d55011941 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
@@ -264,3 +264,4 @@ GLIBC_2.4 pthread_mutexattr_getrobust_np F
 GLIBC_2.4 pthread_mutexattr_setprioceiling F
 GLIBC_2.4 pthread_mutexattr_setprotocol F
 GLIBC_2.4 pthread_mutexattr_setrobust_np F
+GLIBC_2.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/nios2/libpthread.abilist b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
index 78cac2ae27..5b9f4dc4ac 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.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
index 09e8447b06..303ba82a4a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
@@ -266,3 +266,4 @@ GLIBC_2.4 pthread_mutexattr_setprotocol F
 GLIBC_2.4 pthread_mutexattr_setrobust_np F
 GLIBC_2.6 pthread_attr_setstack F
 GLIBC_2.6 pthread_attr_setstacksize F
+GLIBC_2.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
index 8300958d47..1c29426977 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
@@ -257,3 +257,4 @@ GLIBC_2.4 pthread_mutexattr_setprotocol F
 GLIBC_2.4 pthread_mutexattr_setrobust_np F
 GLIBC_2.6 pthread_attr_setstack F
 GLIBC_2.6 pthread_attr_setstacksize F
+GLIBC_2.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
index 9a9e4cee85..82de41f4fc 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.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
index c370fda73d..57e4071753 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.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
index d05468f3b2..ac05de8918 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
@@ -264,3 +264,4 @@ GLIBC_2.4 pthread_mutexattr_getrobust_np F
 GLIBC_2.4 pthread_mutexattr_setprioceiling F
 GLIBC_2.4 pthread_mutexattr_setprotocol F
 GLIBC_2.4 pthread_mutexattr_setrobust_np F
+GLIBC_2.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
index e8161aa747..93ba9b5704 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
@@ -256,3 +256,4 @@ GLIBC_2.4 pthread_mutexattr_getrobust_np F
 GLIBC_2.4 pthread_mutexattr_setprioceiling F
 GLIBC_2.4 pthread_mutexattr_setprotocol F
 GLIBC_2.4 pthread_mutexattr_setrobust_np F
+GLIBC_2.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/sh/libpthread.abilist b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
index bcba07f575..539c7438db 100644
--- a/sysdeps/unix/sysv/linux/sh/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
@@ -254,3 +254,4 @@ GLIBC_2.4 pthread_mutexattr_getrobust_np F
 GLIBC_2.4 pthread_mutexattr_setprioceiling F
 GLIBC_2.4 pthread_mutexattr_setprotocol F
 GLIBC_2.4 pthread_mutexattr_setrobust_np F
+GLIBC_2.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
index b413007ccb..7c30232cbf 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
@@ -264,3 +264,4 @@ GLIBC_2.4 pthread_mutexattr_getrobust_np F
 GLIBC_2.4 pthread_mutexattr_setprioceiling F
 GLIBC_2.4 pthread_mutexattr_setprotocol F
 GLIBC_2.4 pthread_mutexattr_setrobust_np F
+GLIBC_2.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
index ccc9449826..9d6d8469da 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
@@ -256,3 +256,4 @@ GLIBC_2.4 pthread_mutexattr_getrobust_np F
 GLIBC_2.4 pthread_mutexattr_setprioceiling F
 GLIBC_2.4 pthread_mutexattr_setprotocol F
 GLIBC_2.4 pthread_mutexattr_setrobust_np F
+GLIBC_2.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
index 931c8277a8..a69993f4d9 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
@@ -254,3 +254,4 @@ GLIBC_2.4 pthread_mutexattr_getrobust_np F
 GLIBC_2.4 pthread_mutexattr_setprioceiling F
 GLIBC_2.4 pthread_mutexattr_setprotocol F
 GLIBC_2.4 pthread_mutexattr_setrobust_np F
+GLIBC_2.29 sem_timedwait_monotonic F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
index c09c9b015a..0af240bd36 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.29 sem_timedwait_monotonic F
-- 
2.11.0

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

* Re: [PATCH] Semaphores: add sem_timedwait_monotonic GNU extension [BZ #14717]
  2018-12-13 20:28 [PATCH] Semaphores: add sem_timedwait_monotonic GNU extension [BZ #14717] Jan Klötzke
@ 2018-12-13 22:27 ` Joseph Myers
  2018-12-14 21:04   ` Jan Klötzke
  2018-12-14 21:28   ` [PATCH v2] Semaphores: add sem_clockwait " Jan Klötzke
  0 siblings, 2 replies; 9+ messages in thread
From: Joseph Myers @ 2018-12-13 22:27 UTC (permalink / raw)
  To: Jan Klötzke; +Cc: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 1392 bytes --]

On Thu, 13 Dec 2018, Jan Klötzke wrote:

> The added sem_timedwait_monotonic() function behaves just like
> sem_timedwait() but is based on CLOCK_MONOTONIC. An identically named
> function is already provided by QNX for the same reasons.

My understanding from the Austin Group discussion was that the preferred 
approach was functions with "clock" instead of "timed" in their names, 
taking a clockid parameter (so sem_clockwait in this case).

http://austingroupbugs.net/view.php?id=1216

Note that new functions need a NEWS entry.  They also need testcases; I 
don't see any in this patch.

How has this patch been tested?  I'd have expected it to fail the ABI 
tests, because

> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> index 931c8277a8..a69993f4d9 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> @@ -254,3 +254,4 @@ GLIBC_2.4 pthread_mutexattr_getrobust_np F
>  GLIBC_2.4 pthread_mutexattr_setprioceiling F
>  GLIBC_2.4 pthread_mutexattr_setprotocol F
>  GLIBC_2.4 pthread_mutexattr_setrobust_np F
> +GLIBC_2.29 sem_timedwait_monotonic F

(for example) is not placing the new entry in its correct (LC_ALL=C) 
sorted location.

Are you covered by an FSF copyright assignment?

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [PATCH] Semaphores: add sem_timedwait_monotonic GNU extension [BZ #14717]
  2018-12-13 22:27 ` Joseph Myers
@ 2018-12-14 21:04   ` Jan Klötzke
  2018-12-14 21:12     ` Joseph Myers
  2018-12-14 21:28   ` [PATCH v2] Semaphores: add sem_clockwait " Jan Klötzke
  1 sibling, 1 reply; 9+ messages in thread
From: Jan Klötzke @ 2018-12-14 21:04 UTC (permalink / raw)
  To: Joseph Myers; +Cc: libc-alpha

On Thu, Dec 13, 2018 at 08:28:12PM +0000, Joseph Myers wrote:
> On Thu, 13 Dec 2018, Jan Klötzke wrote:
> 
> > The added sem_timedwait_monotonic() function behaves just like
> > sem_timedwait() but is based on CLOCK_MONOTONIC. An identically named
> > function is already provided by QNX for the same reasons.
> 
> My understanding from the Austin Group discussion was that the preferred 
> approach was functions with "clock" instead of "timed" in their names, 
> taking a clockid parameter (so sem_clockwait in this case).
> 
> http://austingroupbugs.net/view.php?id=1216

Oh, I wasn't aware of this proposal. Looks reasonable and even more
generic. I will send a v2 accordingly. I'm not sure if I find the time
to implement the other proposed functions but it looks worth it.

> Note that new functions need a NEWS entry.  They also need testcases; I 
> don't see any in this patch.

Will fix that with v2 too.

> How has this patch been tested?  I'd have expected it to fail the ABI 
> tests, because
> 
> > diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> > index 931c8277a8..a69993f4d9 100644
> > --- a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> > +++ b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
> > @@ -254,3 +254,4 @@ GLIBC_2.4 pthread_mutexattr_getrobust_np F
> >  GLIBC_2.4 pthread_mutexattr_setprioceiling F
> >  GLIBC_2.4 pthread_mutexattr_setprotocol F
> >  GLIBC_2.4 pthread_mutexattr_setrobust_np F
> > +GLIBC_2.29 sem_timedwait_monotonic F
> 
> (for example) is not placing the new entry in its correct (LC_ALL=C) 
> sorted location.

The cold and harsh truth is that I forgot to execute the tests. My bad.
I only tested it by running some manual tests with the new version.

> Are you covered by an FSF copyright assignment?

Not yet. Quite frankly I'm a bit lost what needs to be done exactly to
pass the legal part.

Regards,
Jan

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

* Re: [PATCH] Semaphores: add sem_timedwait_monotonic GNU extension [BZ #14717]
  2018-12-14 21:04   ` Jan Klötzke
@ 2018-12-14 21:12     ` Joseph Myers
  2018-12-14 21:39       ` Carlos O'Donell
  0 siblings, 1 reply; 9+ messages in thread
From: Joseph Myers @ 2018-12-14 21:12 UTC (permalink / raw)
  To: Jan Klötzke; +Cc: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 325 bytes --]

On Fri, 14 Dec 2018, Jan Klötzke wrote:

> > Are you covered by an FSF copyright assignment?
> 
> Not yet. Quite frankly I'm a bit lost what needs to be done exactly to
> pass the legal part.

https://git.savannah.gnu.org/cgit/gnulib.git/plain/doc/Copyright/request-assign.future

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* [PATCH v2] Semaphores: add sem_clockwait GNU extension [BZ #14717]
  2018-12-13 22:27 ` Joseph Myers
  2018-12-14 21:04   ` Jan Klötzke
@ 2018-12-14 21:28   ` Jan Klötzke
  2018-12-17  6:38     ` Ben Hutchings
  1 sibling, 1 reply; 9+ messages in thread
From: Jan Klötzke @ 2018-12-14 21:28 UTC (permalink / raw)
  To: libc-alpha

As defined by POSIX.1-2001 the 'abstime' timeout of  sem_timedwait()
shall be based on CLOCK_REALTIME. This has the unpleasant effect that
application timeouts are affected by system clock adjustments.

The added sem_clockwait() function behaves just like sem_timedwait() but
lets the user specify the clock against which the timeout is measured.
The implementation is based on [1] which covers all functions that take an
absolute struct timespec timeout.

[1] http://austingroupbugs.net/view.php?id=1216

Signed-off-by: Jan Klötzke <jan@kloetzke.net>
---
v2: Reimplement as sem_clockwait.

 One minor issue exists with this implementation: semaphore.h does not expose
 the CLOCK_* constants. It is the users resposibility to include time.h for
 their definition. AFAICT POSIX.1-2008 would allow semaphore.h to include
 time.h but I'm reluctant to do that unconditionally.

 ChangeLog                                          |  50 +++++++++
 NEWS                                               |   5 +
 htl/Makefile                                       |   2 +-
 htl/Versions                                       |   3 +
 manual/ipc.texi                                    |  13 +++
 nptl/Makefile                                      |   5 +-
 nptl/Versions                                      |   4 +
 nptl/sem_clockwait.c                               |  52 +++++++++
 nptl/sem_timedwait.c                               |   2 +-
 nptl/sem_wait.c                                    |   2 +-
 nptl/sem_waitcommon.c                              |  41 +++++--
 nptl/tst-sem17.c                                   | 119 +++++++++++++++++++++
 sysdeps/htl/sem-clockwait.c                        |  40 +++++++
 sysdeps/htl/sem-timedwait.c                        |   7 +-
 sysdeps/htl/sem-wait.c                             |   5 +-
 sysdeps/mach/hurd/i386/libpthread.abilist          |   1 +
 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/hppa/libpthread.abilist    |   1 +
 sysdeps/unix/sysv/linux/i386/libpthread.abilist    |   1 +
 sysdeps/unix/sysv/linux/ia64/libpthread.abilist    |   1 +
 .../sysv/linux/m68k/coldfire/libpthread.abilist    |   1 +
 .../unix/sysv/linux/m68k/m680x0/libpthread.abilist |   1 +
 .../unix/sysv/linux/microblaze/libpthread.abilist  |   1 +
 .../unix/sysv/linux/mips/mips32/libpthread.abilist |   1 +
 .../unix/sysv/linux/mips/mips64/libpthread.abilist |   1 +
 sysdeps/unix/sysv/linux/nios2/libpthread.abilist   |   1 +
 .../linux/powerpc/powerpc32/libpthread.abilist     |   1 +
 .../linux/powerpc/powerpc64/be/libpthread.abilist  |   1 +
 .../linux/powerpc/powerpc64/le/libpthread.abilist  |   1 +
 .../unix/sysv/linux/riscv/rv64/libpthread.abilist  |   1 +
 .../sysv/linux/s390/s390-32/libpthread.abilist     |   1 +
 .../sysv/linux/s390/s390-64/libpthread.abilist     |   1 +
 sysdeps/unix/sysv/linux/sh/libpthread.abilist      |   1 +
 .../sysv/linux/sparc/sparc32/libpthread.abilist    |   1 +
 .../sysv/linux/sparc/sparc64/libpthread.abilist    |   1 +
 .../unix/sysv/linux/x86_64/64/libpthread.abilist   |   1 +
 .../unix/sysv/linux/x86_64/x32/libpthread.abilist  |   1 +
 40 files changed, 362 insertions(+), 19 deletions(-)
 create mode 100644 nptl/sem_clockwait.c
 create mode 100644 nptl/tst-sem17.c
 create mode 100644 sysdeps/htl/sem-clockwait.c

diff --git a/ChangeLog b/ChangeLog
index e419448fe6..69f2a36674 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,53 @@
+2018-12-14  Jan Klötzke  <jan@kloetzke.net>
+
+	[BZ #14717]
+	* NEWS: Mention sem_clockwait.
+	* htl/Makefile (libpthread-routines): Add sem-clockwait.
+	* htl/Versions: Add sem_clockwait.
+	* manual/ipc.texi: Likewise.
+	* nptl/Makefile (libpthread-routines): Add sem_clockwait.
+	(tests): Add tst-sem17.
+	* nptl/Versions: Add sem_clockwait.
+	* nptl/sem_clockwait.c: New file.
+	* nptl/sem_timedwait.c (sem_timedwait): Add __new_sem_wait_slow
+	parameter.
+	* nptl/sem_wait.c: Add __new_sem_wait_slow parameter.
+	* nptl/sem_waitcommon.c (do_futex_wait): Add 'monotonic' parameter.
+	* nptl/tst-sem17.c: New file.
+	* sysdeps/htl/sem-clockwait.c: New file.
+	* sysdeps/htl/sem-timedwait.c (__sem_timedwait_internal): Add
+	'clock_id' parameter.
+	(__sem_timedwait): Pass CLOCK_REALTIME to __sem_timedwait_internal.
+	* sysdeps/htl/sem-wait.c (__sem_wait): Likewise.
+	* sysdeps/mach/hurd/i386/libpthread.abilist: Add sem_clockwait.
+	* sysdeps/pthread/semaphore.h: Likewise.
+	* sysdeps/unix/sysv/linux/aarch64/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/alpha/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/arm/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/hppa/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/i386/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/ia64/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/microblaze/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/nios2/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist:
+	Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist:
+	Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist:
+	Likewise.
+	* sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/sh/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist: Likewise.
+
 2018-12-13  Joseph Myers  <joseph@codesourcery.com>
 
 	* sysdeps/mach/hurd/i386/init-first.c (_hurd_stack_setup): Do not
diff --git a/NEWS b/NEWS
index ae80818df4..1d8c78cf57 100644
--- a/NEWS
+++ b/NEWS
@@ -46,6 +46,11 @@ Major new features:
   incosistent mutex state after fork call in multithread environment.
   In both popen and system there is no direct access to user-defined mutexes.
 
+* The sem_clockwait function has been added. It complements sem_timedwait by
+  allowing to select the clock against which the absolute timeout is measured.
+  Using CLOCK_MONOTONIC enables an application to wait without being affected
+  by system clock adjustments.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
 * The glibc.tune tunable namespace has been renamed to glibc.cpu and the
diff --git a/htl/Makefile b/htl/Makefile
index 11c21df4d3..cebf3cca0e 100644
--- a/htl/Makefile
+++ b/htl/Makefile
@@ -128,7 +128,7 @@ libpthread-routines := pt-attr pt-attr-destroy pt-attr-getdetachstate	    \
 	pt-getschedparam pt-setschedparam pt-setschedprio		    \
 	pt-yield							    \
 									    \
-	sem-close sem-destroy sem-getvalue sem-init sem-open		    \
+	sem-clockwait sem-close sem-destroy sem-getvalue sem-init sem-open  \
 	sem-post sem-timedwait sem-trywait sem-unlink			    \
 	sem-wait							    \
 									    \
diff --git a/htl/Versions b/htl/Versions
index c5a616da10..39aced3245 100644
--- a/htl/Versions
+++ b/htl/Versions
@@ -141,6 +141,9 @@ libpthread {
     pthread_hurd_cond_wait_np;
     pthread_hurd_cond_timedwait_np;
   }
+  GLIBC_2.29 {
+    sem_clockwait;
+  }
   GLIBC_PRIVATE {
     __shm_directory;
     __pthread_threads;
diff --git a/manual/ipc.texi b/manual/ipc.texi
index 081b98fe29..05e2e216bd 100644
--- a/manual/ipc.texi
+++ b/manual/ipc.texi
@@ -100,6 +100,19 @@ by @theglibc{}.
 @c Same safety issues as sem_wait.
 @end deftypefun
 
+@deftypefun int sem_clockwait (sem_t *@var{sem}, clockid_t @var{clock_id}, const struct timespec *@var{abstime});
+@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}}
+@c Same safety issues as sem_wait.
+This function is similar to @code{sem_timedwait}, but allows the calling thread
+to select the clock against which the absolute timeout is measured. Currently
+@code{CLOCK_MONOTONIC} and @code{CLOCK_REALTIME} are supported. Invoking this
+function with @code{CLOCK_REALTIME} has the identical behaviour as
+@code{sem_timedwait}. By using @code{CLOCK_MONOTONIC} the timeout will be
+unaffected by changes to the system real time clock.
+
+This function is a GNU extension.
+@end deftypefun
+
 @deftypefun int sem_trywait (sem_t *@var{sem});
 @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 @c All atomic operations are safe in all contexts.
diff --git a/nptl/Makefile b/nptl/Makefile
index b01f2b0626..76f850d780 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -114,7 +114,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_clockwait sem_timedwait 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 \
 			-fasynchronous-unwind-tables
 CFLAGS-pthread_cond_wait.c += -fexceptions -fasynchronous-unwind-tables
 CFLAGS-sem_wait.c += -fexceptions -fasynchronous-unwind-tables
+CFLAGS-sem_clockwait.c += -fexceptions -fasynchronous-unwind-tables
 CFLAGS-sem_timedwait.c += -fexceptions -fasynchronous-unwind-tables
 
 # These are the function wrappers we have to duplicate here.
@@ -263,7 +264,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 e7f691da7a..4d4a79da55 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.29 {
+    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 0000000000..f0d9487c82
--- /dev/null
+++ b/nptl/sem_clockwait.c
@@ -0,0 +1,52 @@
+/* sem_clockwait -- wait on a semaphore with timeout against specific clock.
+   Copyright (C) 2003-2018 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"
+
+/* This is in a separate file because because sem_clockwait is only
+   provided if __USE_GNU is defined.  */
+int
+sem_clockwait (sem_t *sem, clockid_t clock_id, const struct timespec *abstime)
+{
+  if (__glibc_unlikely (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000))
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  if (__glibc_unlikely (clock_id != CLOCK_MONOTONIC
+			&& clock_id != CLOCK_REALTIME))
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  /* If we do not support waiting using CLOCK_MONOTONIC, return an error.  */
+  if (clock_id == CLOCK_MONOTONIC
+      && !futex_supports_exact_relative_timeouts())
+    return ENOTSUP;
+
+  /* Check sem_wait.c for a more detailed explanation why it is required.  */
+  __pthread_testcancel ();
+
+  if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0)
+    return 0;
+  else
+    return __new_sem_wait_slow((struct new_sem *) sem, abstime,
+			       clock_id == CLOCK_MONOTONIC);
+}
diff --git a/nptl/sem_timedwait.c b/nptl/sem_timedwait.c
index 8886ea2fb3..dec6882f41 100644
--- a/nptl/sem_timedwait.c
+++ b/nptl/sem_timedwait.c
@@ -36,5 +36,5 @@ 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, abstime, 0);
 }
diff --git a/nptl/sem_wait.c b/nptl/sem_wait.c
index e7d910613f..de29868fdb 100644
--- a/nptl/sem_wait.c
+++ b/nptl/sem_wait.c
@@ -39,7 +39,7 @@ __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, NULL, 0);
 }
 versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1);
 
diff --git a/nptl/sem_waitcommon.c b/nptl/sem_waitcommon.c
index 30984be2d0..7012c3fdf1 100644
--- a/nptl/sem_waitcommon.c
+++ b/nptl/sem_waitcommon.c
@@ -103,19 +103,42 @@ __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, const struct timespec *abstime, int monotonic)
 {
   int err;
+  unsigned int * futex_word;
 
 #if __HAVE_64B_ATOMICS
-  err = futex_abstimed_wait_cancelable (
-      (unsigned int *) &sem->data + SEM_VALUE_OFFSET, 0, abstime,
-      sem->private);
+  futex_word = (unsigned int *) &sem->data + SEM_VALUE_OFFSET;
 #else
-  err = futex_abstimed_wait_cancelable (&sem->value, SEM_NWAITERS_MASK,
-					abstime, sem->private);
+  futex_word = &sem->value;
 #endif
 
+  if (monotonic)
+    {
+      /* 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 (futex_word, 0, &rt, sem->private);
+    }
+  else
+    err = futex_abstimed_wait_cancelable (futex_word, 0, abstime, sem->private);
+
   return err;
 }
 
@@ -160,7 +183,7 @@ __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, const struct timespec *abstime, int monotonic)
 {
   int err = 0;
 
@@ -178,7 +201,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, abstime, monotonic);
 	  /* 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.
@@ -279,7 +302,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, abstime, monotonic);
 	      if (err == ETIMEDOUT || err == EINTR)
 		{
 		  __set_errno (err);
diff --git a/nptl/tst-sem17.c b/nptl/tst-sem17.c
new file mode 100644
index 0000000000..12561b8911
--- /dev/null
+++ b/nptl/tst-sem17.c
@@ -0,0 +1,119 @@
+/* Copyright (C) 2018 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 <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#define EXPECT_OK(exp)							    \
+  do {									    \
+    int ret = (exp);							    \
+    if (ret < 0)							    \
+      {									    \
+	printf ("%s:%d: call failed: %s\n", __FILE__, __LINE__,		    \
+		strerror(errno));					    \
+	return 1;							    \
+      }									    \
+  } while (0)
+
+#define SEM_CLOCKWAIT_EXPECT_FAIL(err, clk)				    \
+  do {									    \
+    errno = 0;								    \
+    if (sem_clockwait (&s, (clk), &ts) >= 0)				    \
+      {									    \
+	printf ("%s:%d: sem_clockwait did not fail\n", __FILE__, __LINE__); \
+	return 1;							    \
+      }									    \
+    if (errno != (err))							    \
+      {									    \
+	printf("%s:%d: sem_clockwait did not fail with %d but %d\n",	    \
+	       __FILE__, __LINE__, (err), errno);			    \
+	return 1;							    \
+      }									    \
+  } while (0)
+
+static int
+do_test (void)
+{
+  sem_t s;
+  int val;
+
+  if (sem_init (&s, 0, 2) != 0)
+    {
+      puts ("sem_init failed");
+      return 1;
+    }
+
+  struct timespec ts = { 0, 0 };
+
+  /* CLOCK_REALTIME accepted */
+  EXPECT_OK(sem_clockwait(&s, CLOCK_REALTIME, &ts));
+
+  /* CLOCK_MONOTONIC accepted */
+  EXPECT_OK(sem_clockwait(&s, CLOCK_MONOTONIC, &ts));
+
+  /* invalid clock fails */
+  SEM_CLOCKWAIT_EXPECT_FAIL(EINVAL, 42);
+
+  /* semaphore value ought to be zero by now */
+  EXPECT_OK(sem_getvalue(&s, &val));
+  if (val != 0)
+    {
+      puts("semphore value not zero");
+      return 1;
+    }
+
+  /* invalid tv_nsec */
+  ts.tv_nsec = 1000000001;
+  SEM_CLOCKWAIT_EXPECT_FAIL(EINVAL, CLOCK_MONOTONIC);
+  ts.tv_nsec = -1;
+  SEM_CLOCKWAIT_EXPECT_FAIL(EINVAL, CLOCK_MONOTONIC);
+
+  /* ancient tv_sec */
+  ts.tv_sec = -2;
+  ts.tv_nsec = 0;
+  SEM_CLOCKWAIT_EXPECT_FAIL(ETIMEDOUT, CLOCK_MONOTONIC);
+
+  /* wait 100ms with CLOCK_MONOTONIC */
+  EXPECT_OK(clock_gettime(CLOCK_MONOTONIC, &ts));
+  ts.tv_nsec += 100000000;
+  if (ts.tv_nsec >= 1000000000)
+    {
+      ++ts.tv_sec;
+      ts.tv_nsec -= 1000000000;
+    }
+
+  SEM_CLOCKWAIT_EXPECT_FAIL(ETIMEDOUT, CLOCK_MONOTONIC);
+
+  struct timespec ts2;
+  EXPECT_OK(clock_gettime(CLOCK_MONOTONIC, &ts2));
+
+  if (ts2.tv_sec < ts.tv_sec
+      || (ts2.tv_sec == ts.tv_sec && ts2.tv_nsec < ts.tv_nsec))
+    {
+      puts ("timeout too short");
+      return 1;
+    }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/sysdeps/htl/sem-clockwait.c b/sysdeps/htl/sem-clockwait.c
new file mode 100644
index 0000000000..68eae9a5ab
--- /dev/null
+++ b/sysdeps/htl/sem-clockwait.c
@@ -0,0 +1,40 @@
+/* Wait on a semaphore with timeout on certain clock.  Generic version.
+   Copyright (C) 2005-2018 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 <semaphore.h>
+#include <pt-internal.h>
+
+extern int __sem_timedwait_internal (sem_t *restrict sem,
+				     const struct timespec *restrict timeout,
+				     clockid_t clock_id);
+
+int
+__sem_clockwait (sem_t *restrict sem, clockid_t clock_id,
+		 const struct timespec *restrict timeout)
+{
+  if (__glibc_unlikely (clock_id != CLOCK_MONOTONIC
+			&& clock_id != CLOCK_REALTIME))
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  return __sem_timedwait_internal (sem, timeout, clock_id);
+}
+
+strong_alias (__sem_clockwait, sem_clockwait);
diff --git a/sysdeps/htl/sem-timedwait.c b/sysdeps/htl/sem-timedwait.c
index 803a5c04f4..a7a057faca 100644
--- a/sysdeps/htl/sem-timedwait.c
+++ b/sysdeps/htl/sem-timedwait.c
@@ -24,7 +24,8 @@
 
 int
 __sem_timedwait_internal (sem_t *restrict sem,
-			  const struct timespec *restrict timeout)
+			  const struct timespec *restrict timeout,
+			  clockid_t clock_id)
 {
   error_t err;
   int drain;
@@ -53,7 +54,7 @@ __sem_timedwait_internal (sem_t *restrict sem,
 
   /* Block the thread.  */
   if (timeout != NULL)
-    err = __pthread_timedblock (self, timeout, CLOCK_REALTIME);
+    err = __pthread_timedblock (self, timeout, clock_id);
   else
     {
       err = 0;
@@ -92,7 +93,7 @@ __sem_timedwait_internal (sem_t *restrict sem,
 int
 __sem_timedwait (sem_t *restrict sem, const struct timespec *restrict timeout)
 {
-  return __sem_timedwait_internal (sem, timeout);
+  return __sem_timedwait_internal (sem, timeout, CLOCK_REALTIME);
 }
 
 weak_alias (__sem_timedwait, sem_timedwait);
diff --git a/sysdeps/htl/sem-wait.c b/sysdeps/htl/sem-wait.c
index 9fcd22781b..484c43dc13 100644
--- a/sysdeps/htl/sem-wait.c
+++ b/sysdeps/htl/sem-wait.c
@@ -20,12 +20,13 @@
 #include <pt-internal.h>
 
 extern int __sem_timedwait_internal (sem_t *restrict sem,
-				     const struct timespec *restrict timeout);
+				     const struct timespec *restrict timeout,
+				     clockid_t clock_id);
 
 int
 __sem_wait (sem_t *sem)
 {
-  return __sem_timedwait_internal (sem, 0);
+  return __sem_timedwait_internal (sem, 0, CLOCK_REALTIME);
 }
 
 strong_alias (__sem_wait, sem_wait);
diff --git a/sysdeps/mach/hurd/i386/libpthread.abilist b/sysdeps/mach/hurd/i386/libpthread.abilist
index 4c7d06d073..6085a7ff9c 100644
--- a/sysdeps/mach/hurd/i386/libpthread.abilist
+++ b/sysdeps/mach/hurd/i386/libpthread.abilist
@@ -147,3 +147,4 @@ GLIBC_2.2.6 _IO_ftrylockfile F
 GLIBC_2.2.6 _IO_funlockfile F
 GLIBC_2.21 pthread_hurd_cond_timedwait_np F
 GLIBC_2.21 pthread_hurd_cond_wait_np F
+GLIBC_2.29 sem_clockwait F
diff --git a/sysdeps/pthread/semaphore.h b/sysdeps/pthread/semaphore.h
index ff672ebd24..94417d7d95 100644
--- a/sysdeps/pthread/semaphore.h
+++ b/sysdeps/pthread/semaphore.h
@@ -61,6 +61,13 @@ extern int sem_timedwait (sem_t *__restrict __sem,
 			  const struct timespec *__restrict __abstime);
 #endif
 
+#ifdef __USE_GNU
+/* Similar to `sem_timedwait' but with configurable clock.  */
+extern int sem_clockwait (sem_t *__restrict __sem,
+			  clockid_t __clock_id,
+			  const struct timespec *__restrict __abstime);
+#endif
+
 /* Test whether SEM is posted.  */
 extern int sem_trywait (sem_t *__sem) __THROWNL;
 
diff --git a/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist b/sysdeps/unix/sysv/linux/aarch64/libpthread.abilist
index 9a9e4cee85..1f6e81e572 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.29 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/alpha/libpthread.abilist b/sysdeps/unix/sysv/linux/alpha/libpthread.abilist
index b413007ccb..ff915631b6 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.29 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 af82a4c632..c15acc206c 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.29 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/hppa/libpthread.abilist b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
index bcba07f575..c11b16802f 100644
--- a/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libpthread.abilist
@@ -219,6 +219,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.29 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/i386/libpthread.abilist b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
index bece86d246..3adc3fd963 100644
--- a/sysdeps/unix/sysv/linux/i386/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/i386/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.29 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/ia64/libpthread.abilist b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
index ccc9449826..57d1fe0206 100644
--- a/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libpthread.abilist
@@ -219,6 +219,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.29 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/m68k/coldfire/libpthread.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
index af82a4c632..c15acc206c 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.29 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 bece86d246..3adc3fd963 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/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.29 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/microblaze/libpthread.abilist b/sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
index 5067375d23..60d75df085 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.29 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
index 02144967c6..1c26f72767 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/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.29 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/mips/mips64/libpthread.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
index 02144967c6..1c26f72767 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/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.29 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/nios2/libpthread.abilist b/sysdeps/unix/sysv/linux/nios2/libpthread.abilist
index 78cac2ae27..5ded824c40 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.29 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
index 09e8447b06..e65bfd94f3 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/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.29 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/powerpc/powerpc64/be/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
index 8300958d47..5ac044fad7 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/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.29 sem_clockwait F
 GLIBC_2.3 _IO_flockfile F
 GLIBC_2.3 _IO_ftrylockfile F
 GLIBC_2.3 _IO_funlockfile F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
index 9a9e4cee85..1f6e81e572 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.29 sem_clockwait F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
index c370fda73d..077574fea6 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.29 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 d05468f3b2..919ae6dc42 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
@@ -229,6 +229,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.29 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/s390/s390-64/libpthread.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
index e8161aa747..4178c015cf 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
@@ -221,6 +221,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.29 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/sh/libpthread.abilist b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
index bcba07f575..c11b16802f 100644
--- a/sysdeps/unix/sysv/linux/sh/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libpthread.abilist
@@ -219,6 +219,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.29 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/sparc/sparc32/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
index b413007ccb..ff915631b6 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/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.29 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/sparc/sparc64/libpthread.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
index ccc9449826..57d1fe0206 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
@@ -219,6 +219,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.29 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/x86_64/64/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
index 931c8277a8..b7f0ee5045 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
@@ -219,6 +219,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.29 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/x86_64/x32/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
index c09c9b015a..356412e100 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.29 sem_clockwait F
-- 
2.11.0

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

* Re: [PATCH] Semaphores: add sem_timedwait_monotonic GNU extension [BZ #14717]
  2018-12-14 21:12     ` Joseph Myers
@ 2018-12-14 21:39       ` Carlos O'Donell
  2018-12-14 21:56         ` Jan Klötzke
  0 siblings, 1 reply; 9+ messages in thread
From: Carlos O'Donell @ 2018-12-14 21:39 UTC (permalink / raw)
  To: Joseph Myers, Jan Klötzke; +Cc: libc-alpha

On 12/14/18 4:11 PM, Joseph Myers wrote:
> On Fri, 14 Dec 2018, Jan Klötzke wrote:
> 
>>> Are you covered by an FSF copyright assignment?
>>
>> Not yet. Quite frankly I'm a bit lost what needs to be done exactly to
>> pass the legal part.
> 
> https://git.savannah.gnu.org/cgit/gnulib.git/plain/doc/Copyright/request-assign.future
> 

You follow those instructions, and the FSF will kick off the process.

Please feel free to reach out to me if you have any issues or questions.

Thank you again for contributing to the project.

-- 
Cheers,
Carlos.

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

* Re: [PATCH] Semaphores: add sem_timedwait_monotonic GNU extension [BZ #14717]
  2018-12-14 21:39       ` Carlos O'Donell
@ 2018-12-14 21:56         ` Jan Klötzke
  0 siblings, 0 replies; 9+ messages in thread
From: Jan Klötzke @ 2018-12-14 21:56 UTC (permalink / raw)
  To: Carlos O'Donell; +Cc: Joseph Myers, libc-alpha

On Fri, Dec 14, 2018 at 04:28:11PM -0500, Carlos O'Donell wrote:
> On 12/14/18 4:11 PM, Joseph Myers wrote:
> > On Fri, 14 Dec 2018, Jan Klötzke wrote:
> > 
> >>> Are you covered by an FSF copyright assignment?
> >>
> >> Not yet. Quite frankly I'm a bit lost what needs to be done exactly to
> >> pass the legal part.
> > 
> > https://git.savannah.gnu.org/cgit/gnulib.git/plain/doc/Copyright/request-assign.future
> > 
> 
> You follow those instructions, and the FSF will kick off the process.
> 
> Please feel free to reach out to me if you have any issues or questions.
> 
> Thank you again for contributing to the project.

Thanks - much appreciated. E-mail is already out. I'll come back once
the legal process is finshed...

Regards,
Jan

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

* Re: [PATCH v2] Semaphores: add sem_clockwait GNU extension [BZ #14717]
  2018-12-14 21:28   ` [PATCH v2] Semaphores: add sem_clockwait " Jan Klötzke
@ 2018-12-17  6:38     ` Ben Hutchings
  2018-12-21 17:43       ` Jan Klötzke
  0 siblings, 1 reply; 9+ messages in thread
From: Ben Hutchings @ 2018-12-17  6:38 UTC (permalink / raw)
  To: Jan Klötzke, libc-alpha

On Fri, 2018-12-14 at 22:20 +0100, Jan Klötzke wrote:
> As defined by POSIX.1-2001 the 'abstime' timeout of  sem_timedwait()
> shall be based on CLOCK_REALTIME. This has the unpleasant effect that
> application timeouts are affected by system clock adjustments.
> 
> The added sem_clockwait() function behaves just like sem_timedwait() but
> lets the user specify the clock against which the timeout is measured.
> The implementation is based on [1] which covers all functions that take an
> absolute struct timespec timeout.
[...]
> --- /dev/null
> +++ b/nptl/sem_clockwait.c
> @@ -0,0 +1,52 @@
[...]
> +int
> +sem_clockwait (sem_t *sem, clockid_t clock_id, const struct timespec *abstime)
> +{
> +  if (__glibc_unlikely (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000))
> +    {
> +      __set_errno (EINVAL);
> +      return -1;
> +    }
> +
> +  if (__glibc_unlikely (clock_id != CLOCK_MONOTONIC
> +                       && clock_id != CLOCK_REALTIME))
> +    {
> +      __set_errno (EINVAL);
> +      return -1;
> +    }
> +
> +  /* If we do not support waiting using CLOCK_MONOTONIC, return an error.  */
> +  if (clock_id == CLOCK_MONOTONIC
> +      && !futex_supports_exact_relative_timeouts())
> +    return ENOTSUP;
[...]

Returning an error code here is inconsistent with sem_timedwait() (and
even with the other error cases).

Ben.

-- 
Ben Hutchings, Software Developer                         Codethink Ltd
https://www.codethink.co.uk/                 Dale House, 35 Dale Street
                                     Manchester, M1 2HF, United Kingdom

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

* Re: [PATCH v2] Semaphores: add sem_clockwait GNU extension [BZ #14717]
  2018-12-17  6:38     ` Ben Hutchings
@ 2018-12-21 17:43       ` Jan Klötzke
  0 siblings, 0 replies; 9+ messages in thread
From: Jan Klötzke @ 2018-12-21 17:43 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: libc-alpha

On Mon, Dec 17, 2018 at 12:15:31AM +0000, Ben Hutchings wrote:
> On Fri, 2018-12-14 at 22:20 +0100, Jan Klötzke wrote:
> > As defined by POSIX.1-2001 the 'abstime' timeout of  sem_timedwait()
> > shall be based on CLOCK_REALTIME. This has the unpleasant effect that
> > application timeouts are affected by system clock adjustments.
> > 
> > The added sem_clockwait() function behaves just like sem_timedwait() but
> > lets the user specify the clock against which the timeout is measured.
> > The implementation is based on [1] which covers all functions that take an
> > absolute struct timespec timeout.
> [...]
> > --- /dev/null
> > +++ b/nptl/sem_clockwait.c
> > @@ -0,0 +1,52 @@
> [...]
> > +int
> > +sem_clockwait (sem_t *sem, clockid_t clock_id, const struct timespec *abstime)
> > +{
> > +  if (__glibc_unlikely (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000))
> > +    {
> > +      __set_errno (EINVAL);
> > +      return -1;
> > +    }
> > +
> > +  if (__glibc_unlikely (clock_id != CLOCK_MONOTONIC
> > +                       && clock_id != CLOCK_REALTIME))
> > +    {
> > +      __set_errno (EINVAL);
> > +      return -1;
> > +    }
> > +
> > +  /* If we do not support waiting using CLOCK_MONOTONIC, return an error.  */
> > +  if (clock_id == CLOCK_MONOTONIC
> > +      && !futex_supports_exact_relative_timeouts())
> > +    return ENOTSUP;
> [...]
> 
> Returning an error code here is inconsistent with sem_timedwait() (and
> even with the other error cases).

Good catch. Will be fixed in v3.

The error values are also not in line with the proposal in [1] yet. I
will change the nptl/htl implementations to consistently set errno to
ENOTSUP if a particular clock is not supported.

I'll post it when the CLA is signed. Looks like my employer needs some
more time than anticipated... :/

Jan

[1] http://austingroupbugs.net/view.php?id=1216

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

end of thread, other threads:[~2018-12-21 17:01 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-13 20:28 [PATCH] Semaphores: add sem_timedwait_monotonic GNU extension [BZ #14717] Jan Klötzke
2018-12-13 22:27 ` Joseph Myers
2018-12-14 21:04   ` Jan Klötzke
2018-12-14 21:12     ` Joseph Myers
2018-12-14 21:39       ` Carlos O'Donell
2018-12-14 21:56         ` Jan Klötzke
2018-12-14 21:28   ` [PATCH v2] Semaphores: add sem_clockwait " Jan Klötzke
2018-12-17  6:38     ` Ben Hutchings
2018-12-21 17:43       ` Jan Klötzke

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).