about summary refs log tree commit diff
path: root/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddhesh@redhat.com>2012-11-05 21:12:10 +0530
committerSiddhesh Poyarekar <siddhesh@redhat.com>2012-11-05 21:12:52 +0530
commit8f861542dd0603bef99e126e509ece89514c1eeb (patch)
tree083f3bd20edfa09a2341e0340013c0781b4696ad /nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
parent155ee340b875834693fbd1b7401af7fe88ace04d (diff)
downloadglibc-8f861542dd0603bef99e126e509ece89514c1eeb.tar.gz
glibc-8f861542dd0603bef99e126e509ece89514c1eeb.tar.xz
glibc-8f861542dd0603bef99e126e509ece89514c1eeb.zip
[S390,PPC] Implement FUTEX_WAIT_BITSET for timedwait functions
Since the FUTEX_WAIT operation takes a relative timeout, the
pthread_cond_timedwait and other timed function implementations have
to get a relative timeout from the absolute timeout parameter it gets
before it makes the futex syscall.  This value is then converted back
into an absolute timeout within the kernel.  This is a waste and has
hence been improved upon by a FUTEX_WAIT_BITSET operation (OR'd with
FUTEX_CLOCK_REALTIME to make the kernel use the realtime clock instead
of the default monotonic clock).  This was implemented only in the x86
and sh assembly code and not in the C code.  This patch implements
support for FUTEX_WAIT_BITSET whenever available (since linux-2.6.29)
for s390 and powerpc.
Diffstat (limited to 'nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c')
-rw-r--r--nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c b/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
index 7b4e84343c..9a9e67303b 100644
--- a/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
+++ b/nptl/sysdeps/unix/sysv/linux/lowlevelrobustlock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2006-2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2006.
 
@@ -70,8 +70,15 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime,
   if (oldval == 0)
     goto try;
 
+  /* Work around the fact that the kernel rejects negative timeout values
+     despite them being valid.  */
+  if (__builtin_expect (abstime->tv_sec < 0, 0))
+    return ETIMEDOUT;
+
   do
     {
+#if (!defined __ASSUME_FUTEX_CLOCK_REALTIME \
+     || !defined lll_futex_timed_wait_bitset)
       struct timeval tv;
       struct timespec rt;
 
@@ -90,6 +97,7 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime,
       /* Already timed out?  */
       if (rt.tv_sec < 0)
 	return ETIMEDOUT;
+#endif
 
       /* Wait.  */
       if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0))
@@ -100,7 +108,13 @@ __lll_robust_timedlock_wait (int *futex, const struct timespec *abstime,
 	  && atomic_compare_and_exchange_bool_acq (futex, newval, oldval))
 	continue;
 
+#if (!defined __ASSUME_FUTEX_CLOCK_REALTIME \
+     || !defined lll_futex_timed_wait_bitset)
       lll_futex_timed_wait (futex, newval, &rt, private);
+#else
+      lll_futex_timed_wait_bitset (futex, newval, abstime,
+				   FUTEX_CLOCK_REALTIME, private);
+#endif
 
     try:
       ;