about summary refs log tree commit diff
path: root/nptl/sem_waitcommon.c
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/sem_waitcommon.c')
-rw-r--r--nptl/sem_waitcommon.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/nptl/sem_waitcommon.c b/nptl/sem_waitcommon.c
index 311e511195..772425d33e 100644
--- a/nptl/sem_waitcommon.c
+++ b/nptl/sem_waitcommon.c
@@ -17,6 +17,7 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <kernel-features.h>
 #include <errno.h>
 #include <sysdep.h>
 #include <lowlevellock.h>
@@ -45,6 +46,13 @@ futex_abstimed_wait (unsigned int* futex, unsigned int expected,
     }
   else
     {
+#if (defined __ASSUME_FUTEX_CLOCK_REALTIME	\
+     && defined lll_futex_timed_wait_bitset)
+      /* The Linux kernel returns EINVAL for this, but in userspace
+	 such a value is valid.  */
+      if (abstime->tv_sec < 0)
+	return ETIMEDOUT;
+#else
       struct timeval tv;
       struct timespec rt;
       int sec, nsec;
@@ -68,9 +76,16 @@ futex_abstimed_wait (unsigned int* futex, unsigned int expected,
       /* Do wait.  */
       rt.tv_sec = sec;
       rt.tv_nsec = nsec;
+#endif
       if (cancel)
 	oldtype = __pthread_enable_asynccancel ();
+#if (defined __ASSUME_FUTEX_CLOCK_REALTIME	\
+     && defined lll_futex_timed_wait_bitset)
+      err = lll_futex_timed_wait_bitset (futex, expected, abstime,
+					 FUTEX_CLOCK_REALTIME, private);
+#else
       err = lll_futex_timed_wait (futex, expected, &rt, private);
+#endif
       if (cancel)
 	__pthread_disable_asynccancel (oldtype);
     }